4

構造マップを使用して属性ベースのインターセプトを実行しようとしていますが、最後のルーズエンドを拘束するのに苦労しています。

アセンブリをスキャンするカスタムレジストリがあり、このレジストリで次のITypeInterceptorを定義しました。その目的は、指定された属性で装飾されたタイプを照合し、照合された場合はインターセプターを適用することです。クラスは次のように定義されます。

public class AttributeMatchTypeInterceptor<TAttribute, TInterceptor> 
   : TypeInterceptor 
   where TAttribute : Attribute 
   where TInterceptor : IInterceptor
{
    private readonly ProxyGenerator m_proxyGeneration = new ProxyGenerator();

    public object Process(object target, IContext context)
    {
        return m_proxyGeneration.CreateInterfaceProxyWithTarget(target, ObjectFactory.GetInstance<TInterceptor>());
    }

    public bool MatchesType(Type type)
    {
        return type.GetCustomAttributes(typeof (TAttribute), true).Length > 0;
    }
}

//Usage
[Transactional]
public class OrderProcessor : IOrderProcessor{
}
...   
public class MyRegistry : Registry{
    public MyRegistry()
    {
         RegisterInterceptor(
             new AttributeMatchTypeInterceptor<TransactionalAttribute, TransactionInterceptor>());
         ...
    }
}

Castle.CoreのDynamicProxyを使用してインターセプターを作成していますが、問題は、CreateInterfaceProxyWithTarget(...)呼び出しから返されたオブジェクトが、構造マップでターゲットインスタンスの作成をトリガーしたインターフェイス(つまり、IOrderProcessor)を実装していないことです。上記の例では)。IContextパラメーターがこのインターフェースを明らかにすることを期待していましたが、具体的なタイプ(つまり、上記の例ではOrderProcessor)を把握することしかできないようです。

ProxyGeneratorを呼び出して、すべてのインターフェイスをターゲットインスタンスとして実装するインスタンスを返すか、構造マップから要求されたインターフェイスを取得するか、その他のメカニズムを使用して、このシナリオを機能させる方法についてのガイダンスを探しています。

4

1 に答える 1

2

私は実際に少し注意して何かが機能しているので、これを答えとして投稿します。秘訣は、インターフェースを取得し、それをCreateInterfaceProxyWithTargetに渡すことでした。私の唯一の問題は、現在解決しているインターフェイスについてIContextにクエリを実行する方法が見つからなかったため、ターゲットで最初のインターフェイスを検索するだけでした。以下のコードを参照してください

public class AttributeMatchTypeInterceptor<TAttribute, TInterceptor> : 
    TypeInterceptor
    where TAttribute : Attribute 
    where TInterceptor : IInterceptor
{
    private readonly ProxyGenerator m_proxyGeneration = new ProxyGenerator();

    public object Process(object target, IContext context)
    {
        //NOTE: can't query IContext for actual interface
        Type interfaceType = target.GetType().GetInterfaces().First(); 
        return m_proxyGeneration.CreateInterfaceProxyWithTarget(
            interfaceType, 
            target, 
            ObjectFactory.GetInstance<TInterceptor>());
    }

    public bool MatchesType(Type type)
    {
        return type.GetCustomAttributes(typeof (TAttribute), true).Length > 0;
    }
}

これが誰かに役立つことを願っています

于 2011-08-09T06:50:28.007 に答える