新しいのDLLがディレクトリで見つかった場合DirectoryCatalogの更新を()を呼び出すと、ChangeRejectedExceptionがスローされます
-
16-09-2019 - |
質問
私は MEF を使って実験し、いくつかの指定されたインタフェースを実装する「プラグイン」を呼び出すためのテストプログラムを作成しています、次のこれます:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ProbeContract
{
public interface IProbe
{
int DoProbe(string what);
List<string> GetCapabilities();
}
}
私は1つが、追加のDLLを置くているdiretoryから任意の見つかった場合は、独自のアセンブリから「プラグイン」とし、ロードするサンプルのコンソールプログラムを作成しました。プログラムは、プラグインディレクトリが空であるかどうかOK作品(のみ「ネイティブ」のプラグインが呼び出される)か、で起動する互換性のDLLを持っています。新しいDLLは、ループ反復の間に追加された場合でも...、DirectoryCatalogのリフレッシュ()メソッドは以下のようなものを説明するChangeRejectedExceptionを、スロー:
構図は変わりません。ザ・ 変更が理由で拒否されました 次のエラー(S):組成物 単一組成のエラーを生成しました。 根本的な原因を以下に示します。 CompositionException.Errorsを確認 より詳細のプロパティ 情報ます。
1)の輸出の変化によって防止 非recomposableインポート 「MEFTest.Program.ProberSet (ContractName = "ProbeContract.IProbe")」 一部の 'MEFTest.Program' ます。
プログラムは以下の通りです、私が追加しようとDLLのコードで従ってください。私が間違って何をしているのですか?
using System;
using System.IO;
using System.Reflection;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ProbeContract;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
namespace MEFTest
{
class Program
{
[ImportMany]
IEnumerable<IProbe> ProberSet { get; set; }
CompositionContainer exportContainer;
DirectoryCatalog pluginCatalog;
AggregateCatalog catalog;
private void Run()
{
catalog = new AggregateCatalog();
catalog.Catalogs.Add(new AssemblyCatalog(Assembly.GetExecutingAssembly()));
string myExecName = Assembly.GetExecutingAssembly().Location;
string myPath = Path.GetDirectoryName(myExecName);
pluginCatalog = new DirectoryCatalog(myPath + "/Plugins");
catalog.Catalogs.Add(pluginCatalog);
exportContainer = new CompositionContainer(catalog);
CompositionBatch compBatch = new CompositionBatch();
compBatch.AddPart(this);
compBatch.AddPart(catalog);
exportContainer.Compose(compBatch);
for (; ; )
{
Console.Write("Press any key to run all probes: ");
Console.ReadKey(true);
Console.WriteLine();
pluginCatalog.Refresh();
foreach (var Prober in ProberSet)
{
Prober.DoProbe("gizmo");
}
}
}
static void Main(string[] args)
{
Program p = new Program();
p.Run();
}
}
}
プラグイン。他の2つのプラグインが類似している、それらはメインプログラムと同じアセンブリ内に存在する唯一の違い
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel.Composition;
using ProbeContract;
namespace OtherProbes
{
[Export(typeof(IProbe))]
public class SpankyNewProber : IProbe
{
public int DoProbe(string what)
{
Console.WriteLine("I'm Spanky and New and I'm probing [{0}]", what);
return 0;
}
public List<string> GetCapabilities()
{
List<string> retVal = new List<string>();
retVal.Add("spanky");
retVal.Add("new");
return retVal;
}
}
}
解決
私はあなたが拒否の例外を見ているので、あなたがMEFプレビュー6を使用していると仮定しています。あなたのProberSetがrecomposableされていないので、あなたが拒否さの変化を見ている理由があります。あなたのProberSetのインポートを変更してみます:
[ImportMany(AllowRecomposition=true)]
IEnumerable<IProbe> ProberSet { get; set; }
そうすることで、このインポートは、すでに構成された後にカタログ/コンテナに導入される新しいIProbeの輸出が可能になります。
ここでの考え方は、あなたが安定な組成物を得れば、私たちは潜在的にその構図を不安定化し、あなたのケースであなたはそれがintially設定した後に非recomposable IProbeのセットは非常に新しいIProbe年代を追加するオブジェクトたい述べた可能性のある変更を拒否することを希望その要件に違反します。