C# 使用存储库模式、工作单元和autofac依赖项注入实现webapi
开始使用存储库模式、工作单元和Autofac依赖项注入开发web api 建筑会像C# 使用存储库模式、工作单元和autofac依赖项注入实现webapi,c#,asp.net-web-api,autofac,repository-pattern,unit-of-work,C#,Asp.net Web Api,Autofac,Repository Pattern,Unit Of Work,开始使用存储库模式、工作单元和Autofac依赖项注入开发web api 建筑会像 webapi作为服务 业务层(类库)-将实体转换为DTO等业务逻辑 数据访问层(类库)-存储库和UOW(工作单元) 数据(类库)-实现实体框架 我创建了通用存储库并扩展了特定的存储库,每个存储库都有UOW。UOW由构造函数注入到存储库中 问题:从BAL中,存储库将由构造函数注入并分配到本地字段。我应该创建UOW并将其作为输入参数传递,还是由autofac处理 存储库 public class Repository
public class Repository<TEntity>:IRepository<TEntity> where TEntity:class
{
protected readonly DbContext Context;
public Repository(IUnitOfWork unitOfWork)
{
Context = unitOfWork.TMSContext;
}
public TEntity Get(int id)
{
return Context.Set<TEntity>().Find(id);
}
public IEnumerable<TEntity> GetAll()
{
return Context.Set<TEntity>().ToList();
}
public IEnumerable<TEntity> Find(Expression<Func<TEntity, bool>> predicate)
{
return Context.Set<TEntity>().Where(predicate);
}
public TEntity SingleOrDefault(Expression<Func<TEntity, bool>> predicate)
{
return Context.Set<TEntity>().SingleOrDefault(predicate);
}
public void Add(TEntity entity)
{
Context.Set<TEntity>().Add(entity);
}
public void AddRange(IEnumerable<TEntity> entities)
{
Context.Set<TEntity>().AddRange(entities);
}
public void Remove(TEntity entity)
{
Context.Set<TEntity>().Remove(entity);
}
public void RemoveRange(IEnumerable<TEntity> entities)
{
Context.Set<TEntity>().RemoveRange(entities);
}
}
}
UserRepository继承存储库类
public class UserRepository : Repository<User>, IUserRepository
{
IUnitOfWork _unitOfWork;
public UserRepository(IUnitOfWork unitOfWork):base(unitOfWork)
{
_unitOfWork = unitOfWork;
}
public bool ValidateUser(string userName, string password)
{
var res = SingleOrDefault(x => x.UserName == userName && x.UserPwd == password);
return res != null;
}
}
WebAPI控制器
public class UserController : ApiController
{
IUserManager _userManager;
public UserController(IUserManager userManager)
{
_userManager = userManager;
}
[HttpGet]
public bool ValidateUser(string userName, string password)
{
return _userManager.ValidateUser(userName, password);
}
}
AutoFac
public class Bootstrapper
{
public static void Run()
{
//Configure AutoFac
AutofacWebapiConfig.Initialize(GlobalConfiguration.Configuration);
}
}
private static IContainer RegisterServices(ContainerBuilder builder)
{
//Register your Web API controllers.
builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
builder.RegisterType<TMSDataEntities>()
.As<DbContext>()
.InstancePerRequest();
builder.RegisterType<DbFactory>()
.As<IDbFactory>()
.InstancePerRequest();
//Set the dependency resolver to be Autofac.
Container = builder.Build();
return Container;
}
公共类引导程序
{
公共静态无效运行()
{
//配置自动传真
AutofacWebapiConfig.Initialize(全局配置.Configuration);
}
}
专用静态IContainer注册表服务(ContainerBuilder builder)
{
//注册您的Web API控制器。
RegisterAppController(Assembly.getExecutionGassembly());
builder.RegisterType()
.As()
.InstancePerRequest();
builder.RegisterType()
.As()
.InstancePerRequest();
//将依赖项解析程序设置为Autofac。
Container=builder.Build();
返回容器;
}
从上面的示例中,UserRepository将从UserManager BAL中的构造函数注入
InstancePerRequest
Autofac将为每个新请求创建所需的实例,并在请求结束时自动处理所有创建的实例
请参阅autofac文档,以更好地了解生命周期范围
InstancePerRequest
Autofac将为每个新请求创建所需的实例,并在请求结束时自动处理所有创建的实例
请参阅autofac文档,以更好地了解生命周期范围
public class Repository<TEntity> : IRepository<TEntity> where TEntity : class
{
protected IUnitOfWork UnitOfWork { get; }
public Repository(IUnitOfWork unitOfWork)
{
UnitOfWork = unitOfWork;
}
// ...
}
public class Repository<TEntity> : IRepository<TEntity> where TEntity : class
{
protected IUnitOfWork UnitOfWork { get; }
public Repository(IUnitOfWork unitOfWork)
{
UnitOfWork = unitOfWork;
}
// ...
}
Cyril Durand,如何在BAL中调用Begin transaction,提交/回滚(来自上面的示例)?@user1645200有很多方法。你能更新这个问题并详细解释一下你需要什么和你迄今为止尝试了什么吗Cyril Durand,在BAL用户管理器类中更新了我的代码。SaveUser方法正在尝试使用UOW添加两个不同实体的值,此实现是否正确,或者是否需要进行任何修改?Cyril Durand,如何调用上述示例中的Begin transaction,在BAL中提交/回滚?@user1645200有许多方法可以做到这一点。你能更新这个问题并详细解释一下你需要什么和你迄今为止尝试了什么吗Cyril Durand,在BAL用户管理器类中更新了我的代码。SaveUser方法正在尝试使用UOW添加两个不同实体的值,此实现是否正确,或者是否需要进行任何修改?
public class Repository<TEntity> : IRepository<TEntity> where TEntity : class
{
protected IUnitOfWork UnitOfWork { get; }
public Repository(IUnitOfWork unitOfWork)
{
UnitOfWork = unitOfWork;
}
// ...
}
public class UserManager : IUserManager
{
private IUserRepository _userRepository;
private IAddressRepository _addressRepository;
public UserManager(IUserRepository userRepository,
IAddressRepositoryaddressRepository)
{
_userRepository = userRepository;
_addressRepository = addressRepository;
}
public bool ValidateUser(string userName, string password)
{
return _userRepository.ValidateUser(userName, password);
}
public void SaveUser(UserDTO userDTO, AddressDTO addressDTO)
{
try
{
// Is doesn't matter if you use _userRepository or _addressRepository,
// because this classes use the same UnitOfWork.
_userRepository.UnitOfWork.BeginTransaction();
_userRepository.Add(ConvertToUser(userDTO));
_addressRepository.Add(ConvertToAddress(addressDTO));
_userRepository.UnitOfWork.SaveCahnges();
_userRepository.UnitOfWork.Commit();
}
catch (Exception)
{
// Todo - log exception
_userRepository.UnitOfWork.Rollback();
}
}
}