1

我正在为我的插件系统使用MEF (C# 4.0)。有时需要获取所有插件的派生类型列表(主要用于 XML 反序列化)。这可以在不实例化插件的情况下完成吗?

这有效,但需要实例化:

var cat = new DirectoryCatalog(path, "*.dll");
var container = new CompositionContainer(cat);
container.ComposeParts(this);
foreach (var plugin in Plugins)
{
    // Would be better if this could be done via Metadata!
    DoStuff(plugin.Value.GetType());
}
// ...
[ImportMany]
public Lazy<PluginBase, IPluginMetadata>[] Plugins
{
    get;
    private set;
}

问:是否有可能通过一些ExportAttribute或其他技术来实现这一点?

谢谢。

4

2 回答 2

2

MEF 无法自行提供此信息。要了解原因,请考虑通过属性进行以下导出:

[Export(typeof(PluginBase))]
public PluginBase MyPlugin
{
    get
    {
        if (someCondition)
        {
           return new FooPlugin();
        }
        else
        {
           return new BarPlugin();
        }
    }
}

但是,您仍然可以在导出的元数据中包含类型(如下所示或通过包含元数据的自定义导出属性):

[Export(typeof(PluginBase))]
[ExportMetadata("Type", typeof(Foo))]
public class Foo : PluginBase
{
}

并添加IPluginMetadata.Type成员。

于 2012-04-19T10:27:16.607 回答
1

您还可以对 ComposableParts 进行一些迭代,假设您有一个包含目录的静态 MEFHelper 类,您可以编写此代码

public static IEnumerable<Type> GetExportedTypes<T>()
{
    return catalog.Parts
        .Select(part => ComposablePartExportType<T>(part))
        .Where(t => t != null);
}

private static Type ComposablePartExportType<T>(ComposablePartDefinition part)
{

    if (part.ExportDefinitions.Any(
        def => def.Metadata.ContainsKey("ExportTypeIdentity") &&
            def.Metadata["ExportTypeIdentity"].Equals(typeof(T).FullName)))
    {
        return ReflectionModelServices.GetPartType(part).Value;
    }
    return null;
}

我在这篇博文中解释了这一点(您可以下载一个工作示例)

于 2012-05-08T17:41:00.313 回答