Пытаясь понять МОК и обязательность - PullRequest
0 голосов
/ 15 марта 2012

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

Пожалуйста, исправьте меня, если я не так понимаю, потому что мой вопрос основан на этом:

Теперь я вижу эту модель очень часто в следующих проектах:

private readonly IEmailService emailService;
private readonly ITemplateRenderer templateRenderer;
private readonly IHtmlToTextTransformer htmlToTextTransformer;

public TemplateEmailService(IEmailService emailService,
    ITemplateRenderer templateRenderer,
    IHtmlToTextTransformer htmlToTextTransformer)
{
    this.emailService = emailService;
    this.htmlToTextTransformer = htmlToTextTransformer;
    this.templateRenderer = templateRenderer;
}

Я понимаю, что это помогает использовать все реализации этих классов без их обновления, а также вам не нужно решать, какую реализацию получить, ваш IOC решит это за вас, верно?

но когда я кодируютаким образом, я даже не касаюсь файлов конфигурации IOC.И снова я использую git только в течение 2 дней, но из всех прочитанных мною учебников я ожидал, что я сам настрою что-то, что скажет класс «Разрешить IParent to Child».Но это работает без меня, ничего подобного.Это потому, что существует только одна реализация этих интерфейсов?и если у меня есть несколько реализаций, тогда и только тогда мне придется настраивать в явном виде?

1 Ответ

4 голосов
/ 22 марта 2012

Пример кода, который у вас есть, это случай Конструктор Injection .

В традиционном коде у вас был бы конструктор без параметров, и в нем вы бы "обновляли" ваши объекты следующим образом:

IEmailService emailService = new EmailService();

Таким образом, ваш код явно контролирует, какая реализация присваивается переменной интерфейса.

В IoC с использованием инжекции в конструктор управление инвертируется, что означает, что контейнер "управляет шиной" и создает ваш объект TemplateEmailService. Когда он собирается его создать, контейнер просматривает параметры вашего конструктора (IEmailService, ITemplateRenderer и т. Д.) И передает эти объекты в ваш класс для использования.

Контейнер IoC можно настроить так, чтобы интерфейс A выполнялся реализацией B (или C) явно. У каждого есть способ сделать это. Или он может сделать это по соглашению (IFoo выполняется Foo), или даже атрибуты в классах, что угодно.

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

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

...