Просто предположите, что у меня есть некоторый класс Foo, который имеет две зависимости: ISerializer<T>
и IFileAccessHandler
.
Теперь этот класс также имеет другие зависимости, функциональные зависимости. Я не хочу никого инстанцирующего этого класса в недопустимом состоянии, таким образом, я должен был бы также передать объект области в конструкторе.
Но как я могу иметь, что обработанный МОК, когда я также знаю, что объект области передать в момент я на самом деле создаю класс Foo?
Я сделал объект области свойством, которое я установил Фабрикой. Таким образом, Фабрика выполняет Сервисный вызов Локатора для получения правильно инстанцированного класса "Нечто" с, он - зависимости, и далее заполняет его корректным объектом области и возвращает его.
Но действительно ли это - лучший способ пойти? Я предпочел бы иметь часть объекта области своего конструктора для создания этого очевидным, что на самом деле необходимо работать с "Нечто".
Какие-либо идеи? Я пропускаю что-то здесь?
Решение по умолчанию для 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 и использовать ее.