Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.
like image 795
Sławomir Rosiek Avatar asked Dec 17 '22 19:12

Sławomir Rosiek


1 Answers

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.

like image 64
Steven Avatar answered Jan 03 '23 13:01

Steven