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;
}

Q: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 に答える