为什么MEF在部件构造函数上失败?

时间:2016-07-14 17:16:21

标签: c# .net constructor mef

我正在尝试使用MEF构建模块化应用程序 但是,在编写它时似乎忽略了SetExportedValue(..., ...),导致它找不到我需要的值/对象。

这是我的(匿名和简化)代码:

interface IPlugin {  }
class MyClass
{
    [ImportsMany(typeof(IPlugin))]
    public IEnumerable<Lazy<IPlugin>> Plugins;

    public LoadParts()
    {
        var ac = new AggregateCatalog();
        ac.Catalogs.Add(new AssemblyCatalog(typeof(PluginManager).Assembly));

        // imagine adding some DirectoryCatalogs here

        var cc = new CompositionContainer(ac);
        cc.ComposeExportedValue("MyValue", someinstance);
        cc.ComposeParts(this);
    }
}
[Export(typeof(IPlugin))]
class MyPart : IPlugin
{
    [ImportingConstructor]
    public MyPart([Import("MyValue")] sometype arg)
    { }
}

这会导致以下错误消息:

  

System.ComponentModel.Composition警告:1:ComposablePartDefinition&#39; MyNamespace.MyPart&#39;被拒绝了。构图保持不变。由于以下错误,更改被拒绝:组合产生单个组合错误。根本原因如下。查看CompositionException.Errors属性以获取更多详细信息。

     

1)没有找到符合约束的导出:

ContractName  MyValue
RequiredTypeIdentity  somenamespace.sometype
     

导致:无法设置导入&#39; MyNamespace.MyPart..ctor(参数=&#34; ...&#34;,ContractName =&#34; ...&#34;)&# 39;部分&#39; MyNamespace.MyPart&#39;。
  元素:MyNamespace.MyPart..ctor(参数=&#34; ...&#34;,ContractName =&#34; ...&#34;) - &gt; MyNamespace.MyPart - &gt; DirectoryCatalog(路径=&#34; ./")

我是否误解了部分构造者的工作方式? 如何让它接受构造函数参数?

编辑投诉:someinstancesometype的特定实例。我不想在容器中添加类型,而是添加特定的类实例。

1 个答案:

答案 0 :(得分:1)

您的ImportingConstructor也需要有效的合同,而不仅仅是价值。

这是一个示例,我的构造函数的工作原理:

[ImportingConstructor]
    public MyType([Import] IStatus status, [Import] IProtocoll protocoll) {
    }

如您所见,您需要使用Interfaces作为Contructor-Parameters。

这些接口简单明了,没有任何必需的属性。

IProtocoll的片段

public interface IProtocoll {

    IProtocollStateController ProtocollController { get; set; }

    void WriteProtocoll(string action, string message, bool? result, Guid conditionId);

    void WriteProtocoll(Protocoll protocoll);

    List<Protocoll> GetAllProtocoll();
  }

我建议您在有效的界面中转换MyValue。对于一个简单的字符串,这可能有点过分,但这就是MEF的工作方式。

干杯