选择实施的构成

时间:2013-07-01 06:53:36

标签: c# mef composition

如果我有多个相同接口的实现

[Export("DALREMOTE", typeof(IDAL))]
[PartCreationPolicy(CreationPolicy.Shared)]
public class DAL : IDAL

[Export("DALLOCAL", typeof(IDAL))]
[PartCreationPolicy(CreationPolicy.Shared)]
public class DAL : IDAL

有没有办法以编程方式选择在模块的构造函数中使用哪个实现作为标准。

[ImportingConstructor]
public ShellViewModel(IDAL dal........

我正在使用PRISM / MEF引导程序,虽然我可以把它放在那里

1 个答案:

答案 0 :(得分:1)

由于您使用的是合约名称,因此可以将合约名称指定为特定参数的ImportAttribute的一部分。

以下是使用“DALLOCAL”合同名称的示例:

[ImportingConstructor]
public ShellViewModel([Import("DALLOCAL")]IDAL dal........

ImportAttribute可用于装饰参数和属性。

根据您的评论,您不希望使用合同名称,并且希望能够从某种应用程序配置中选择运行时的实现,您可以使用导出元数据。以下是使用弱元数据的示例:

[Export("DALREMOTE", typeof(IDAL))]
[ExportMetadata("Tag", "DALREMOTE")]
[PartCreationPolicy(CreationPolicy.Shared)]
public class DAL : IDAL

[Export("DALLOCAL", typeof(IDAL))]
[ExportMetadata("Tag", "DALLOCAL")]
[PartCreationPolicy(CreationPolicy.Shared)]
public class DAL : IDAL

请注意,“Tag”是一个任意键。另请注意,如果您需要在程序的其他部分使用,则可以保留命名合同。

构造函数变为:

[ImportingConstructor]
public ShellViewModel([ImportMany]IEnumerable<Lazy<IDAL, IDictionary<string, object>>> dals)
{
    if (dals == null) throw new ArgumentNullException("dals");

    //Get the tag from your apps configuration.
    string tagFromConfiguration = ........

    _dal = dals.Where(l => l.Metadata["Tag"].Equals(tagFromConfiguration )).Single().Value;
}

这里的主要区别在于,不是单个IDAL,而是注入一系列IDAL。然后在.ctor中,您将必须选择所需的IDAL。请注意,仅当存在具有特定标记值的单个导出IDAL时,才使用Enumerable.Single

MEF的Codeplex文档中的Exports and Metadata指南包含了许多有用的示例。