Работа с циклическими зависимостями в МОК - PullRequest
9 голосов
/ 27 января 2009

Я пытаюсь использовать контейнер IOC для создания начального графа объектов в моем приложении.

У меня есть MainForm. Эта форма зависит от MenuStrip, который зависит от нескольких MenuStripItems. Некоторые MenuStripItems зависят от MainForm.

В данный момент я настраиваю все зависимости для внедрения в конструктор. Очевидно, что разрешение MainForm теперь приводит к переполнению стека, так как зависимости MenuStripItem от MainForm пытаются разрешить Mainform и т. Д. И т. Д.

Как лучше всего разрешить эту круговую зависимость?

Ответы [ 7 ]

5 голосов
/ 27 января 2009

Круговые зависимости являются признаком плохого дизайна, независимо от того, используете ли вы IoC или нет. Я предлагаю вам сделать редизайн, чтобы избежать этого. Добавление вспомогательного объекта может быть решением.

Например, сделать так, чтобы MenuStripItems зависели только от одной необходимой ему части MainForm, а не от всего.

3 голосов
/ 13 апреля 2010

Я согласен с kgiannakakis:

Круговые зависимости являются признаком плохой дизайн, независимо от того, используете ли вы МОК или нет. Я предлагаю вам сделать Редизайн, чтобы избежать этого. Добавление помощника объект может быть решением.

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

Учитывая, что у вас есть класс A и класс B, которые ссылаются друг на друга и создают круговую зависимость. Чтобы узнать, какие методы извлекать в объект внешнего помощника, перечислите все методы в вашем классе A, используемые классом A, и все методы в вашем классе B, используемые классом A. Короче из этих двух списков ваш скрытый помощник. класс С.

По мотивам Мишко Хевери http://misko.hevery.com/2008/08/01/circular-dependency-in-constructors-and-dependency-injection/

3 голосов
/ 27 января 2009

Вы можете использовать сеттер для внедрения некоторых зависимостей после построения.

3 голосов
/ 27 января 2009

Создайте класс контроллера, который предоставляет данные и логику, которые необходимы MainForm и MenuStripItem, чтобы избежать циклической ссылки.

1 голос
/ 30 октября 2017

Вам необходимо создать дилерский класс (или интерфейс), содержащий ссылку на оба класса, которые вы используете. Вы должны использовать этот дилерский класс (или интерфейс), а не каждый эталонный класс, который вы пытались использовать ранее.

Объясняя решение:
Рассмотрим 3 класса следующим образом:

public Class A {
    public Method CommonMethod(){
        //Some implementation...
    }

    Method C(){
        //CommonMethod form class B are using here
        B obj = new B();
        B.CommonMethod();
    }
}


public Class B {
    public Method CommonMethod(){
        //Some implementation...
    }

    Method D(){
        //CommonMethod form class A are using here
        A obj = new A();
        A.CommonMethod();
    }
}


public Class DealerClass {
    private readonly A _inctanceA;
    private readonly B _inctanceB;

    //Cunstructor method of the class
    DealerClass(A inctanceA, B inctanceB){
        _inctanceA = inctanceA;
        _inctanceB = inctanceB;
    }

    //Using CommonMethod of class A
    public UsingCommonMethodA(){
        _inctanceA.CommonMethod();
    }

    //Using CommonMethod of class B
    public UsingCommonMethodB(){
        _inctanceB.CommonMethod();
    }    
}

Таким образом, согласно этому решению вы должны использовать методы других классов, которые имеют круговую зависимость друг от друга в DealerClass.

1 голос
/ 27 января 2009

Я не вижу, как создание вспомогательного класса или контроллера решает проблему циклической зависимости.

Я дам еще несколько деталей. Элементы MenuStripItems зависят от MainForm, потому что они могут устанавливать содержимое MainForm. Следуя приведенным выше предложениям, допустим, я создал отдельный интерфейс для содержимого MainForm, IFormContent. MenuStripItem может затем зависеть от IFormContent. Но реализация IFormContent снова будет зависеть от MainForm, что приведет к циклической зависимости.

Может быть, мне стоит прибегнуть куда-нибудь к установщику, а не к конструктору?

0 голосов
/ 28 октября 2009

Как создаются MenuStrip и MenuStripItems?

Когда я использовал IOC, всегда существует отношение 1 к 1 между службой и зависимостями, которые контейнер IOC предоставляет для службы. Если службе требуется более одного объекта, она будет иметь отношение 1 к 1 с одним объектом фабрики, который создает несколько элементов. Этот фабричный метод может быть параметризован, чтобы позволить созданным элементам обращаться к своему контейнеру.

...