3

MEF (具体的にはMEF 2 Preview 5 )を使用するアプリケーションに取り組んでおり、汎用インターフェイスに基づいてインポートしようとすると問題が発生しました。

私はインターフェースを持っています:

public interface IMessageHandler<in T>
{
    void HandleMessage(T message);
}

ここで、T は処理するメッセージのタイプです。以下を使用して、これらのものをカタログにインポートしていRegistrationBuilderます。

RegistrationBuilder context = new RegistrationBuilder();

context.ForTypesDerivedFrom(typeof(IMessageHandler<>))
    .Export(builder => builder.AsContractType(typeof(IMessageHandler<>)));

[ImportMany]次に、これらのリストをにインポートするために使用している消費クラスでIEnumerable<Lazy>>:

[ImportMany(typeof(IMessageHandler<>))]
IEnumerable<Lazy<IMessageHandler<object>, HandledMessageTypeAttribute>> _messageHandlers;

さて、ここに最初の問題があります。この時点で、型をジェネリック インターフェイスに割り当てる必要があります。実装には、消費したい関連メタデータがあるため、使用Lazy<T, TMetadata>しています( )。IMessageHandler<T>HandledMessageTypeAttribute

コレクション内の任意の要素にアクセスしよIEnumerable<Lazy<>>うとすると、次の例外が発生します。

Cannot cast the underlying exported value of type 
'MessageHandlerImplementation (ContractName="IMessageHandler(System.Object)")' 
to type 'IMessageHandler`1[System.Object]'.

例外が発生する理由を(大まかに)理解していますが、問題は、それを回避する方法がわからないことです。だから、基本的に私がやりたいことは次のとおりです。

  1. インターフェイスを実装するクラスがたくさんありIMessageHandler<T>ます。
  2. MEF を使用して実行時にそれらを検出します。
  3. それらをコレクションにインポートして、それらが持つメタデータを使用できるようにします。
  4. それらをインスタンス化できるようにします。

IMessageHandler単純に非ジェネリックにしてIMessageHandler.HandleMessage()型のパラメーターを受け入れることができることは理解していますobjectが、もう少しエレガントなソリューションを探していました

任意のポインタまたはガイダンスをいただければ幸いです。

4

1 に答える 1

3

非汎用インターフェースを使用せずに達成しようとしていることを行うためのより良い方法はありません。問題の根本は、インターフェイスの定義です。

public interface IMessageHandler<in T>

Aこれは、との2 つのクラスがある場合B、 がBから派生するA場合、これが許可されることを意味します。

IMessageHandler<B> handler = new AHandler();

しかし、これはそうではありません:

IMessageHandler<A> handler = new BHandler();

基本的に後者を実行しようとしています。これが例外をスローする原因です。あなたがやりたいことは、型を指定してハンドラーを取得できるようにすることだと思います。その場合は、おそらく非ジェネリック インターフェイスを使用し、メッセージ タイプをエクスポート メタデータで使用できるようにする必要があります。次に、次のようなものがあります。

public IMessageHandler GetHandler<T>()
{
    Type handlerType = typeof(T);
    return _messageHandlers.FirstOrDefault(x => x.Metadata.MessageType == handlerType);
}

この質問も関連性があると思うかもしれません。お役に立てれば。

于 2012-06-21T20:45:20.277 に答える