MEF和单独的接口组件导致"每个类的接口"

wag*_*agi 7 dependency-injection mef interface inversion-of-control

我特别喜欢DI/IoC和MEF.

我有一个Web应用程序,它有两种类型的部分(可能更有一天)由需要访问整个环境的接口定义.该应用程序有一个列表,其中包含每种类型的具体实现,由MEF组成.

环境包括:

  • 几个存储库
  • 目前的申请要求
  • 渲染引擎
  • 导航引擎
  • 加上一些静态实用程序类

如何将接口定义放在单独的程序集中,同时指定环境注入?

显然,我不能只引用主程序集,因为它需要引用契约程序集而我无法创建循环引用.

看来我需要为每个环境类创建一个接口,以及它们公开可用的类型等等......必须有更好的方法吗?!

也许我也错过了明显更大的缺陷,如果有人能指出来的话?

Mar*_*ann 10

如果你想将你的抽象与它们的实现分离(总是一个有价值的目标),你应该在它们自己的程序集中定义这些抽象.

从实现方面来说,这很容易处理,因为您需要引用抽象来实现它们.无论你是否使用MEF,都无法解决这个问题,因为它一如既往:

[Import(typeof(IFoo))]
public class MyFoo : IFoo { }
Run Code Online (Sandbox Code Playgroud)

但是,正如您所说,这意味着您无法从抽象库中引用您的Composition Root.但是,这是应该的,因为抽象不应该担心它们是如何组合的.

换句话说,您必须在抽象库之外实现依赖项的组合.一个很好的选择是可执行文件本身,而您可以将所有具体实现保存在一个或单独的库中.

抽象库将没有引用,而消费者和实现者都需要引用它,因此依赖关系图可能如下所示:

Composition Root --> Abstractions <-- Implementations
Run Code Online (Sandbox Code Playgroud)

箭头表示参考.

  • 对,那是正确的.所有这些额外的接口可能看起来像开销很多,但实际上每个接口都是**Seam**,你可以将实现者与消费者分开.最终结果是一个更松散的耦合系统.好处可能不会立即显而易见,但是一旦你开始体验消费和暴露抽象而不是具体类型的能力,你永远不会想要回去:) (2认同)