2013-04-22 5 views
10

MEF Runtime Plugin更新の問題

Issue

MEFコードは、実行時にDirectoryCatalogに関連付けられたフォルダからアセンブリを適切に更新していません。プラグインは実行時に十分に読み込まれますが、dllを更新してDirectoryCatalogでRefreshを呼び出すと、アセンブリが更新されません。

背景

私はMEFコンテナを持つdllを構築しており、ローカルのプラグインフォルダを見つけるためにDirectoryCatalogを使用しています。私はこのDLLを現在シンプルなWinFormから呼び出しています。これは、ShadowCopyを使用するための別個のプロジェクトをセットアップしているので、プラグインフォルダ内のDLLを上書きすることができます。 FileWatcherを使用してこのフォルダを更新する代わりに、DirectoryCatalogの更新を呼び出すパブリックメソッドを公開しています。したがって、自動的にではなくアセンブリを更新できます。

コード

基底クラスは、MEFカタログやコンテナをインスタンス化し、参照のアクセスのためのクラス変数として保存し、後で

public class FieldProcessor 
{ 
    private CompositionContainer _container; 
    private DirectoryCatalog dirCatalog; 

    public FieldProcessor() 
    { 
     var catalog = new AggregateCatalog(); 
     //Adds all the parts found in the same assembly as the TestPlugin class 
     catalog.Catalogs.Add(new AssemblyCatalog(typeof(TestPlugin).Assembly)); 
     dirCatalog = new DirectoryCatalog(AppDomain.CurrentDomain.BaseDirectory + "Plugin\\"); 
     catalog.Catalogs.Add(dirCatalog); 

     //Create the CompositionContainer with the parts in the catalog 
     _container = new CompositionContainer(catalog); 
    } 

    public void refreshCatalog() 
    { 
     dirCatalog.Refresh(); 
    } 

} ... 

ここで私が上書きしようとしているプラ​​グインです。私の更新のテストは、返された刺し傷がテキストボックスに出力され、プラグインが戻ってきた文字列を変更して再構築し、それをプラグインフォルダにコピーします。しかし、それは私がアプリケーションを閉じて再起動するまで、実行中のアプリケーションのために更新されません。

[Export(typeof(IPlugin))] 
[ExportMetadata("PluginName", "TestPlugin2")] 
public class TestPlugin2 : IPlugin 
{ 
    public IEnumerable<IField> GetFields(ContextObject contextObject, params string[] parameters) 
    { 
     List<IField> retList = new List<IField>(); 
     //Do Work Return Wrok Results 
     retList.Add(new Field("plugin.TestPlugin2", "TestPluginReturnValue2")); 
     return retList; 
    } 
} 

編集

import文

[ImportMany(AllowRecomposition=true)] 
    IEnumerable<Lazy<IPlugin, IPluginData>> plugins; 

研究

私はかなり大規模な研究を行っているし、どこでも記事やコードサンプルでは答えは、であることをコンテナにDirectoryCatalogを追加して保存表示されます新しいプラグインが追加された後、そのカタログの参照を呼び出し、その参照でRefreshを呼び出すと、アセンブリは更新されますが、新しいプラグインのDLLから更新された出力は表示されません。

リクエスト

誰でもこの問題を見たことがありますか、または実行時にアセンブリに問題が発生している可能性がありますか?追加情報や洞察力があれば感謝します。

解像度

私の解決に私の問題をもたらしたリンクのためのパノスとスタンプのおかげで。将来のナレッジシーカーにとって、私の主な問題は、新しいアセンブリが上書きされたdllとまったく同じアセンブリ名を持つ場合、Refreshメソッドはアセンブリを更新しないということでした。私のPOCのために、私はちょうどアセンブリ名とそれ以外のすべてに加えられた日付との再構築をテストし、それは魅力のように働いた。以下のコメントのリンクは非常に便利で、同じ問題がある場合はお勧めします。

+1

DirectoryCatalog.Refreshます更新されたassebmliesを検出しません。新規または削除されたもののみ。回避策と提案のためのこの答えを見てください:http://stackoverflow.com/a/14842417/850119 –

+0

私のdllはロードされるとロックされますので、新しいdllでそれらを無効にできません。この問題はありませんでしたか?あなたはそれらを更新可能にした何かをしましたか? –

+0

ええ、私はこの問題を抱えていました。私が渡した段階の1つは、「シャドウコピー」を有効にすることでした。シャドウコピーを使用すると、プログラムはDLLをロックする代わりに、ローカルアセンブリのローカルコピーを作成してローカルキャッシュに追加することができます。これは、実行時にdllを "ホットスワップ"できるようにするために有効にする必要があります。そうしないと、プログラムを停止し、dllを変更して再起動する必要があります。私はこれが私が見ている例だと思うが、それはあなたのGoogle MEFとシャドーコピーのために動作しない場合、http://stackoverflow.com/questions/12593308/mef-and-shadowcopying-dlls-so-that-i -can-overwrite-them-at-runtime – Madullah

答えて

3

インポート属性にAllowRecompositionパラメータを設定しましたか?周りの仕事のため http://msdn.microsoft.com/en-us/library/system.componentmodel.composition.hosting.directorycatalog.refresh.aspx

AllowRecomposition 
Gets or sets a value that indicates whether the property or field will be recomposed when exports with a matching contract have changed in the container. 

http://msdn.microsoft.com/en-us/library/system.componentmodel.composition.importattribute(v=vs.95).aspx

編集:

DirectoryCatalogは、アセンブリを更新しない、唯一の追加または削除 https://stackoverflow.com/a/14842417/2215320

+0

私は、インポート・ステートメント・コードを最初に投稿しなかったことを申し訳ありません。インポート・ステートメントを反映するように質問を更新しました。 – Madullah

+0

とリフレッシュコード?私は問題が内部だと思う。あなたはFileSystemWatcherを使用していないと言っていますが、あなたのアセンブリをどのように検出してリロードしますか? – Niels

+0

私は上記のRefreshCatalogメソッドを通して公開しています。私はwinFormのボタンクリックイベントからそのメソッドを呼び出しています。 – Madullah