4

(1) 以下のコードを使用すると、エクスポートされた 1 つの同じプラグインのコンテナにちょうど 2 つのアイテムが表示されます。

(2) 私が本当に実装できない追加の質問: フレームワークを拡張して、さまざまな種類のプラグインを処理するにはどうすればよいですか (たとえば、さまざまな種類のインポートを複数持つ、またはすべてのプラグインを動的な IEnumerable に格納する 1 つのインポートなど)。静的ラッパー クラスに、検出されたプラグインを型と一致するメタ データの関数として返す 1 つのジェネリック メソッドを提供したいと考えています。

エクスポートされたプラグイン (別の dll に存在し、DirectoryCatalogビルド時にその場所が指定されます。

[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");
    }
}

次のコードは、厳密に型指定されたメタ データとインポート、および MEF 機能を実行し、検出されたプラグインを保持する静的クラスを定義します。

[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()
    {

    }
}

MEF コアの一部をラップする静的クラスを次に示します。

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

}
4

1 に答える 1