2015-02-23 3 views
0

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

Скажем, например, что у меня есть следующий контроллер:

public class TestController : Controller { 

    ILog logger; 

    public TestController(ILog log) { 

    logger = log; 

    } 

    public string TestMethod() { 

    businessLayer businessLayer = new businessLayer(); 

    return businessLayer.DoSomethingAndLogIt(); 

    } 

} 

Я понимаю, что в большинстве случаев это не представляется возможным использовать внедрение конструктора вне контроллера классов. Таким образом, было бы невозможно напрямую использовать ILog-внедрение insdie класса «businesslayer».

Одно простое решение, которое я мог себе представить, заключается в следующем:

public class TestController : Controller { 

    ILog logger; 

    public TestController(ILog log) { 

    logger = log; 

    } 

    public string TestMethod() { 

    businessLayer businessLayer = new businessLayer(logger); 

    return businessLayer.DoSomethingAndLogIt(); 

    } 

} 

Так переходя на зависимостях от контроллера до нижележащих слоев. Но это лучший способ? Существуют ли более эффективные решения для того, чтобы мой доступ к классу businessLayer к реализации ILog?

Thx!

ответ

3

Я понимаю, что в большинстве случаев использование конструктора впрыска вне классов контроллера.

Это неверное описание. Вы должны использовать инъекцию конструктора для всех ваших компонентов (каждый класс в вашем приложении, который содержит поведение).

Зависимость от инъекции - это инъекция зависимых услуг/компонентов во потребляющие компоненты. Таким образом, это означает, что вы не должны вводить новый класс businesslayer в свой контроллер; вы должны ввести его с помощью конструктора. Путем изменения этой зависимости вы нарушаете Dependency Inversion Principle, что вызывает высокую сцепность. Это снова делает ваш код более сложным для тестирования и затрудняет изменение контроллера и затрудняет применение в системе сквозных задач (таких как ведение журнала, завершение аудита, управление транзакциями и т. Д.).

Таким образом, было бы невозможно напрямую использовать реализацию ILog insdie класс «businesslayer».

Неверный. Реализация ILog должна быть введена в конструктор вашего класса businesslayer.

Короче говоря, ваш контроллер должен выглядеть следующим образом:

public class TestController : Controller { 
    IBusinessLayer businessLayer; 

    public TestController(IBusinessLayer bl) { 
    this.businessLayer = bl; 
    } 

    public string TestMethod() { 
    return businessLayer.DoSomethingAndLogIt(); 

}}

Поскольку TestController не кажется использовать ILog непосредственно, он не должен быть введен в конструктор. ILog - это деталь реализации класса бизнес-уровня, и детали реализации не должны протекать потребителю (это опять-таки будет нарушением принципа инверсии зависимостей).

+0

Thx! Одна вещь, которую я не понимал, - это то, как IBusinessLayer будет использовать реализацию ILog. Но большинство DI-контейнеров, похоже, могут решить это при регистрации. http://simpleinjector.readthedocs.org/ru/latest/using.html#automatic-constructor-injection-auto-wiring – mhtsbt

+0

@Matthias: Это не касается контейнеров DI.Каждый класс должен просто принимать зависимости, которые он (непосредственно) нуждается в качестве аргументов конструктора, а в пути запуска приложения вы создаете полный графический объект (ы) ([Корень композиции] (http://blog.ploeh.dk/ 2011/07/28/CompositionRoot /)). Для этого вам не нужен контейнер DI, и он может даже иметь преимущества, чтобы не использовать контейнер вообще. С другой стороны, контейнер DI может помочь сделать ваш корневой состав намного более удобным. – Steven

Смежные вопросы