Не может объединить Фабрику / DI

Просто предположите, что у меня есть некоторый класс Foo, который имеет две зависимости: ISerializer<T> и IFileAccessHandler.

Теперь этот класс также имеет другие зависимости, функциональные зависимости. Я не хочу никого инстанцирующего этого класса в недопустимом состоянии, таким образом, я должен был бы также передать объект области в конструкторе.

Но как я могу иметь, что обработанный МОК, когда я также знаю, что объект области передать в момент я на самом деле создаю класс Foo?

Я сделал объект области свойством, которое я установил Фабрикой. Таким образом, Фабрика выполняет Сервисный вызов Локатора для получения правильно инстанцированного класса "Нечто" с, он - зависимости, и далее заполняет его корректным объектом области и возвращает его.

Но действительно ли это - лучший способ пойти? Я предпочел бы иметь часть объекта области своего конструктора для создания этого очевидным, что на самом деле необходимо работать с "Нечто".

Какие-либо идеи? Я пропускаю что-то здесь?

44
задан ROMANIA_engineer 6 October 2017 в 19:51
поделиться

1 ответ

Решение по умолчанию для DI, когда вы не можете подключить конкретный type во время регистрации - использовать Abstract Factory

В вашем случае я бы определил интерфейс IFooFactory:

public interface IFooFactory
{
    Foo Create(DomainClass dc);
}

Это позволит вам определить конкретную реализацию, которая знает о ваших инфраструктурных сервисах.

public class FooFactory : IFooFactory
{
    private readonly ISerializer serializer;
    private readonly IFileAccessHandler fileHandler;

    public FooFactory(ISerializer serializer, IFileAccessHandler fileHandler)
    {
        if(serializer == null)
        {
            throw new ArgumentNullException("serializer");
        }
        if(fileHandler == null)
        {
            throw new ArgumentNullException("fileHandler");
        }

        this.serializer = serializer;
        this.fileHandler = fileHandler;
    }

    public Foo Create(DomainClass dc)
    {
        return new Foo(this.serializer, this.fileHandler, dc);
    }
}

В таким образом вы можете защитить инварианты вашего класса Foo, что позволит вам остаться с Constructor Injection .

В контейнере DI вы можете зарегистрировать IFooFactory и соответствующую реализацию. Везде, где у вас есть экземпляр DomainClass и вам нужен экземпляр Foo, вы должны взять зависимость от IFooFactory и использовать ее.

70
ответ дан 26 November 2019 в 22:11
поделиться
Другие вопросы по тегам:

Похожие вопросы: