【问题标题】:How to make a "discoverable" service in MEF without a Shared Interface?如何在没有共享接口的情况下在 MEF 中创建“可发现”服务?
【发布时间】:2014-10-22 23:32:30
【问题描述】:
这是场景。
Assembly main 使用 MEF 将程序集 a 和程序集 b 加载到 appdomain 中。现在假设程序集a 和b 都提供可以使用的服务。
程序集a 是否可以在运行时调用/实例化程序集b 中的类,而无需引用?本质上是让服务“可发现”?
我通常会使用两个程序集都引用的共享接口,但在这种情况下,程序集 a 和 b 直到运行时才知道彼此。
【问题讨论】:
标签:
c#
reflection
mef
.net-assembly
【解决方案1】:
这是我的看法:
您只需要一个接口即可让 MEF 工作。哇,你真的不需要那个,你可以解析一个 object 类型的命名合约,它返回一个对象,并且该对象可以做任何它想做的事情,比如通过 MEF 解决其他依赖关系,并在他们的 OWN 库中使用合约。
[Import("MyEntryDelegate",typeof(object))]
public Lazy<object> mefBootstrapper { get; set; }
您有一个由 MEF 为一个常见的已知接口解析的对象,所有其他 MEF 解析的对象将在目录中加载的外部 dll 中发现它们自己的部分。就像摇和烘焙 IoC,在你的库中编写你自己的接口和[Import] 对你内心内容的依赖
在你正在创建的任何对象的构造函数中,你可以引导任何你想要的。
interface INeedSomethingOfMyOwn{
void DoSomething();
}
[Export("MyEntryDelegate",typeof(object))]
class MyClass{
private readonly INeedSomethingOfMyOwn _myobj;
[ImportingConstructor]
public MyClass([Import]INeedSomethingOfMyOwn myobj){
_myobj = myobj;
}
}
【解决方案2】:
由于多态性,在应用了适当的类型转换后,共享接口允许以早期绑定(静态类型)方式使用该值。虽然需要各方之间的共同知识,但共享接口也可以在外部程序集中维护 - 这通常是我使用的方法。
还有结构类型(这个术语在 C#/.NET 中不使用) - 基本上在消费者中有一个 不同 接口/类型,这样写它匹配消费类型。有问题的对象以静态类型的方式访问(通过消费者中定义的类型),但用作动态代理。请参阅How to make a simple dynamic proxy in C# 了解详细信息/限制和一些实现链接。
但是,如果上述两种方法都不起作用,则只能使用 后期绑定(动态类型) - 例如带有对象值的 Reflection 或 dynamic-typed 表达式。有些人喜欢它,但我更喜欢早期绑定。这绝对是最“灵活”的方法。