4

Ninject 3.0 を注入したサービス クラスがあります。プロキシがインターフェイス プロキシではなくクラス プロキシになるように設定しました。このサービスには 2 つのメソッドがあります。最初のメソッドは広範な結果を返し、2 つ目のメソッドは最初のメソッドを呼び出してフィルタリングします。最初のメソッドの結果をキャッシュするインターセプターを追加しました。

サービスの外部から最初のメソッドを呼び出すと、傍受は正常に機能します。

問題は、インターセプターが 2 番目のメソッドを呼び出すときに、プロキシ経由ではなくサービス自体を介して呼び出すため、サービスからの最初のメソッドへの呼び出しがインターセプトされず、キャッシュされないことです。

どうすればこれを機能させることができますか?

更新: サンプル コードを追加

これは私の頭の上にあるので、何かがコンパイルされていないように見える場合は申し訳ありません

これはサービスクラスのサンプルです

public class Service : IService
{

    [CacheMethodOutput]
    public virtual object[] GetObjects(int x)
    {
        ...
    }

    public virtual object GetObject(int x, int y)
    {
        return GetObjects(x).SingleOrDefault(o => o.y == y);
    }
}

CacheMethodOutputAttribute は単純な属性クラスです

バインディングの例を次に示します (これは、インターフェイス プロキシの代わりにクラス プロキシを使用することを確認する方法ですが、実際にはインターフェイスによって注入された参照を残します)。

// Binds by type instead of proxy to create a class proxy
Bind<Service>().ToSelf().InSingletonScope().Intercept().With<CacheAttributeInterceptor>()
Bind<IService>().ToMethod<Service>(r => r.Kernel.Get<Service>());

そのため、IService が挿入されている任意のクラスから GetObjects を呼び出すと、インターセプターがトリガーされますが、Service 自体の GetObject メソッドからはトリガーされません。

CacheAttributeInterceptor は次のようになります (ただし、実装の詳細は関係ありません)。

public class CacheAttributeInterceptor : SimpleInterceptor
{
    public ICacheManager CacheManager {get;set;}

    public override void BeforeInvoke(IInvocation invocation)
    {
        if (Attributes.GetCustomAttribute(invocation.Request.Method, typeof(CacheMethodOutputAttribute) != null)
        {
            string key = GenerateKey(invocation.Request.Method.Name, invocation.Request.Method.Arguments);

            object returnValue;
            if (!CacheManager.TryGet(key, out returnValue))
            {
                 invocation.Proceed();
                 returnValue = invocation.ReturnValue;
                 CacheManager.Add(key, returnValue);
            }
            else
                invocation.ReturnValue = returnValue;

        }
        else
            base.BeforeInvoke(invocation);
    }
}
4

1 に答える 1

-1

問題の解決策/詳細を見つけました。

GetObject メソッドの仮想モディファイアを削除すると、インターセプトされなくなり、GetObjects が呼び出されると、インサーセプターがトリガーされます。

これらすべてのことから、両方のメソッドをインターセプトしたい場合は、可能であればインターセプターを深く機能させる必要があると考えるようになりました。

于 2012-11-16T19:06:37.413 に答える