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

Why is MEF failing on the part constructor?

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

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

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 Warning: 1 : The ComposablePartDefinition 'MyNamespace.MyPart' has been rejected. The composition remains unchanged. The changes were rejected because of the following error(s): The composition produced a single composition error. The root cause is provided below. Review the CompositionException.Errors property for more detailed information.

1) No exports were found that match the constraint:

ContractName  MyValue
RequiredTypeIdentity  somenamespace.sometype

Resulting in: Cannot set import 'MyNamespace.MyPart..ctor (Parameter="...", ContractName="...")' on part 'MyNamespace.MyPart'.
Element: MyNamespace.MyPart..ctor (Parameter="...", ContractName="...") --> MyNamespace.MyPart --> DirectoryCatalog (Path="./")

我是不是误解了部分构造函数的工作原理?
如何让它接受构造函数参数?


编辑澄清:someinstancesometype 的特定实例。我不想向容器添加类型,而是添加特定的 class 实例。

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

这是一个例子,我的构造函数是如何工作的:

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

如您所见,您需要使用接口作为构造函数参数。

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

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 的工作原理。

干杯