IServiceRepository </t>中的存储库模式IRepository <t>

时间:2012-07-19 11:04:58

标签: c# model-view-controller dependency-injection repository repository-pattern

我已经实现了存储库模式,它运行得很好。

public interface IServiceRepository
{
    User GetUser(int id);
    User GetUser(string email);
    User GetUser(string email, byte[] password);
    //SkipCode
}

//Service repository where I keep extended methods for database manipulation
public class ServiceRepository : IServiceRepository
{
    private readonly IRepository<User> _userRepository;
    private readonly IRepository<Order> _orderRepository;
    private readonly IUnitOfWork _unitOfWork;

    public ServiceRepository(IRepository<User> userRepository, IRepository<Order> orderRepository, IUnitOfWork unitOfWork)
    {
    }

    //SkipImplementation        
}

当我想从Controller中的IServiceRepository访问某些方法时,我会这样做

public class AccountController : Controller
{
    private readonly IRepository<OrderDetail> _orderDetailRepository;
    private readonly IRepository<UserDetail> _userDetailRepository;
    private readonly IServiceRepository _serviceRepository;

    public AccountController(IRepository<OrderDetail> orderDetailRepository, IRepository<UserDetail> userDetailRepository, IServiceRepository serviceRepository)
    {
        _orderDetailRepository = orderDetailRepository;
        _userDetailRepository = userDetailRepository;
        _serviceRepository = serviceRepository;
    }
}

如您所见,我在此方案中注入了IRepositoriesIServiceRepository。有时我会根据需要仅注入IRepositoriesIServiceRepository

问题可能是我应该将所有IRepositories移到IServiceRepository。并且在所有控制器中仅嵌入IServiceRepository并从IRepositories访问IServiceRepository?这个实现看起来更清楚,因为只有IServiceRepository将被注入控制器。但是要访问Repositorie<User>中的一个ServiceRepository,需要在ServiceRepository中构建并注入所有其他存储库,因此可能会降低整个应用程序的速度。你觉得怎么样?

2 个答案:

答案 0 :(得分:3)

我的回答是有争议的,所以请耐心等待我:)

要点
构建和注入存储库应该几乎没有时间。我假设您的存储库在创建时不会打开任何连接,所以不要打扰微优化,只需让它工作:)

只要结果界面很小(比如说方法不超过10个),你可以合并你的界面,专注并有明确的目的。

<小时/> 旁边评论
存储库模式需要什么?您是否允许(或在最近的计划中)轻松地在数据库之间切换?对于大多数情况,存储库是一个巨大的过度杀伤和维护问题。

考虑这段代码

public interface IServiceRepository
{
    User GetUser(int id);
    User GetUser(string email);
    User GetUser(string email, byte[] password);
    //SkipCode
}

它告诉我什么?好吧,从通用名称我无法理解这个接口的作用,它就像服务的服务,抽象的抽象。但是从方法定义中我发现它与User s做了一些事情。

为什么要明确使用IUnitOfWork?是否尚未由您使用的数据提供商实施?

而不是所有架构(当然,如果可能的话),只需直接使用ORM,这很容易做到并且维护,可靠和快速。

答案 1 :(得分:1)

您的ServiceRepository似乎更接近Service Layer中的域服务,而不是自己的存储库。

域服务通常协调与各种数据存储库的一系列交互,例如从客户存储库加载客户和从订单存储库加载订单列表,以呈现客户及其所有订单的统一视图。因为这样的域服务用于在应用程序周围创建操作边界 - 抽象出各种数据访问序列。

这是一个很好的方法,但我认为你遇到的问题是你没有采取足够的措施。如果您决定将应用程序的操作封装到一系列域服务中,那么Controller将无需访问存储库。另一方面,如果您决定控制器将采用该可重用性并自行访问存储库,那么您的ServiceRepository类和其他类似的类基本上成为实用程序类。

我发现您有两个选择 - 将服务层改进到控制器不再需要存储库的程度:

public class AccountController
{
    public AccountController(IAccountsService service)
    {
        _service = service;
    }

    public void SomeActionMethod(Foo someParams)
    {
        _service.SomeAction(someParams);
    }
}

或调用ServiceRepository它是什么,一个用于执行固定数据访问序列的快捷方式实用程序......

public class AccountController
{
    public AccountController(ICustomerRepository customerRepo, IOrderRepository orderRep)
    {
        _customerRepo = customerRepo;
        _orderRepo = orderRepo;
    }

    public void SomeActionMethod(Foo someParams)
    {
        var utility = new CustomerOrderBuilderUtility(_customerRepo, _orderRepo);

        var customerWithOrders = utility.GetCustomerAndOrders(someParams.CustomerId);

        // some domain logic...
    }
}