Я думаю, что в некоторых случаях вы не хотите внедрять экземпляр в конструктор.Я часто впрыскиваю ленивые предметы или заводских делегатов.Я постараюсь объяснить очень быстро, почему вы хотели бы сделать это.
В некоторых реальных сценариях вы можете в конечном итоге внедрить множество экземпляров в конструктор, а иногда, в зависимости от логики приложения, лишь немногие из них фактически используются в течение жизненного цикла объекта.Это означает, что иногда вы инициализируете зависимость, даже если она не используется.
В .NET 4 вы можете использовать класс Lazy, который позволяет создавать экземпляр класса зависимостей только при его первом использовании.Здорово, когда создание экземпляров зависимостей занимает много времени или экземпляр требует много памяти.
public class ClassA
{
private readonly Lazy<IClassB> _lazyClassBObj;
public ClassA(Lazy<IClassB> lazyClassBObj)
{
_lazyClassBObj = lazyClassBObj;
}
public void UseClassBMethod()
{
_lazyClassBObj.Value.classBMethod();
}
}
class Program
{
static void Main(string[] args)
{
ClassA classA = new ClassA (new Lazy<IClassB>(() => new ClassB));
...
}
}
Другая хитрость заключается в том, чтобы внедрить делегат фабрики в конструктор вместо экземпляра.Это очень похоже на решение Lazy, но у него есть несколько преимуществ.Инъекция фабричного делегата - это здорово, если ваш класс должен иметь возможность создавать любое количество новых экземпляров класса зависимости (хотите создавать экземпляры в цикле или что-то подобное).В этом примере ClassA будет иметь ссылку на метод, который может создать объект, который реализует IClassB.Чтобы сделать вещи более интересными, ClassB, который реализует IClassB, также имеет зависимость IClassC.
public class ClassA
{
private readonly Lazy<IClassC> _lazyClassBObj;
private readonly Func<IClassC, IClassB> _classBObjFactory;
public ClassA(Func<IClassC, IClassB> classBObjFactory, Lazy<IClassC> lazyClassBObj)
{
_classBObjFactory = classBObjFactory;
_lazyClassBObj = lazyClassBObj;
}
public void UseClassBMethod()
{
var classC = _lazyClassBObj.Value;
var classB1 = _classBObjFactory(classC); // instance 1
var classB2 = _classBObjFactory(classC); // instance 2
var classB3 = _classBObjFactory(classC); // instance 3
}
}
Основным преимуществом этого подхода является снижение требований к памяти за счет отказа от инициализации объектов, которые вы, возможно, не используете.Преимущество внедрения фабричного делегата состоит в том, что вы можете скрыть логику инициализации зависимостей и можете контролировать, какие фабричные параметры будут отображаться для вызывающей стороны.ClassA не нужно знать, как собрать все свои зависимости, ему нужно знать только те параметры, о которых он знает, и которыми он может управлять.Это позволяет вам заменить зависимости более легко.
Надеюсь, это имеет смысл :) Просто хотел продемонстрировать, как можно получить больше от паттерна, используя функциональный стиль C #.