Подтвердить что ты не робот

Инъекция зависимостей - требуется новый экземпляр для нескольких методов классов

У меня есть код, который выглядит примерно так:

public MyService(IDependency dependency)
{
    _dependency = dependency;
}

public Message Method1()
{
    _dependency.DoSomething();

}

public Message Method2()
{
    _dependency.DoSomething();  
}

public Message Method2()
{
    _dependency.DoSomething();  
}

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

Итак, каков наилучший способ сделать это, и до сих пор не существует конкретного экземпляра?

Используете ли вы контейнер IoC и вызываете контейнер в каждом из этих методов? Или есть ли более гладкий способ, когда вы можете сделать только один вызов контейнера?

Что делать, если я не использовал контейнер IoC - будет ли способ не создавать конкретный экземпляр в каждом методе?

4b9b3361

Ответ 1

Большинство ответов здесь пока предлагают, чтобы вы изменили тип вложенной зависимости на какой-то Аннотация Factory (a Func<T> также является абстрактным Factory) для решения этой проблемы. Однако, если вы это сделаете, это будет нечеткая абстракция, потому что вы позволите знанию конкретной реализации определить дизайн потребителя. Это нарушает Принцип замены Лискова.

Лучшим вариантом является сохранить MyService как, а затем создать оболочку для IDependency, которая учитывает конкретную проблему в течение всей жизни:

public class TransientDependencyWrapper : IDependency
{
    public void DoSomething()
    {
        new MyStatefulDependency().DoSomething();
    }
}

Внесите это в MyService вместо прямого ввода исходной реализации (MyStatefulDependency).

Если вы хотите отвлечься от создания зависимостей, вы всегда можете ввести абстрактный Factory на этом уровне.

Ответ 2

Похоже, вы должны ввести поставщика / factory. Как вы представляете, что зависит от вас (и что поддерживает IoC) - это может быть так же просто, как:

public MyService(Func<IDependency> dependencyProvider)
{
    this.dependencyProvider = dependencyProvider;
}

public Message Method1()
{
    IDependency dependency = dependencyProvider();
    dependency.DoSomething();    
}

... или у вас может быть интерфейс для этого конкретного типа factory или общий IFactory<T> и т.д. Существуют всевозможные возможности, но основной бит заключается в том, что вы вводите то, что вам нужно, что в этом case - это "способ создания новой реализации IDependency для каждого вызова".

Ответ 3

Если вам нужно создать несколько экземпляров введенного типа, вы должны ввести вместо него IDependencyFactory, который будет отвечать за управление жизненными циклами экземпляра:

interface IDependencyFactory
{
    IDependency GetInstance();
}

Ответ 4

Вы можете сделать это следующим образом:

private readonly Func<IDependancy> _dependancy;
public MyService(Func<IDependancy> dependancy)
{
    _dependancy = dependancy;
}

public Message Method1()
{
    _dependancy().DoSomething();
}

public Message Method2()
{
    _dependancy().DoSomething();  
}

public Message Method3()
{
    _dependancy().DoSomething();  
}

И затем:

var service = new MyService(() => new SomeConcreteDependency());
service.Method1();
service.Method2();
service.Method3();

Ответ 5

Первые две идеи, которые приходят мне в голову,

  • Не вводите его в конструктор, но используйте его для каждого метода.
  • Вместо передачи экземпляра в конструктор перейдите в factory или Func<IDependency>, который будет создавать новый экземпляр каждый раз, когда вы вызываете func.