MEF Contrib Provider モデルがパーツをインポートしない
質問
MEF Contrib からの MEF インポートとエクスポートを処理するために構成可能なプロバイダー モデルを使用しようとしています (リンク)。Codeplex のドキュメントと Code Junkie のブログ投稿 (リンク);ただし、パーツを作成するためのコンテナを取得できないようです。私のどこが間違っているのでしょうか?
プログラム.cs
namespace MEFTest
{
class Program
{
static void Main(string[] args)
{
Program p = new Program();
p.Run();
}
// [ImportMany("command", typeof(IHelp))]
public IEnumerable<IHelp> Commands { get; set; }
void Run()
{
Compose();
foreach(IHelp cmd in Commands)
{
Console.WriteLine(cmd.HelpText);
}
Console.ReadKey();
}
void Compose()
{
var provider = new ConfigurableDefinitionProvider("mef.configuration");
var catalog = new DefinitionProviderPartCatalog<ConfigurableDefinitionProvider>(provider);
var container = new CompositionContainer(catalog);
container.ComposeParts(this);
}
}
}
テストコマンド.cs
namespace MEFTest
{
//[Export("command", typeof(IHelp))]
public class TestCommand : IHelp
{
private string _helpText = "This is a test.";
public string CommandName
{
get { return "Test"; }
}
public string HelpText
{
get { return _helpText; }
}
}
}
App.Config セクション:
<mef.configuration>
<parts>
<part type="MEFTest.TestCommand, MEFTest">
<exports>
<export contract="IHelp" />
</exports>
</part>
<part type="MEFTest.Program, MEFTest">
<imports>
<import member="Commands" contract="IHelp" />
</imports>
</part>
</parts>
</mef.configuration>
MEF コアの一部である典型的な属性ベースのシステム (適切なカタログも使用) に切り替えると、ビルド エラーは発生せず、正常に実行されます。上記の例では、Program.Commands は常に NULL です。コレクションの代わりに単一のプロパティを使用して、同じ結果を得ようとしました。
デバッグ時に Provider.Parts コレクションを取得できるので、構成情報に正しくアクセスしていることがわかります。ただし、デバッグして、catalog.Parts にドリルダウンしようとするたびに、InvalidOperationException が発生します。
ここで私がどこで間違っているのかについて経験のある人はいますか?
解決
文書化されているとおり ここ, 、設定ファイルにもこれが必要です。
<configSections>
<section
name="mef.configuration"
type="MefContrib.Models.Provider.Definitions.Configurable.PartCatalogConfigurationSection, MefContrib.Models.Provider" />
</configSections>
すでにそれを持っている場合は、そのスタック トレースを見せてみるのも面白いかもしれません。 InvalidOperationException
アクセスしたときに得られるもの provider.Parts
.
他のヒント
私も同じ問題があり、動作させることができませんでしたが、詳細は次のとおりです。ComposeParts() は (少なくとも私が使用したバージョンでは) 期待どおりに動作しないようです。これは、Reflection に基づいて、必要なすべてのインポートを検索する静的メソッドを使用しているためです (したがって、この部分は MEF の外部から変更できないようです)。残念ながら、MEF 属性ではなく XML 設定を使用したいと考えています。
ComposeParts() で使用するクラスのメンバーに [Import] 属性を追加すると機能します。あなたの場合、これは「プログラム」になります。この場合、構成ファイルで定義されているすべてのエクスポートが検索されます。
MEF Contrib ページには、その問題に関するドキュメントや例が見つかりませんでした。また、ComposeParts() を使用する MEF contrib プロジェクトにはunittest はありません。回避策は、container.GetExportedValues() を使用して値を取得することですが、この場合、クラスのメンバーを手動で設定する必要があります。
それが役立つことを願っています。