为什么 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="./")
我是不是误解了部分构造函数的工作原理?
如何让它接受构造函数参数?
编辑澄清:someinstance
是 sometype
的特定实例。我不想向容器添加类型,而是添加特定的 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 的工作原理。
干杯
我正在尝试使用 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="./")
我是不是误解了部分构造函数的工作原理?
如何让它接受构造函数参数?
编辑澄清:someinstance
是 sometype
的特定实例。我不想向容器添加类型,而是添加特定的 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 的工作原理。
干杯