MEF и отдельная сборка интерфейса приводят к "интерфейсу для каждого класса",

Я мочу ноги с помощью DI/IoC и MEF в частности.

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

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

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

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

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

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

Возможно, мне тоже не хватает очевидного большего недостатка, если кто-нибудь может указать мне на меня?

Ответ 1

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

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

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

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

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

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

Composition Root --> Abstractions <-- Implementations

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