如何在工厂中使用存储库
你好 我正在尝试按照 DDD 进行申请。我有以下实体:
public class Item { public Category Category { get; protected set; } ... } public class SpecificItem : Item { ... } public class Category { public static int IdOfCategoryForSpecificItem = 10; public int Id { get; set; } }
现在我想使用创建 SpecificItem 类型对象的方法创建 factory 。但这个特定的项目必须属于特定的类别。所以我创建了这样的工厂:
public class ItemFactory { public static SpecificItem CreateSpecificItem(object someArguments) { IRepository<Category> repository = null // How to get repository? return new SpecificItem { Category = repository.FirstOrDefault(i => i.Id == Category.IdOfCategoryForSpecificItem), // additional initialization }; } }
现在我的问题:
- 创建工厂和使用存储库的正确方法是?
- 如何获取存储库?我不能使用 DI,因为它是静态方法。我不喜欢 ServiceLocator,因为它很难进行单元测试。
- 也许这个问题有更好的解决方案。
Hi
I'm trying to make application in accordance with the DDD. I'm have the following entities:
public class Item { public Category Category { get; protected set; } ... } public class SpecificItem : Item { ... } public class Category { public static int IdOfCategoryForSpecificItem = 10; public int Id { get; set; } }
And now I would like to create factory with method that create object of SpecificItem type. But this specific item must be in specific category. So I created factory like this:
public class ItemFactory { public static SpecificItem CreateSpecificItem(object someArguments) { IRepository<Category> repository = null // How to get repository? return new SpecificItem { Category = repository.FirstOrDefault(i => i.Id == Category.IdOfCategoryForSpecificItem), // additional initialization }; } }
And now my questions:
- It is correct way to create factory and use repository?
- How to get repository? I can't use DI because it's static method. I don't like ServiceLocator because it's difficult to unit testing.
- Maybe there are better solutions for this problem.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
重写您的
ItemFactory
以使用依赖项注入,并使用构造函数注入注入IRepository
。完成此操作后,ItemFactory
将如下所示:通过这种方式,您将检索
IRepository
实现的责任转移给了调用者。现在,您可以对所有需要ItemFactory
的类型执行相同的操作。将ItemFactory
作为依赖项注入到这些类型的构造函数中。一直这样做到应用程序类型层次结构的顶部并组合它们的类型(组合根)。特别是 IoC/DI 框架将非常方便地为您自动创建类型。
Rewrite your
ItemFactory
to use dependency injection and inject theIRepository<Category>
using constructor injection. After doing that, theItemFactory
will look like this:This way you moved the responsibility of retrieving an implementation of
IRepository<Category>
to the caller. Now you can do the same for all types that need theItemFactory
. Inject theItemFactory
as dependency in the constructors of these types. Do this all the way up to the top of your application's type hierarchy and compose the types their (the composition root).Especially IoC/DI frameworks will get very handy to automate the creation of types for you.
我建议创建 Dao 和 Service 类。 Dao 组织对数据的访问,而 Service 使用 Dao 来管理数据。架构是:
1) Dao 类正在访问数据
2) 服务类正在形成存储库
3) 为您的工厂提供存储库的服务类
这是非常笼统的模式,但我希望我的回答对您有所帮助。
I suggest making Dao and Service classes. While Dao organizes access to data, Service uses Dao to manage data. The schema is:
1) Dao-class is getting access to data
2) Service-class is forming the repository
3) Service-class providing the repository for your factory
It's very generalized schema, but I hope my answer will help you.
我认为这是对语法的困惑会引导你找到更好的解决方案的时候之一。
您似乎可能希望为每个类使用不同的存储库,这正是 DI 可以为您做的事情,而静态属性会阻止这种情况。
但我也认为你在这里混淆了你的名字 - 工厂创建某种类型的新项目,而存储库存储/保留该类型的项目。您是在创建还是检索?
我的建议是将它们分开 - 实现一个工厂来创建新的工厂和一个存储库来保存/检索现有的工厂。使用DI在运行时根据类型决定具体实现哪种。
I think this is one of those times that puzzling over syntax is leading you toward a better solution.
It seems likely that you might want a different repository for each class, which is exactly what DI can do for you and which a static property would prevent.
But I also think you're confusing your names here - a factory creates NEW items of some type while a repopsitory stores/persists items of that type. Are you creating or retrieving?
My suggestion is to split these up - implement a factory to create new ones and an repository to save/retreive existing ones. Use DI to decide which concrete implementation based on type at run-time.