MEF и отдельная сборка интерфейса приводят к «Интерфейсу для каждого класса» - PullRequest
7 голосов
/ 01 марта 2010

Я промочил ноги, в частности, DI / IoC и MEF.

У меня есть веб-приложение, которое состоит из двух типов частей (возможно, когда-нибудь больше), определенных интерфейсами, которым требуется доступ ко всей среде. Приложение имеет список с конкретными реализациями для каждого типа, составленный MEF.

Среда состоит из:

  • несколько репозиториев
  • текущий запрос заявки
  • рендер движок
  • навигационный движок
  • плюс некоторые статические служебные классы

Как я могу поместить определения интерфейса в отдельную сборку и в то же время указать внедрение среды?

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

Кажется, мне нужно создать интерфейс для каждого из классов среды, их общедоступных типов и т. Д. Должен быть лучший способ?!

Может быть, я также упускаю очевидный больший недостаток, если кто-нибудь может указать мне на это?

1 Ответ

10 голосов
/ 02 марта 2010

Если вы хотите отделить свои абстракции от их реализаций (всегда достойная цель), вы должны определить эти абстракции в их собственной сборке.

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

[Import(typeof(IFoo))]
public class MyFoo : IFoo { }

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

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

Библиотека абстракций не будет иметь ссылок, в то время как потребители и разработчики должны будут ссылаться на нее, поэтому граф зависимостей может выглядеть следующим образом:

Composition Root --> Abstractions <-- Implementations

Где стрелки обозначают ссылку.

...