Выборка объекта из контейнера и пример внедрения зависимости? - PullRequest
1 голос
/ 08 октября 2009

Пример ниже Внедрение зависимостей в отношении класса Worker? Класс Worker не получает экземпляр ITool из установщика свойств или конструктора, а скорее извлекает его из контейнера?

public MainClass {

    static void Main(string[] args) {
        ITool someTool = new Tool();
        MyContainer.Register<ITool>(someTool);
    }
}

public class MyContainer {

    private WindsorContainer container;

    public MyContainer() {
        container = new WindsorContainer();
    }

    public static T Resolve<T>() {
        return container.Resolve<T>();
    }

    public static void Register<T>(object instance) {
        container.Kernel.AddComponentInstance(typeof(T).ToString(), typeof(T), instance);
    }
}

public class Worker {

    public DoSomeWork() {
        ITool tool = MyContainer.Resolve<ITool>();
        tool.DoTheWork();
    } 
}

Ответы [ 6 ]

5 голосов
/ 08 октября 2009

Здесь у вас есть «Расположение службы», а не «Внедрение зависимостей», хотя оба являются примерами «Инверсии контроля».

Вы захотите прочитать « Инверсия управляющих контейнеров и шаблон внедрения зависимостей » и обратить пристальное внимание на этот раздел .

Не волнуйтесь, если вы чувствуете себя разбитым, это много, чтобы принять все сразу. Для более структурированного ознакомления с реальным инструментом внедрения зависимостей я настоятельно рекомендую Руководство пользователя Ninject .

5 голосов
/ 08 октября 2009

Для меня это пример Inversion of Control и Deverdency Inversion Princial, поскольку класс Worker запрашивает ITool из контейнера, а не создает его сам, но на самом деле это не пример внедрения Dependency Injection, поскольку зависимость не «вводится» извне, а «запрашивается» изнутри.

Термины могут быть довольно запутанными и часто используются взаимозаменяемо (неправильно), однако, пока ваш код отделен, чтобы вы не зависели от конкретных реализаций или «новых» вещей в ваших «модулях», то Вы получаете основные преимущества.

Лично очень редко я не делаю инъекцию в конструктор, даже если я не использую всеобъемлющий контейнер - я считаю это самым простым методом для модульных тестов и т. Д.

4 голосов
/ 08 октября 2009

Ну, я полагаю, это не строго "вводит" зависимость. Worker все еще имеет жестко запрограммированную зависимость от MyContainer - я полагаю, что для "истинного" внедрения зависимости потребуется передать ITool в Worker вместо Worker поиска ITool .

2 голосов
/ 09 октября 2009

IoC с контейнерами не так полезен, как внедрение зависимостей.

Если вы не передаете это, вы не получаете никаких преимуществ от чего-либо. Вы по-прежнему в значительной степени полагаетесь на глобальный элемент в единственном стиле: ваш контейнерный объект. Как только вы вводите (передаете) в контейнерный объект, вы не получаете никакой выгоды от контейнера! И вы также в конечном итоге передаете объект, который может разрешать все виды глобальных объектов, которые вам не нужны! Так зачем это делать? Это добавляет ненужную сложность. Контейнеры и реестры являются хорошим примером мышления астронавтов.

Передайте именно то, что вам нужно, и только то, что вам нужно. Если вам нужно что-то, что реализует ITool, передайте это. Не забудьте указать на переданный объект как интерфейс ITool. Это все, что вам нужно.

0 голосов
/ 23 июня 2011

DI часто неправильно понимают. Вот очень простой пример того, что DI, http://codingcraft.wordpress.com/2011/06/23/dependency-injection-simplified/

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

В дополнение ко всему в ответе Стивена Роббинса, это также пример шаблона Service Locator , поскольку класс MyContainer действует как Registy внутри класса Worker

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