Autofac 存储库模式和工作单元
Autofac Repository Pattern and Unit Of Work
稍微搜了一下,一头雾水
First Approach 使用 Autofac 为每个实体使用存储库和服务。工作单元 class 没有存储库。因此,您应该创建每个存储库,而不是仅在调用者构造函数中创建一个工作单元 class。
OrderService(IUnitOfWork unitOfWork, IUserRepository userRepository,IOrderRepository orderRepository,IBalanceRepository balanceRepository)
Second Approach 仅使用通用存储库。它使用扩展 classes 而不是为每个实体使用一个存储库。工作单元 class 具有泛型 repositories.Therefore,您只需在调用方 class 构造函数上创建工作单元 class。
OrderService(IUnitOfWork unitOfWork)
在这种方法中,我们对存储库使用一个通用 class,但我们为每个实体创建一个存储库对象。如果这种方法没问题,我该如何使用 Autofac 来实现它?
Third Approach 使用一个通用存储库和一个对象用于 Autofac 的通用存储库。它使用泛型方法而不是泛型 class。但是通用存储库有工作单元 class 而不是相反。这是反模式吗?
OrderService(IUnitOfWork unitOfWork,IGenericRepository repository)
我应该使用哪种方法?
我用的是第2个,IUnitOfWork只是一个接口,后面我用的是ef。
public interface IUnitOfWork:IDisposable
{
IRepository<T> GetRepository<T>() where T:class;
int SaveChanges();
}
并创建 dbcontext class
public class DataContext:DbContext,IUnitOfWork
实现 GetRepository 方法,你应该添加一个适配器 class,从 dbset 到 irepository
public IRepository<T> GetRepository<T>() where T:class
{
return new RepositoryEfAdapter<T>(Set<T>(), this);
}
这是一个示例,您可以将数据上下文注册为 iunitofwork
工作单元和存储库模式的含义是准确描述用例所需的内容。因此,对于每个实体都有存储库或可以通过通用方法为任何实体创建存储库的工作单元,就像 returns 一个 IQueryable 的存储库一样要避免。最后一个缺陷会将您的 Dal 移动到您的域模型甚至 UI(想象一下过滤器逻辑的编写位置以及执行过滤器的确切时间以及将抛出任何异常的位置),第一个创建一种单一应用程序并使编写单元测试变得困难。一个工作单元(接口)只有您的用例需要的 3 个存储库和三个只有所需方法的存储库(接口),返回单个对象或对象列表更容易模拟和测试并指定用例的确切需求并将其传达给您的开发人员同事(或 2 年后的您自己)。这些接口可以由一个大的工作单元 class 和一些标准存储库 class 实现(如果您选择的话),但这是一个不同的决定,应该由技术(EF 代码)指导首先在早期版本中无法在一个数据库中拥有多个上下文)和应用程序的复杂性。
稍微搜了一下,一头雾水
First Approach 使用 Autofac 为每个实体使用存储库和服务。工作单元 class 没有存储库。因此,您应该创建每个存储库,而不是仅在调用者构造函数中创建一个工作单元 class。
OrderService(IUnitOfWork unitOfWork, IUserRepository userRepository,IOrderRepository orderRepository,IBalanceRepository balanceRepository)
Second Approach 仅使用通用存储库。它使用扩展 classes 而不是为每个实体使用一个存储库。工作单元 class 具有泛型 repositories.Therefore,您只需在调用方 class 构造函数上创建工作单元 class。
OrderService(IUnitOfWork unitOfWork)
在这种方法中,我们对存储库使用一个通用 class,但我们为每个实体创建一个存储库对象。如果这种方法没问题,我该如何使用 Autofac 来实现它?
Third Approach 使用一个通用存储库和一个对象用于 Autofac 的通用存储库。它使用泛型方法而不是泛型 class。但是通用存储库有工作单元 class 而不是相反。这是反模式吗?
OrderService(IUnitOfWork unitOfWork,IGenericRepository repository)
我应该使用哪种方法?
我用的是第2个,IUnitOfWork只是一个接口,后面我用的是ef。
public interface IUnitOfWork:IDisposable
{
IRepository<T> GetRepository<T>() where T:class;
int SaveChanges();
}
并创建 dbcontext class
public class DataContext:DbContext,IUnitOfWork
实现 GetRepository 方法,你应该添加一个适配器 class,从 dbset 到 irepository
public IRepository<T> GetRepository<T>() where T:class
{
return new RepositoryEfAdapter<T>(Set<T>(), this);
}
这是一个示例,您可以将数据上下文注册为 iunitofwork
工作单元和存储库模式的含义是准确描述用例所需的内容。因此,对于每个实体都有存储库或可以通过通用方法为任何实体创建存储库的工作单元,就像 returns 一个 IQueryable 的存储库一样要避免。最后一个缺陷会将您的 Dal 移动到您的域模型甚至 UI(想象一下过滤器逻辑的编写位置以及执行过滤器的确切时间以及将抛出任何异常的位置),第一个创建一种单一应用程序并使编写单元测试变得困难。一个工作单元(接口)只有您的用例需要的 3 个存储库和三个只有所需方法的存储库(接口),返回单个对象或对象列表更容易模拟和测试并指定用例的确切需求并将其传达给您的开发人员同事(或 2 年后的您自己)。这些接口可以由一个大的工作单元 class 和一些标准存储库 class 实现(如果您选择的话),但这是一个不同的决定,应该由技术(EF 代码)指导首先在早期版本中无法在一个数据库中拥有多个上下文)和应用程序的复杂性。