4

だから、私はこの問題を抱えており、誰も助けることができないようです。だから、バッシングを続けるのではなく、この特定の猫の皮を剥ぐ別の方法のためにそこに捨てるつもりです.

私は現在、次のものを持っています:

public interface ICustomerService
{
    Customer GetCustomer(int id);
}

public class CustomerService : ICustomerService
{
    public Customer GetCustomer(int id)
    {
        ...
    }
}

...そしてUnityを使用すると、IOCがセットアップされ、同時に次のような傍受が構成されます。

IUnityContainer ioc = new UnityContainer();
ioc.RegisterType<ICustomerService, CustomerService>()
    .Configure<Interception>()
    .SetInterceptorFor<ICustomerService>(new InterfaceInterceptor());

私が達成したいのは、次のようにインターフェイスに属性を配置できるようにすることです。

public interface ICustomerService
{
    [Log]
    Customer GetCustomer(int id);
}

... のように定義:

public class LogAttribute: HandlerAttribute
{
    public override ICallHandler CreateHandler(IUnityContainer container)
    {
        return new LogHandler();
    }
}  

...そして、LogHandlerクラスで、必要なすべてのログを次のように行います:

public class LogHandler : ICallHandler
{
    public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
    {
        ... log stuff
    }
}

私が達成したいのは、ハンドラーが呼び出されている名前空間.クラス.メソッド名と、それを呼び出した親名前空間.クラス.メソッド名をログに記録するトレース/ログシステムです。「入力」IMethodInvocation パラメータを使用して必要な情報を取得しようとしましたが、成功しませんでした。問題は、入力が「ICustomerService」インターフェイスを返し、親のスタックフレームをチェックすると、親の実装されたクラスが返されることです (例: . CustomerService) エンティティ ID として namespace.class.methodname を使用してツリー構造を作成しようとすると、ID と親 ID が一致しないことを意味します。

[Log] 属性にパラメーターをドロップしても、実際には機能しません。そこに何を入れることができるのでしょうか? インターフェース名を入力しても、1つのIDがインターフェースであり、親が実装クラスである上記と同じ問題がまだあります。そして、実装クラス名をインターフェイスの属性に入れることはできません。これは、そもそもインターフェイスを持つという目的を無効にするためです!

それがジレンマです。誰か新鮮なアイデアを思いつきましたか?

4

2 に答える 2

1

UnityとInterceptionを使用してロギングを機能させています。構成のセットアップスキルがひどく不足していたため、プログラムで行う必要がありました。少なくとも1つのインターセプターと、1つ以上のポリシーオブジェクトを設定する必要があります。そうそう、それUnityContainer.Configure<Interception>は重要です。

このようなもの:

// I'm using the TransparentProxyInterceptor because I want to trace EVERYTHING...
var intp = myUnityContainer.Configure<Interception>().
    SetInterceptorFor(typeof(MyTypeToLog), new TransparentProxyInterceptor());

var policy = intp.AddPolicy("somePolicyName");

policy.AddMatchingRule<TypeMatchingRule>(
    new InjectionConstructor(
        new InjectionParameter(typeof(MyTypeToLog)))
          .AddCallHandler(typeof(MyCallHandler), 
               new ContainerControlledLifetimeManager());

もちろん、インターセプト呼び出しハンドラーも定義する必要があります。

public class MyCallHandler : ICallHandler, IDisposable
{
    public IMethodReturn Invoke(IMethodInvocation input, 
        GetNextHandlerDelegate getNext)
    {
        var methodReturn = getNext().Invoke(input, getNext);

        // log everything...
        LogMethodCall(input, methodReturn);

        // log exception if there is one...
        if (methodReturn.Exception != null)
        {
            LogException(methodReturn);
        }

        return methodReturn;
    }
}
于 2010-10-08T18:10:13.660 に答える
1

PostSharp を使用して、このようにロギングを実装することになりました。http://www.postsharp.org

于 2009-12-01T15:04:50.943 に答える