Инъекция отражательной зависимости .NET с несколькими контейнерами - PullRequest
2 голосов
/ 26 октября 2010

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

Допустим, у меня есть два контейнера, каждый из которых содержит разные экземпляры одного и того же типа зависимости.Например, каждый из них содержит различные отдельные экземпляры MyApplicationContext и MyRequestContext.

. Теперь давайте скажем, что у меня есть несколько классов, которые зависят от одного (или обоих) этих экземпляров.Они не должны беспокоиться о том, какой из двух контейнеров они используют;им просто необходим экземпляр зависимости, чтобы выполнить работу.

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

public class MyDependableClass{
  protected MyApplicationContext Application {get; set;}
  protected MyRequestContext Request {get; set;}
  public MyDependableClass() {
    Dependencies.Inject(this);
  }
}

Однако, AFAIK, нет практического способа определить подходящий контейнер.Я рассмотрел возможность регистрации каждого объекта в определенном контейнере (например, container.Register(obj);), но это было бы трудоемким и не сработало бы, если бы в конструкторе требовались зависимости.В качестве альтернативы вы можете проанализировать стек вызовов, чтобы вывести контейнер из зарегистрированного объекта верхнего уровня ... не будет работать для асинхронных вызовов и т. Д.

Любые идеи?

Пример: У меня может быть несколько классов, которые могут зависеть от экземпляра прокси;давайте назовем это ILogicProxy.Этот прокси может переадресовывать вызовы на локальную или удаленную логику на другом компьютере.Кроме того, приложение может устанавливать соединения с несколькими удаленными компьютерами.Итак ... у нас есть потенциально несколько ILogicProxy экземпляров, которые нужно внедрить в несколько классов ... но какой из них идет куда?Подобное решение может просто использовать простое «внедрение свойства сеттера», однако оно не масштабируется, когда требуется больше зависимостей, поскольку это приведет к тому, что процесс «подключения» станет грязным / многословным.

Ответы [ 2 ]

1 голос
/ 26 октября 2010

Это не относится к нескольким контейнерам.Используйте конфигурацию контейнера, чтобы соединить вещи.Если у вас есть большое количество компонентов, зарегистрированных в интерфейсе ILogicProxy, то да, вам придется больше подключать вручную.Но спросите себя, должны ли эти компоненты действительно регистрироваться под одним и тем же интерфейсом.

О примере кода:

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

public class MyDependableClass{
  protected MyApplicationContext Application {get; set;}
  protected MyRequestContext Request {get; set;}
  public MyDependableClass() {
    Dependencies.Inject(this);
  }
}

Это расположение службы, а не внедрение зависимостей.Всегда предпочитайте внедрение зависимости местоположению службы.Старайтесь не зависеть от методов Resolve () или Inject () в ваших компонентах.

0 голосов
/ 27 октября 2010

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

public class LogicProxyRouter : ILogicProxy
{
    private readonly ILogicProxy local;
    private readonly ILogicProxy remote;

    public LogicProxyRouter(ILogicProxy local, ILogicProxy remote)
    {
        this.local = local;
        this.remote = remote;
    }

    public void Method(params)
    {
        if (someCondition)
        {
            this.local.Method(params);
        }
        else
        {
            this.remote.Method(params);
        }
    }
}

Таким образом, вы можете подключить один экземпляр, например:

ILogicProxy proxy =
    new LogicProxyRouter(new LocalLogicProxy(), new RemoteLogicProxy());

// Register that instance in your favorite IoC framework
container.RegisterSingle<ILogicProxy>(proxy);

Iнадеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...