如何普遍创建从通用类型继承的存储库? [英] How to universally create Repositories that inherit from a generic type?

查看:71
本文介绍了如何普遍创建从通用类型继承的存储库?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在尝试在我的DbContext之上实现存储库模式。问题是,最终我不得不将几个存储库注入到 UnitOfWork 构造函数中,如下所示:

I'm currently trying to implement the Repository Pattern on top of my DbContext. The thing is, I eventually end up with a situation where I have to inject several Repositories into a UnitOfWork constructor, like this:

public class UnitOfWork
{
    private DbContext _context;
    ICustomerRepository Customers { get; private set; }
    IEmployeeRepository Employees { get; private set; } 
    public UnitOfWork(DbContext context, ICustomerRepository cust, IEmployeeRepository emp)
    {
        _context = context;
        Customers = cust;
        Employees = emp;
    }    
}

但是,由于所有这些人都必须共享相同的DbContext,我看不到将它们作为选项注入。

However, since all of them would have to share the same DbContext, I can't see injecting them as an option.

这就是为什么我在考虑创建 RepositoryFactory 类,但是由于所有存储库都继承自通用接口,因此我发现无法创建单个 Create()方法,因为毕竟它们没有真正的共同点

That's why I was thinking about creating a RepositoryFactory class, but since all of the repositories inherit from a generic interface I found it impossible to create a single Create() method, because, after all, they have no real common ancestor that would be a valid return type.

为了给您更多的见识,代码就是这样的

To give you some more insight, that's how the code looks like:

public interface IRepository<TEntity> where TEntity:class
{
    TEntity Get(int id);
    IEnumerable<TEntity> GetAll();
}







public interface ICustomerRepository : IRepository<Customer>
{
    IEnumerable<Customer> GetSeniorCustomers();
}







public class CustomerRepository : ICustomerRepository
{
    private readonly DbContext _context;
    public CustomerRepository(DbContext context) : base(context)
    {
        _context = context;
    }
// ... implementation of ICustomerRepo here
}



< hr>

现在,这是当前的状态:


Now, that's the current state of things:

我想做的是:

public UnitOfWork(DbContext context, RepositoryFactory fac)
{
     _context = context;
     Customers = fac.Create(context, RepoType.Customer);
     Employees = fac.Create(context, RepoType.Employee);
}  

我知道它并没有给我带来更多的灵活性,但确实

I know it doesn't really give me any additional flexibility, but it does keep the code a bit less clunky in my opinion.

但是,正如我前面提到的,我无法想到Create()方法的有效返回类型。

But, as I mentioned earlier, I cannot think of a valid return type for the Create() method.

因此,我想到了在RepositoryFactory类中创建多个方法的想法,而不是像这样的单个参数化方法:

So, I came up with the idea to create multiple methods inside the RepositoryFactory class, instead of a single parameterized one, like this:

public class RepositoryFactory
{
    public ICustomerRepository CreateCustomerRepo(DbContext context){/*...*/}
    public IEmployeeRepository CreateEmployeeRepo(DbContext context){/*...*/} 
}

所以问题是:


  1. 我正在做的事情甚至可以称为工厂方法吗?

  2. 如果不是,至少是一个有效的解决方案?如果没有,我如何以一种更简洁的方式实现同一件事

  1. Can the thing I'm doing be even called a Factory Method?
  2. If not, is it at least a valid solution? If not, how can I achieve the same thing in a cleaner manner?

通过实现同一件事我的意思是要实现一种以可管理,简洁的方式创建这些存储库的方法。

By achieve the same thing I mean implement a way of creating those repositories in a managable, concise way.

感谢您提前获得的所有帮助。

Thank you for all the help in advance.

推荐答案

如果您不太在意打开/关闭原理,那么 RepositoryFactory类中的多个方法解决方案就很好。如果满足您的需要,则可以使用此方法。

Your "multiple methods inside the RepositoryFactory class" solution is quite good if you do not care much about Open/Close principle. If this suits your needs, you may go with this.


我正在做的事情甚至可以称为工厂方法吗?

Can the thing I'm doing be even called a Factory Method?

是;这些是工厂中的方法。无论如何,只要它满足您的要求而又不产生新问题,就不要太在意。

Yes; those are sort of factory methods. Anyway, do not care too much as long as it fulfill your requirements without creating new problem.


如果不满足,至少是有效的解决方案?

If not, is it at least a valid solution?

如上所述,如果它满足您的需求;是的,它是有效的。

As said above, if it suits your needs; yes it is valid.


如果没有,我如何以一种更清洁的方式实现同​​一件事?

If not, how can I achieve the same thing in a cleaner manner?

另一种替代方法是工厂方法,如下所示:

Another alternative is factory method something like below:

public T CreateRepository<T>() where T : IRepositoryId
{
    IRepositoryId repository = null;
    if(typeof(T) == typeof(ICustomerRepository))
        repository = new CustomerRepository(context);
    ......
    ......
    else
        throw new XyzException("Repository type is not handled.");
    return (T)repository;
}

public interface IRepositoryId
{
    Guid RepositoryId { get; }
}

您现有的 IRepository 接口是通用的。使用该接口实现上述方法时,会产生问题。因此,只需创建其他界面即可,如上所示。从此界面派生每个存储库。

Your existing IRepository interface is generic. It creates problems while implementing above method with that interface. So, just create other interface as shown above. Derive each repository from this interface.

这篇关于如何普遍创建从通用类型继承的存储库?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆