.NET Framework ベースのアプリケーションのコレクションを .NET Core に移植しようとしています。このプロセスの一環として、MEF1 の使用から MEF2 の使用に切り替える必要があります。私は MEF2 に関連する問題に頭を悩ませていましたが (この投稿は非常に役に立ちました)、最近、問題の 1 つの背後にある理由に出くわしました。
特に、カスタムExportAttribute
を使用してメタデータをエクスポートする多くのクラスがあり、それらすべてを別のクラスにインポートして、このメタデータに基づいてフィルタリングしたいと考えています。これは MEF1 ではすべて正常に機能していましたが、MEF2 では「xのエクスポート メタデータが見つからず、デフォルト値が指定されていません」などの問題に遭遇しました。
より具体的には、エクスポートしたクラスに次のように注釈を付けます。
[Export(typeof(IClientRequestProcessor<RelaySystemModel>))]
[TargetDevice("<<Foo>>")]
internal class RelaySystemClientRequestProcessor : IClientRequestProcessor<RelaySystemModel>
{
}
次に、他の場所で、次のようにインポートしようとします。
[ImportMany]
public IEnumerable<ExportFactory<IClientRequestProcessor<RelaySystemModel>, DeviceSpecific>> RelayRequestProcessors { private get; set; }
そして、インポートが完了したら、メタデータでフィルター処理を試みます。
private static IEnumerable<ExportFactory<T, DeviceSpecific>> FilterForFoo<T>(IEnumerable<ExportFactory<T, DeviceSpecific>> items)
{
return from it in items where it.Metadata.DeviceId == "<<Foo>>" select it;
}
は次TargetDeviceAttribute
のように定義されます。
[MetadataAttribute, AttributeUsage(AttributeTargets.Class)]
public class TargetDeviceAttribute : ExportAttribute, IDeviceSpecific
{
public TargetDeviceAttribute(string deviceId)
{
this.DeviceId = deviceId;
}
public string DeviceId { get; private set; }
}
何が起こっているかというと、パーツ が 2つのエクスポートRelaySystemClientRequestProcessor
に対応していることがわかりました。ただし、「DeviceId」メタデータは後者にのみ関連付けられており、前者には関連付けられていないため、役に立ちません。IClientRequestProcessor<RelaySystemModel>
RelaySystemClientRequestProcessor
完全にテストしていませんが、これを解決できると思われる方法がいくつかあります。
ExportMetadata("DeviceId", "<<foo>>")
エクスポートされたすべてのパーツに属性を適用します。TargetDeviceAttribute
コンストラクターを使用するように変更しますpublic TargetDeviceAttribute(string deviceId, Type exportType) : base(exportType)
。
私はこれらの解決策に賛成ではありません。前者はメタデータ キーを変更したい場合に問題があり、どちらもすべてのパーツをエクスポートする方法を変更する必要があります。
私が疑問に思っているのは、MEF2 が MEF1 のようにメタデータをエクスポートする方法を提供するかどうかです: カスタム メタデータ属性を作成し、そのメタデータをパーツに関連付けられたすべてのエクスポートに適用します。これは可能ですか?