Инъекция зависимости с циклической зависимостью - PullRequest
1 голос
/ 05 октября 2011

Позвольте мне иметь два очень простых объекта, таких как:

public class View
{
    public View(Controller controller)
    {
        // Use the model exposed by the controller here
    }
}

public class Controller
{
    private readonly IView view;

    public Controller()
    {
        this.view = new View(this);
    }

    public Controller(View v)
    {
        this.view = v;
    }
}

Позже я решаю ввести объект View в контроллер через DI, но там у меня циклическая зависимость (т.е. я не могу использовать var ctrl = new Controller(new View(ctrl));). Как бы вы поступили по поводу внедрения зависимости в этом случае?

Ответы [ 3 ]

4 голосов
/ 05 октября 2011

Наиболее распространенным решением является использование свойства зависимости для решения циклических зависимостей.т.е. создайте новое свойство в одном из классов и позвольте контейнеру IoC назначить его.

Если вы используете Unity, вам следует добавить [Dependency] к этому свойству.

sidenote: A Viewне должно иметь зависимости от контроллера.Он не должен знать об этом вообще.

Обновление в ответ на комментарий

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

1 голос
/ 05 октября 2011

Я действительно нашел хорошее решение, используя Ninject.

public class Controller
{
    private readonly View view;

    public Controller(ViewModule viewModule)
    {
        using (IKernel kernel = new StandardKernel(viewModule))
        {
            this.view = kernel.Get<View>(new ConstructorArgument("controller", this);
        }
    }
}

Там, где ViewModule - это предварительно сконфигурированный модуль Ninject для разрешения конкретной зависимости представления (GUI, CLI и т. Д.). Небольшая проблема здесь заключается в том, что я теперь зависим от конкретной структуры DI.

0 голосов
/ 05 октября 2011

Вы не можете сделать это вообще с помощью инжектора конструктора. Если вы измените конструктор контроллера на

public Controller(IView view)

, в каком порядке вы бы создали два объекта?Для просмотра необходим экземпляр Instance, а для контроллера - представление.Тем не менее, вы можете сделать свойство IView контроллера открытым и установить свойство после создания (некоторые DI-контейнеры могут сделать это автоматически при установке правильного атрибута).

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