简体   繁体   English

存储库模式IRepository <T> 在IServiceRepository中

[英]Repository Pattern IRepository<T> inside IServiceRepository

I have implemented repository pattern and it works pretty well. 我已经实现了存储库模式,它运行得很好。

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        
}

When I want to access some methods from IServiceRepository in Controller I do this 当我想从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;
    }
}

As you see I inject IRepositories and IServiceRepository in this scenario. 如您所见,我在此场景中注入了IRepositoriesIServiceRepository Sometimes I inject only IRepositories or IServiceRepository depending on a needs. 有时我会根据需要仅注入IRepositoriesIServiceRepository

Question would be maybe I should move all IRepositories into IServiceRepository . 问题可能是我应该将所有IRepositories移动到IServiceRepository And in all controllers embed only IServiceRepository and access IRepositories from IServiceRepository ? 并且在所有控制器中只嵌入IServiceRepository并从IServiceRepository访问IRepositories This implementation looks more clear to me because only IServiceRepository will be injected in controllers. 这个实现对我来说更清楚,因为只有IServiceRepository会被注入到控制器中。 But to access for example one Repositorie<User> from ServiceRepository will need to build and inject all other repositories in ServiceRepository , so it may slow down the whole application. 但是要访问例如ServiceRepository一个Repositorie<User> ,需要在ServiceRepository构建并注入所有其他存储库,因此可能会降低整个应用程序的速度。 What do you think? 你怎么看?

My answer is controversial, so please bear with me :) 我的回答是有争议的,所以请耐心等我:)

To the point 到了这一点
Building and injecting repositories should take almost no time. 构建和注入存储库几乎不需要时间。 I assume your repositories do not open any connections when they are created, so do not bother about micro optimisation, just get it working :) 我假设您的存储库在创建时不会打开任何连接,所以不要打扰微优化,只需让它工作:)

You can merge your interfaces, as long as the result interface is small (say no more than 10 or so methods), focused and has a clear purpose. 您可以合并您的接口,只要结果接口很小(例如,方法不超过10个),专注且具有明确的目的。


Side comments 一边评论
What is the need for the repository pattern? 存储库模式需要什么? Do you allow (or in the nearest future plan) to easily switch between databases? 您是否允许(或在最近的计划中)轻松地在数据库之间切换? For most cases repository is a massive overkill and a maintenance problem. 对于大多数情况,存储库是一个巨大的过度杀伤和维护问题。

Consider this code 考虑这段代码

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

What does it tell me? 它告诉我什么? Well, from the generic name I couldn't understand what this interface does, it is like service of a service, abstraction over abstraction. 好吧,从通用名称我无法理解这个接口的作用,它就像服务的服务,抽象的抽象。 But from the method definitions I see it does something with User s. 但是根据方法定义,我看到它对User做了一些事情。

Why do you explicitly using IUnitOfWork ? 为什么要明确使用IUnitOfWork Is it not already implemented by the data provider you using? 您使用的数据提供程序尚未实现吗?

Instead of all this architecture (of course if possible), just use ORM directly, this is easy to do and maintain, reliable and fast. 而不是所有这些架构 (当然,如果可能的话),只需直接使用ORM,这很容易做到和维护,可靠和快速。

Your ServiceRepository seems to be closer to a domain service in a Service Layer than a repository of its own. 您的ServiceRepository似乎更接近服务层中的域服务而不是自己的存储库。

A domain service typically coordinates a sequence of interactions with various data repositories, for example loading a customer from a customer repository and a list of orders from an order repository to present a unified view of a customer and all their orders. 域服务通常协调与各种数据存储库的交互序列,例如从客户存储库加载客户和从订单存储库加载订单列表以呈现客户及其所有订单的统一视图。 As such domain services are used to create an operational boundary around an application - abstracting the various sequences of data access. 因为这样的域服务用于在应用程序周围创建操作边界 - 抽象出各种数据访问序列。

This is a fine approach, but I think the problem you have is that you have not taken it far enough. 这是一个很好的方法,但我认为你遇到的问题是你没有采取足够的措施。 If you decide that the operations of the application should be encapsulated into a series of domain services, then there will be no need for a Controller to access repositories. 如果您决定将应用程序的操作封装到一系列域服务中,那么Controller将无需访问存储库。 If on the other hand you decide that the Controllers will take that reposibility, and access repositories themselves, then your ServiceRepository class, and others like it, basically become utility classes. 另一方面,如果您决定控制器将采用该可重用性并自行访问存储库,那么您的ServiceRepository类和其他类似的类基本上成为实用程序类。

I see that you have two options - improve your service layer to such an extent that controllers no longer need repositories: 我看到你有两个选择 - 将服务层改进到控制器不再需要存储库的程度:

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

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

or call the ServiceRepository what it is, a shortcut utility for doing a fixed sequence of data accesses... 或调用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...
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM