1

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

[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 引导程序,虽然我可以把它放在那里

4

1 回答 1

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

请注意,“标签”是任意键。另请注意,如果您在程序的其他部分需要命名合同,您可以保留它。

构造函数变为:

[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。请注意,Enumerable.Single的使用仅在存在具有特定标记值的单个导出 IDAL 时才有效。

MEF 的 Codeplex 文档中的导出和元数据指南包含许多有用的示例。

于 2013-07-01T12:54:29.260 回答