MEF,为什么同一个出口插件创建的相同的重复? [英] MEF, why are identical duplicates of one and the same exported plugin created?
问题描述
(1)使用下面的代码,我在同一个出口插件容器得到完全相同2项,我不知道为什么:
(2)其他问题这我真的无法实施:我如何扩展框架来处理不同类型的插件(如具有不同类型,或存储的所有插件在一个动态的IEnumerable左右一个导入的几个进口)。我想在我的静态包装类以提供返回发现的插件类型和匹配元数据的功能,一个通用的方法。
导出插件(驻留在一个单独的DLL,其位置指向的 DirectoryCatalog
建成时。
[导出(typeof运算(IPlugin))//< ----如果该行被注释掉那么只有一个项目进口的(为什么?)
[PluginAttribute(typeof运算(StrategyPlugin_Test1),StrategyPlugin,Plugin1)]
公共类StrategyPlugin_Test1:IPlugin
{
公共无效DoSomething的( )
{
Console.WriteLine(我做了什么);
}
}
下面的代码定义了强类型的元数据和进口,以及执行的MEF功能,应该保持发现插件静态类:
[MetadataAttribute]
[AttributeUsage(AttributeTargets.Class,的AllowMultiple = FALSE)]
公共类PluginAttribute:ExportAttribute
{
公共类型PluginType {获取;集;}
公共字符串PluginGroupName {搞定;组; }
公共字符串PluginName {搞定;组; }
公共PluginAttribute(类型pluginType,串pluginGroupName,串pluginName):基地(typeof运算(IPlugin))
{
PluginType = pluginType;
PluginGroupName = pluginGroupName;
PluginName = pluginName;
}
}
公共接口IPluginAttribute
{
型PluginType {搞定; }
串PluginGroupName {搞定; }
串PluginName {搞定; }
}
公共接口IPlugin
{
无效DoSomething的();
}
公共类PluginDefinition
{
[ImportMany(typeof运算(IPlugin))]
公开的IEnumerable<懒人< IPlugin,IPluginAttribute>>插件{搞定;组; }
公共PluginDefinition()
{
}
}
下面的静态类,它包装一些核心MEF的东西:
公共静态类插件管理
{
私有静态PluginDefinition PluginDefinitions {搞定;组; }
静态插件管理()
{}
公共静态无效配置(PluginDefinition pluginDefinitions,IEnumerable的<串> pluginDirectories)
{
AggregateCatalog aggregateCatalog =新AggregateCatalog(新DirectoryCatalog(pluginDirectories.FirstOrDefault()));
CompositionContainer中集装箱=新CompositionContainer中(aggregateCatalog);
container.ComposeParts(pluginDefinitions);
//存储插件定义
PluginDefinitions = pluginDefinitions;
}
公共静态牛逼GetPlugin< T>(字符串pluginName,串pluginGroupName)其中T:类
{
//如何实现这一特定的T型可能是一个扩展PluginDefinition类的任何类型的插件...
的//...provided呢?
返回NULL;
}
}
重复的出口背后的原因是,你是从的 ExportAttribute 。这意味着,当你装饰与 PluginAttribute
A类成员,你不需要添加 ExportAttribute
。 MEF将寻找分配给 ExportAttribute
属性,它会找到一个在你的 PluginAttribute
。
有关其它问题的插件类型,MEF允许对同一类型的多个出口。你可以有型IPlugin的一个出口,另一个更专业化就像你在你的代码做的:
[导出(typeof运算(IPlugin ))//< ----如果该行被注释掉那么只有一个项目是进口的(为什么)
[PluginAttribute(typeof运算(StrategyPlugin_Test1),StrategyPlugin,Plugin1)]
公共类StrategyPlugin_Test1:IPlugin
然后对每个导出不同类型的进口。你可以有一个的IEnumerable< IPlugin方式>
进口,然后在另一个属性 StrategyPlugin_Test1
导入
(1) Using the code below I get exactly 2 items in my containers of one and the same exported plugin and I wonder why:
(2) Additional question which I really cannot implement: How can I extend the framework to handle different plugin types (such as having several imports of different types, or one import that stores all plugins in a dynamic IEnumerable or so). I want to provide in my static wrapper class one generic method that returns the discovered plugin as a function of type and matching meta data.
The exported plugin (which resides in a separate dll and whose location is pointed to when the DirectoryCatalog
is built.
[Export(typeof(IPlugin))] //<---- If this line is commented out then only one item is imported (why?)
[PluginAttribute(typeof(StrategyPlugin_Test1), "StrategyPlugin", "Plugin1")]
public class StrategyPlugin_Test1 : IPlugin
{
public void DoSomething()
{
Console.WriteLine("I do something");
}
}
The following code defines the strongly typed meta data and imports as well as a static class that performs the MEF functions and is supposed to hold the discovered plugins:
[MetadataAttribute]
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class PluginAttribute : ExportAttribute
{
public Type PluginType { get; set; }
public string PluginGroupName { get; set; }
public string PluginName { get; set; }
public PluginAttribute(Type pluginType, string pluginGroupName, string pluginName) : base(typeof(IPlugin))
{
PluginType = pluginType;
PluginGroupName = pluginGroupName;
PluginName = pluginName;
}
}
public interface IPluginAttribute
{
Type PluginType { get; }
string PluginGroupName { get; }
string PluginName { get; }
}
public interface IPlugin
{
void DoSomething();
}
public class PluginDefinition
{
[ImportMany(typeof(IPlugin))]
public IEnumerable<Lazy<IPlugin, IPluginAttribute>> Plugins { get; set; }
public PluginDefinition()
{
}
}
Here the static class that wraps some of the core MEF stuff:
public static class PluginManager
{
private static PluginDefinition PluginDefinitions { get; set; }
static PluginManager()
{}
public static void Configure(PluginDefinition pluginDefinitions, IEnumerable<string> pluginDirectories)
{
AggregateCatalog aggregateCatalog = new AggregateCatalog(new DirectoryCatalog(pluginDirectories.FirstOrDefault()));
CompositionContainer container = new CompositionContainer(aggregateCatalog);
container.ComposeParts(pluginDefinitions);
//store plugin definition
PluginDefinitions = pluginDefinitions;
}
public static T GetPlugin<T>(string pluginName, string pluginGroupName) where T : class
{
//how to implement this given type of T could be any of the plugin types ...
//...provided for in an extended PluginDefinition class?
return null;
}
}
The reason behind the duplicate exports is the fact that you are deriving your custom export metadata attribute from ExportAttribute. This means that when you decorate a class member with PluginAttribute
, you do not need to add the ExportAttribute
. MEF will look for attributes assignable to ExportAttribute
and it will find one in your PluginAttribute
.
For the other question regarding plug-in types, MEF allows for multiple exports on the same type. You can have one export of type IPlugin and another more specialized like you were doing in your code:
[Export(typeof(IPlugin))] //<---- If this line is commented out then only one item is imported (why?)
[PluginAttribute(typeof(StrategyPlugin_Test1), "StrategyPlugin", "Plugin1")]
public class StrategyPlugin_Test1 : IPlugin
And then have different imports for each exported type. You can have an IEnumerable<IPlugin>
import and then on another property a StrategyPlugin_Test1
import.
这篇关于MEF,为什么同一个出口插件创建的相同的重复?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!