通用存储库、DI、聚合根
拥有一个通用存储库,例如
public class Repository<T>
where T: Entity<T>
{
/*anything else*/
}
是否应该为每个聚合根
class ProductRepository : Repository<Product>
{
}
class CategoryRepository : Repository<Category>
{
}
创建具体存储库?
另外,我如何将 DI (Ninject
) 与存储库的通用实现结合使用。
样品值得赞赏!
谢谢!
Having a generic repository like
public class Repository<T>
where T: Entity<T>
{
/*anything else*/
}
should concrete repositories per agregation root like
class ProductRepository : Repository<Product>
{
}
class CategoryRepository : Repository<Category>
{
}
be created?
Also how do I use DI (Ninject
) with generic implementation of repository.
Samples are apreciated!
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我在 SO 的问题中看到很多泛型的滥用,虽然它不一定指您的问题(尽管这将有助于澄清),但我想在这里写一个总结。
泛型是行为的
无类型
重用(几乎是这样,因为您可以使用限制来限制类型)。如果某个行为由所有类型(或仅限于限制的类型)共享,则可以使用泛型。但是,如果每个泛型类型的实现都需要单独实现,那么使用泛型就没有帮助,而且会沦为装饰——对我来说,这是糟糕的设计。
好吧,让我们举个例子:
这看起来像是一个很好的泛型(将一种类型转换为另一种类型),但我必须将所有此类类型组合实现为不同的转换器。而
IConverter
没有任何意义。因此这里的泛型是误导性的并且是不好的。现在回到存储库。关于这个特定问题有数百篇文章(有很多争议),但这是我的个人看法:
通常不建议使用通用存储库。 但是,根据我个人的经验,我使用通用存储库来实现常见的内容(由基本存储库实现),然后使用单独的内容(如果有任何其他内容):
注意
有些人相信存储库必须允许将条件传递到存储库 (Eric Evans DDD书),但我再次觉得我不必同意这一点。我更喜欢在存储库上进行具有重要领域意义的声明(例如
GetTopFiveBestSellingProducts
或GetTopBestSellingProducts
),除非报告撰写者中有数百个此类声明(仅占案例的 1%)。第二个问题:
执行的方法,它可能略有不同。
我不使用 Ninject,但对于任何 DI,这里是根据 DI 框架如何
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:
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:
NOTE
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
orGetTopBestSellingProducts
) unless there are 100s of such like in a report writer which is only 1% of cases.Second question:
I do not use Ninject but for any DI, here is how you do it
depending on DI framework, it can be slightly different.