我正在尝试使用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; ./")
我是否误解了部分构造者的工作方式? 如何让它接受构造函数参数?
编辑投诉:someinstance
是sometype
的特定实例。我不想在容器中添加类型,而是添加特定的类实例。
答案 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的工作方式。
干杯