组合选择实现



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

[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引导程序,我想我可能会把它放在那里

由于使用的是合同名称,因此可以将合同名称指定为特定参数的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文档中的导出和元数据指南包含了许多有用的示例。

最新更新