简体   繁体   中英

How to use repository in factory

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:

  1. It is correct way to create factory and use repository?
  2. 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.
  3. Maybe there are better solutions for this problem.

Rewrite your ItemFactory to use dependency injection and inject the IRepository<Category> using constructor injection. After doing that, the ItemFactory will look like this:

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
        };
    }
}

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 the ItemFactory . Inject the ItemFactory 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.

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM