Является ли наличие обертки для вашего IoC хорошей идеей? - PullRequest
3 голосов
/ 24 ноября 2010

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

class IoC {
    public static T GetInstance<T>()
    {
        return (T)GetInstance(typeof(T));
    }
    public static IEnumerable<T> GetAllInstances<T>()
    {
        return ObjectFactory.GetAllInstances<T>();
    }

    public static IEnumerable GetAllInstances(Type type)
    {
        return ObjectFactory.GetAllInstances(type);
    }

    public static object GetInstance(Type type)
    {
        return ObjectFactory.GetInstance(type);
    }

    public static void Inject<T>(T obj)
    {
        ObjectFactory.Inject(obj);
    }
}

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

Каковы плюсы / минусы использования этого подхода?

Ответы [ 3 ]

6 голосов
/ 24 ноября 2010

По этой причине был разработан проект Common Service Locator . Это абстракция над DI-фреймворками, и он определяет интерфейс, очень похожий на ваш IoC класс. Я даже разработал библиотеку Simple Service Locator ; библиотека DI, которая является прямой реализацией интерфейса Common Service Locator.

Так что в этом смысле не странно иметь абстракцию над структурами DI. Однако при правильном (и полном) выполнении Dependency Injection идея состоит в том, чтобы соответствующим образом настроить дизайн приложения, настроить контейнер в корне приложения и, желательно, иметь только одно место в приложении, где собраны типы (читай: были GetInstance называется). Для приложения ASP.NET MVC это будет ControllerFactory. Для приложения ASP.NET WebForms обычно требуется переопределить PageHandlerFactory .

Когда вы играете по этим правилам, нет смысла использовать такую ​​абстракцию, потому что вы все равно просто вызываете контейнер в одном месте вашего приложения. Однако, если это невозможно для вас, в качестве альтернативы можно использовать Common Service Locator или собственную абстракцию.

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

  • Делает код намного сложнее для тестирования.
  • Скрывает зависимости, делая код труднее для чтения и обслуживания.
  • Отключает поддержку во время компиляции.
  • Запрещает проверку графиков зависимостей с помощью инструмента.
1 голос
/ 10 ноября 2013

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

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

1 голос
/ 24 ноября 2010

Преимущество заключается в том, что вы можете безболезненно менять контейнеры IOC. Дело в том, что вы теряете любую функциональность, специфичную для контейнера IOC. MVC турбина использует этот подход. Посмотрите на его источник, чтобы увидеть, как он обрабатывает локатор. http://mvcturbine.codeplex.com/

...