MEF против любого IoC

Глядя на Microsoft Managed Extensibility Framework (MEF) и различные контейнеры IoC (такие как Unity), я не могу понять, когда использовать один тип решения над другим. Более конкретно, кажется, что MEF обрабатывает большинство шаблонов типов IoC и что контейнер IoC, такой как Unity, не будет необходим.

В идеале я хотел бы видеть хороший пример использования контейнера IoC вместо MEF или в дополнение к нему.

4 ответа

Решение

При разложении основное различие заключается в том, что контейнеры IoC обычно наиболее полезны со статическими зависимостями (известными во время компиляции), а MEF обычно наиболее полезен с динамическими зависимостями (известными только во время выполнения).

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

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

Кроме того, статья в ответе @Pavel Nikolov дает несколько отличных указаний (ее написал Гленн Блок, руководитель программы MEF).

Я уже некоторое время использую MEF, и ключевым фактором, когда мы используем его вместо продуктов IOC, является то, что мы регулярно имеем 3-5 реализаций данного интерфейса, которые находятся в каталоге плагинов в данный момент времени. Какую из этих реализаций следует использовать, на самом деле может быть решено только во время выполнения.

MEF хорошо позволяет вам делать это. Как правило, IOC направлен на то, чтобы в какой-то момент в будущем вы могли заменить, например, IUserRepository, основанный на ORM Product 1 для ORM Product 2. Однако большинство решений IOC предполагают, что в данный момент будет действовать только один IUserRepository.

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

В качестве примера, мы проводим проверку разрешений и проверку с помощью плагинов MEF для большого веб-приложения, над которым я работал некоторое время. Используя MEF, мы можем посмотреть на дату создания записи CreatedOn и перейти к поиску подключаемого модуля проверки, который фактически действовал при создании записи, и запустить запись ОБА через этот подключаемый модуль И действующий в настоящее время валидатор и сравнить действительность записи с время.

Этот тип мощности также позволяет нам определять сквозные переопределения для плагинов. Приложения, над которыми я работаю, на самом деле представляют собой одну и ту же кодовую базу, развернутую для 30+ реализаций. Итак, мы обычно ищем плагины, спрашивая:

  1. Реализация интерфейса, специфичная для текущего сайта и определенного типа записи.
  2. Реализация интерфейса, специфичная для текущего сайта, но работающая с любыми типами записей.
  3. Интерфейс, который работает для любого сайта и любой записи.

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

IOC - отличная технология, но на самом деле, кажется, она больше направлена ​​на то, чтобы упростить кодирование интерфейсов вместо конкретных реализаций. Тем не менее, замена этих реализаций является скорее событием сдвига проекта в МОК. В MEF вы берете гибкость интерфейсов и конкретных реализаций и принимаете решение во время выполнения между многими доступными опциями.

Я извиняюсь за то, что не по теме. Я просто хотел сказать, что есть 2 недостатка, которые делают MEF ненужным осложнением:

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

  • в нем нет механизма устранения неполадок, позволяющего выяснить причины отклонения некоторых деталей. Несмотря на указание на неисправную часть, она не говорит вам, почему эта часть вышла из строя.

Поэтому я очень разочарован этим. Я потратил слишком много времени на борьбу с ветряными мельницами, пытаясь запустить несколько классов вместо того, чтобы работать над реальными проблемами. Я убежден, что нет ничего лучше старой методики внедрения зависимостей, когда у вас есть полный контроль над тем, что создается, когда и может отследить что-либо в отладчике VS. Я хотел бы, чтобы кто-то, кто защищает MEF, представил кучу веских причин, почему я бы выбрал его вместо обычного DI.

Я согласен с тем, что MEF может быть полностью функциональной средой IoC. На самом деле я пишу приложение прямо сейчас, основанное на использовании MEF для расширяемости и IoC. Я взял его общие части и превратил в "фреймворк" и открыл его в виде собственного фреймворка под названием SoapBox Core на тот случай, если люди захотят увидеть, как он работает.

В частности, посмотрите, как работает Хост, если вы хотите увидеть MEF в действии.

Другие вопросы по тегам