【问题标题】:Composition choosing implementation组合选择实现
【发布时间】:2013-06-28 05:51:00
【问题描述】:

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

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

【问题讨论】:

    标签: c# mef composition


    【解决方案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 文档中的 Exports and Metadata 指南包含许多有用的示例。

    【讨论】:

    • 不知道,谢谢。事情是我需要从应用程序设置中配置它,以便我可以在运行时切换,如果我采用上述方法,我需要重新编译应用程序
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-04-06
    • 1970-01-01
    • 1970-01-01
    • 2016-01-08
    • 1970-01-01
    • 1970-01-01
    • 2017-04-19
    相关资源
    最近更新 更多