3

MEF を使用していくつかのプラグインをロードする WPF アプリでアセンブリのインポートの問題をデバッグしようとしており、この特定の例外を解決するためのアイデアを探しています。

制約に一致する複数のエクスポートが見つかりました:
ContractName MarkPad.Contracts.ISpellingService
RequiredTypeIdentity MarkPad.Contracts.ISpellingService

関心のあるプラグインを autofac 登録の一部として直接参照するアセンブリは 1 つだけです (最後のコード スニペット)。

[ImportingConstructor]
public SpellCheckPlugin(
    IPluginSettingsProvider settingsProvider,
    ISpellingService spellingService,
    ISpellCheckProviderFactory spellCheckProviderFactory)

の実装は 1 つだけです。ISpellingService

[Export(typeof(ISpellingService))]
public class SpellingService : ISpellingService

これは github のオープン ソースCode52 プロジェクトです。

プラグインのインポートは次のとおりです。

[ImportMany]
IEnumerable<IPlugin> plugins;

私がこれまでに試したこと:

  1. これこのブログ投稿は使用について言及しています[ImportMany(AllowRecomposition = true)]が、それも役に立たないようです。
  2. 私が見つけた他の議論では、「ローカルのコピー」をfalseに設定することが言及されていますが、実際には登録コードで使用されているため、出力フォルダーに収まらないため、オプションではありません。

何か案は?

プラグインを参照する登録コード

builder.RegisterType<SpellingService>().As<ISpellingService>()
    .SingleInstance()
    .OnActivating(args =>
{
    var settingsService = args.Context.Resolve<ISettingsProvider>();
    var settings = settingsService.GetSettings<SpellCheckPlugin.SpellCheckPluginSettings>();
    args.Instance.SetLanguage(settings.Language);
})
4

1 に答える 1

3

解決

この問題は、現在のアセンブリ viaが に提供されているGetExecutingAssemblyのカタログ エントリの 1 つとして PluginManager() で使用されていたバグでした。AggregateCatalogCompositionContainer

var catalog = new AggregateCatalog();

// This was causing the composition to detect additional imports
catalog.Catalogs.Add(new AssemblyCatalog(Assembly.GetExecutingAssembly()));

このバグは、サービス/プラグインを独自のアセンブリに抽出したことから発生しました。これらのアセンブリは、もともとコア MarkPad アセンブリの一部でした。

クレジットは@shiftkeyとこのパッチに送られます。

追加の改善

このパッチの一部として、この回答をサポートするのに役立つかもしれないいくつかの追加のクリーンアップがありました。

SpellCheckPlugin はインターフェースを取っていたので、エクスポートは具象型ではなくインターフェース自体に単純に移動されました。

[ImportingConstructor]
public SpellCheckPlugin(
    IPluginSettingsProvider settingsProvider,
    ISpellingService spellingService,
    ISpellCheckProviderFactory spellCheckProviderFactory)

代わりにインターフェイスにエクスポートを追加する

[InheritedExport]
public interface ISpellCheckProviderFactory

// and

[InheritedExport]
public interface ISpellingService  

コンクリート エクスポートの削除

[Export(typeof(ISpellingService))]
public class SpellingService : ISpellingService

// and

[Export(typeof(ISpellCheckProviderFactory))]
public class SpellCheckProviderFactory : ISpellCheckProviderFactory
于 2012-07-16T13:05:25.613 に答える