通用存储库,DI,聚合根

lex*_*eme 2 c# design-patterns dependency-injection ninject repository

拥有一个通用的存储库

public class Repository<T> 
    where T: Entity<T> 
{ 
    /*anything else*/ 
}
Run Code Online (Sandbox Code Playgroud)

应该是每个聚合根的具体存储库

class ProductRepository : Repository<Product> 
{
} 

class CategoryRepository : Repository<Category> 
{ 
}
Run Code Online (Sandbox Code Playgroud)

被创造?

另外,我如何使用DI(Ninject)与存储库的通用实现.

样品是apreciated!

谢谢!

Ali*_*tad 5

我在SO的问题中看到了很多滥用泛型的问题,虽然它并不一定会引用你的问题(虽然它有助于澄清),但我认为一旦在这里写了一个摘要.

泛型是typeless对行为的重用(几乎,因为您可以使用限制来限制类型).如果所有类型(或限制为限制的行为)共享行为,则使用泛型.

但是,如果每个泛型类型的实现需要单独实现,那么使用泛型并没有帮助,而是简化为装饰 - 对我来说这是糟糕的设计.

好的,我们有一个例子:

interface IConverter<T1, T2>
{
    T1 Convert(T2 t2);
}
Run Code Online (Sandbox Code Playgroud)

这看起来像一个很好的泛型(将一种类型转换为另一种类型),但我必须将所有这些类型的组合实现为不同的转换器.而且IConverter<Apple, Orange>没有任何意义.因此,这里的仿制药具有误导性和不良性.

现在回到存储库.关于这个特定问题有很多文章(很多争议),但这是我个人的看法:

通常不建议使用通用存储库.但是,根据我的个人经验,我使用通用存储库来实现常见的东西(由基础仓库实现),然后使用单独的存储库,如果有任何额外的:

interface IRepository<T>
{
    T GetById(int id);
    IEnumerable<T> GetAll();
    void Save(T t);
}

class BaseRepository<T> : IRepository<T>
{
   ... // implement common methods
}

interface IProductRepository : IRepository<T>
{
    IEnumerable<T> GetTop5BestSellingProducts();    
}

class ProductRepository : BaseRepository<T>, IProductRepository 
{
    ... // implement important methods
}
Run Code Online (Sandbox Code Playgroud)

注意

有些人认为存储库必须允许将标准传递到存储库(Eric Evans DDD书),但我再次认为我不必同意这一点.我更喜欢存储库中的域名重要声明(例如GetTopFiveBestSellingProducts或者GetTopBestSellingProducts),除非报告编写者中有100个这样的声明只占案例的1%.


第二个问题:

我不使用Ninject但是对于任何DI,这是你如何做到的

 // PSEUDOCODE !!!
 container.Register<IProductRepository , ProductRepository>(); 
Run Code Online (Sandbox Code Playgroud)

根据DI框架,它可能会略有不同.