7

MEF を使用して、ユーザーが C# ライブラリを拡張できるようにしています。これまでのところうまく機能していますが、今まで見たことのない方法で使用しようとしています。

これまでに見た MEF の主な使用例は次のとおりです。

  • アプリケーションがプリミティブ インターフェイスを公開する ( IPerson)
  • 外部ライブラリは MEF とプリミティブ インターフェイスを使用して、メイン ライブラリの機能を拡張します (たとえばIPoliceman : IPerson、機能を追加します)。
  • 次に、アプリケーションは、何をしなければならないかに応じてImportMany正しいものを検索するために使用しますIPerson

しかし、次のようなものが必要です。たとえば、一連のパラメーターを取り、それらのパラメーターに応じて推定税額を返す税計算機があるとします。これらの計算方法を変更するプラグインを MEF でユーザーが作成できるようにしたいと考えています。一度にロードできるのは、これを行う 1 つのプラグインだけです。それ以外の場合、どの代替実装を使用するかをどのように決定すればよいですか?

基本的に、私の質問は次のようになります。通常、MEF では、クラスとメソッドの実装を追加できます。ユーザーが実装を置き換えられるようにするにはどうすればよいですか?

4

3 に答える 3

12

通常、アプリケーションに既に存在するエクスポートをオーバーライドしようとすると、[Import(typeof(IFoo)]MEF は正確に 1 つの一致するエクスポートが使用可能であると想定するため、カーディナリティ例外が発生します。

ただし、プラグインを別のエクスポート プロバイダーに配置して、優先順位を付けることができます。ここでは、アプリケーション フォルダー内の "plugins" サブフォルダーに対してこれを行います。

Assembly executingAssembly = Assembly.GetExecutingAssembly();
string exeLocation = Path.GetDirectoryName(executingAssembly.Location);
string pluginPath = Path.Combine(exeLocation, "plugins");

var pluginCatalog = new DirectoryCatalog(pluginPath);
var pluginExportProvider = new CatalogExportProvider(pluginCatalog);

var appCatalog = new DirectoryCatalog(exeLocation,"*");
var appExportProvider = new CatalogExportProvider(appCatalog);

var container = new CompositionContainer(
    pluginExportProvider, appExportProvider);

pluginExportProvider.SourceProvider = container;
appExportProvider.SourceProvider = container;

コンポジション コンテナーに渡されるエクスポート プロバイダーの順序によって優先度が決まります。エクスポートがプラグインとアプリケーション パーツの両方によって提供される場合、プラグインが優先されます。

于 2012-06-26T08:27:52.467 に答える
3

あなたが話していることは、実際には同じ問題を別の方法で見ているだけです。答えは思ったより簡単です。クライアントがオーバーライドできるようにしたい動作については、その動作をプラグインに入れるだけです。

アプリケーションの作成者だからといって、プラグインを作成できないということはありません。TaxCalculator クラスをプラグインに入れ、インターフェースを公開して、ユーザーが独自の税金計算機を作成できるようにします。実行時に複数のロードがある場合は、自分のものではないものを優先してください。すぐに使用できる税計算プラグインを使用するため、期待どおりに機能します。ユーザーが独自の税計算プラグインを作成して適切なディレクトリにドロップした場合、代わりにそれを使用して、元の機能を効果的に「上書き」できるようにします。

于 2012-06-25T20:10:36.053 に答える
1

どれだけ意味があるのか​​わかりませんが、やってみましょう。

私はTaxCalculatorManagerクラスを作ります。そのクラスはITaxCalculator、MEFからすべての実装をロードできます。そこからExport、実装のランク付けを可能にする何かを属性に含めることができます。次に、税金を計算する必要がある場合は、実装をTaxCalculatorManager.Calculateランク付けして勝者を呼び出すように呼び出します。ITaxCalculatorCalculate

ポイントを明確にする必要がある場合はお知らせください。

于 2012-06-25T20:18:06.687 に答える