控制哪个部分由MEF组成

时间:2011-12-07 14:20:22

标签: .net mef

我有以下课程:

public class Foo
{
    [Import]
    public IFirstInterface firstImport;

    [Import]
    public ISecondInterface secondImport;

    // ...
}

public class A : ISecondInterface {}

public class B : ISecondInterface {}

我想在课堂上调用

var foo = compositionContainer.GetExportedValue<Foo>();

要指定我想要使用A类或B类。

我知道,我可以在GetExportedvalue方法中指定合约名称。但据我了解,这意味着有两个类Foo。我想重用相同的类,但控制使用哪个类(A或B)来满足ISecondInterface依赖。

编辑: “决定你是使用A级还是B级的规则是什么?”

A: Foo由wcf服务调用。 A类和B类的不同之处在于它们正在处理不同的实体。这些实体具有不同的字段,无法以相同的方式查询。

我的课程不是英语,但我会尝试翻译成比Foo和Bar更有意义的术语。

Foo可能是RecordAssigner。 RecordAssigner为用户分配记录。执行此操作的逻辑包含在此类中。 ISecondInterface是与记录一起使用的数据层类的接口。

它的实现公开了处理不同类型记录的方法。虽然两种类型的记录都需要公开分配它们的必要方法,但它们在数据级别上的处理方式也不同。

在服务级别,我希望能够调用方法 AssignRecordTypeA和AssignRecordTypeB,而不复制RecordAssigner中的所有代码。

2 个答案:

答案 0 :(得分:1)

决定您是使用A级还是B级的规则是什么?您可以为MEF导出编写自己的解析器。

此博文http://randomactsofcoding.blogspot.com/2010/01/configurable-type-catalog-for-mef.html提到了一种方法,如果您搜索“mef custom export provider”或“mef custom catalog”,您可以找到其他一些方法

修改 您的方案让我想起了不久前与一些同事的一些对话。在我看来,MEF是针对应用程序的“扩展”而不是依赖项。你看起来更像是依赖。因此,最好使用IoC容器来管理依赖项。您可以使用不同的密钥注入多个ISecondInterface实例,然后选择要使用的实例。

如果您认为MEF更适合您的要求,您仍可以通过更改

来实现此目的
public class Foo
{
    [Import]
    public IFirstInterface firstImport;

    [ImportMany]
    public Collection<ISecondInterface> secondImport;

    // ...
}

然后决定使用哪一个。

话虽如此,有一个服务处理与两个不同存储库对话的两个不同实体的情况是值得商榷的。 如果你有一些共同的逻辑,你可以重构它,但最好有两个不同的服务,每个服务都需要依赖它来完成它的工作。

答案 1 :(得分:1)

我无法立即想到在MEF中执行此操作而不创建任何其他类的方法。我能想到的最好的方法是创建具有不同Foo规范的[Import]子类。

其他容器如AutoFac(请参阅example)或Ninject(请参阅contextual binding)可以为您提供更细粒度的控制。