如何在工厂中使用存储库

时间:2010-12-13 18:03:34

标签: c# domain-driven-design repository factory

您好 我正在尝试按照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
            };
       }
}

现在我的问题是:

  1. 创建工厂和使用存储库是正确的方法吗?
  2. 如何获取存储库?我不能使用DI,因为它是静态方法。我不喜欢ServiceLocator,因为它很难进行单元测试。
  3. 也许这个问题有更好的解决方案。

3 个答案:

答案 0 :(得分:9)

重写ItemFactory以使用依赖注入,并使用构造函数注入注入IRepository<Category>。完成后,ItemFactory将如下所示:

public class ItemFactory
{
    private readonly IRepository<Category> repository;

    public ItemFactory(IRepository<Category> repository)
    {
        this.repository = repository;
    }

    public SpecificItem CreateSpecificItem(object someArguments)
    {
        return new SpecificItem
        {
             Category = this.repository.FirstOrDefault(i => 
                 i.Id == Category.IdOfCategoryForSpecificItem),
             // additional initialization
        };
    }
}

这样您就可以将检索IRepository<Category>的实现的责任转移给调用者。现在,您可以对需要ItemFactory的所有类型执行相同的操作。在这些类型的构造函数中注入ItemFactory作为依赖项。这样做一直到应用程序的类型层次结构的顶部,并组成他们的类型(composition root)。

特别是IoC / DI框架将非常方便自动为您创建类型。

答案 1 :(得分:1)

我建议制作 Dao 服务类。当Dao组织对数据的访问时,Service使用Dao来管理数据。架构是:
1)Dao级正在访问数据
2)服务级正在形成存储库
3)为您的工厂提供存储库的服务级
这是非常概括的架构,但我希望我的回答能够帮到你。

答案 2 :(得分:0)

我认为这是令人费解的语法正在引导您寻求更好的解决方案的时代之一。

您可能希望每个类都有一个不同的存储库,这正是DI可以为您做的以及静态属性可以防止的。

但我也认为你在这里混淆了你的名字 - 一个工厂创造了某种类型的新物品,而一个工厂存放/坚持那种类型的物品。你在创建还是检索?

我的建议是将它们分开 - 实现工厂以创建新工厂和存储库以保存/检索现有工厂。使用DI根据运行时的类型确定哪种具体实现。