通用信息库,DI,聚集根 [英] Generic repository, DI, Aggregation Roots
问题描述
拥有一个像
public class Repository<T>
where T: Entity<T>
{
/*anything else*/
}
应每根agregation混凝土仓库像
should concrete repositories per agregation root like
class ProductRepository : Repository<Product>
{
}
class CategoryRepository : Repository<Category>
{
}
创建?
be created?
另外我怎么使用DI( Ninject
)与通用实现仓库的。
Also how do I use DI (Ninject
) with generic implementation of repository.
样品apreciated!
Samples are apreciated!
谢谢!
推荐答案
我看到了很多在这样的问题仿制药的滥用,虽然它并不一定是指你的问题(虽然这将有助于澄清),我想一次都在这里写一个总结。
I see a lot of misuse of generics in the questions in SO and while it does not necessarily refer to your question (although it will help to clarify), I think once for all write a summary here.
泛型是无类型
行为的重用(差不多,因为你可以使用限制限制类型)。如果一个行为是由所有类型的共享(或者那些仅限于限制)您使用泛型。
Generics is a typeless
reuse of the behaviour (almost, since you can limit the types using restrictions). If a behaviour is shared by all types (or those limited to restrictions) you use the generics.
不过,如果需要单独执行,然后使用实现每个泛型类型。仿制药没有帮助,并减少到装饰 - 对我来说是糟糕的设计。
However if implementation of each generic type needs to be individually implemented, then using generics does not help and is reduced to a decoration - and for me it is bad design.
好吧,让我们有一个例子:
OK, let's have an example:
interface IConverter<T1, T2>
{
T1 Convert(T2 t2);
}
这看起来像一个很好的仿制药(一种类型转换为另一种),但我必须实现的类型,不同的转换器,所有这样的组合。和 IConverter<苹果,橘子>
没有任何意义。因此,这里的仿制药是一种误导和坏的。
This looks like a good generics (converting one type to another), but I have to implement all such combinations of types as different converters. And a IConverter<Apple, Orange>
does not make any sense. Hence generics here is misleading and BAD.
现在要回库。有关于这个具体问题(许多争议),文章数百但这个人我的看法:
Now going back to repositories. There are 100s of articles on this particular issue (lots of controversies) but this is personal my take:
通常不建议使用通用存储库。 然而,以我个人的经验,我用通用的存储库,以实现共同的东西(由基底回购来实现),然后使用单独的,如果有任何额外的:
Usually it is not recommended to use generic repositories. However, in my personal experience I use generic repository to implement common stuff (implemented by a base repo) and then use individual ones if there is any additional:
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
}
注意
有些人认为库必须允许标准传递到存储库( Eric Evans的DDD书),但我再做一次不觉得我不得不同意。我更喜欢在库(如 GetTopFiveBestSellingProducts
或 GetTopBestSellingProducts
),除非有这样的100S就像一个域显著声明。报告作者是病例只有1%
Some believe repository must allow for criteria to be passed to the repository (Eric Evans DDD book) but I again do not feel I have to agree to that. I prefer a domain-significant declaration on the repository (e.g. GetTopFiveBestSellingProducts
or GetTopBestSellingProducts
) unless there are 100s of such like in a report writer which is only 1% of cases.
第二个问题:
我不使用Ninject,但任何DI,这里是你怎么做。
I do not use Ninject but for any DI, here is how you do it
// PSEUDOCODE !!!
container.Register<IProductRepository , ProductRepository>();
根据DI框架,它可以略有不同。
depending on DI framework, it can be slightly different.
这篇关于通用信息库,DI,聚集根的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!