1

アプリケーションを拡張するための単純なプラグインシステムにMEF(モノラルで構築されたバージョン)を使用しようとしています。私は、WindowsでMicrosoft .NET Frameworkを使用して正常に実行されているさまざまなチュートリアルに従いましたが、mono-2.10.9を使用するLinux(kernel 3.7.3 --gentoo)では(同じコード)失敗しました。

すべてのエクスポート(私の拡張機能)が外部アセンブリで参照する必要があるインターフェイスを作成しました。

namespace PlugInInterface {

    [InheritedExport]
    public interface IPlugIn {

        void Execute(); 

    }

}

次に、PluginInterfaceも参照するHostapplication(ConsoleApplication)を作成しました。

namespace Host {

    class MainClass {

        private static PluginHost plugins;

        public static void Main(string[] args) {
            plugins = new PluginHost();
            foreach(IPlugIn plugin in plugins.plugins) {
                plugin.Execute();
            }
        }
    }


    class PluginHost{

        [ImportMany(typeof(IPlugIn))]
        public List<IPlugIn> plugins = new List<IPlugIn>();

        public PluginHost() {
            var catalog = new DirectoryCatalog("PlugIns");
            var container = new CompositionContainer(catalog);
            container.ComposeParts(this);   
        }   
    }
}

そして、ホストアプリケーションが配置されているDebugディレクトリの「PlugIns」サブフォルダにコンパイルされる1つの拡張機能:

namespace TestPlugin1 {
    [Export(typeof(IPlugIn))]
    public class TestPlugin1 : IPlugIn {
        public void Execute() {
            Console.WriteLine("Hello, my Name is TestPlugin_Implementation1");
        }
    }
}

DirectoryCatalogは、プラグインのファイル( "./PlugIns/TestPlugin1.dll")をロードしますが、それをエクスポート( "パーツ")として認識しないため、pluginsリストは空のままです。PluginFileをアプリケーションの作業ディレクトリに置き、DirectoryListを次のように変更すると機能します。 var catalog = new DirectoryCatalog("");

.NETコンパイラからモノラルでコンパイルされたコンパイル済みバージョンを実行すると、プラグインが2回ロードされます。

PlugIn-filesをでロードし、次にAssemblyCatalogsを使用して見つかったすべてのアセンブリをロードすることにより、 DirectoryCatalogを手動で置き換えようとしました。System.Reflection.Assembly.LoadFile(...);

class PluginHost{

    [ImportMany(typeof(IPlugIn))]
    public List<IPlugIn> plugins = new List<IPlugIn>();

    public PluginHost() {
        List<AssemblyCatalog> catalogs = new List<AssemblyCatalog>();
        foreach(string plfile in Directory.GetFiles("PlugIns", "*.dll", SearchOption.AllDirectories)) {
            catalogs.Add(new AssemblyCatalog(System.Reflection.Assembly.LoadFile(plfile)));
        }           
        var container = new CompositionContainer(new AggregateCatalog(catalogs));
        container.ComposeParts(this);   
    }   
}

これは機能しますが、コンパイルされた.NET実行可能ファイルと同じです。プラグインは2回ロードされます。

これはモノラルのバグであり、MEFの実装ですか、それとも私は何か間違ったことをしていますか?

4

1 に答える 1

1

.NETコンパイラからモノラルでコンパイルされたコンパイル済みバージョンを実行すると、プラグインが2回ロードされます。

これは、あなたがあなたと一緒にIPlugIn装飾したにもかかわらずInheritedExportAttribute、プラグインも。で装飾するために起こりますExportAttribute。カタログはこれらの両方に一致するため、2回エクスポートされます。2つのアプローチのうちの1つだけが必要です。を保持し、InheritedExportAttribute実装をで装飾しないか、ExportAttributeすべての実装をで装飾してインターフェイスからExportAttribute削除しInheritedExportAttributeます。

DirectoryCatalogプラグインアセンブリをMonoにロードできない理由がわかりません。あなたが述べたように、CLRでは正しく動作します。

于 2013-02-12T00:06:44.160 に答える