1

まず、これまで Unity を使用したことがありませんでした... Unity インターセプトを使用して、プロジェクトに Tracing / Logging を導入したいと考えています。
プロジェクトはかなり大きい (~30000 ファイル)。目標は、外部サービスを呼び出すたびにパフォーマンス/実行期間をトレースすることです。残念ながら、他のライブラリは使用できません。
この概念がどのように機能するかを理解するために、MSDN で見つけた小さなプログラムを作成しました。ただし、ログ属性を使用した傍受はまだ発生しません。いくつかの構成または/および初期化が欠落していると確信しています。助けていただければ幸いです。

ここに私のメインプログラムがあります:

namespace calc
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                var t = new calc.Calculator.Calculator().Sub(5, 8);
            }
            catch (Exception ex)
            {
                System.Console.WriteLine(ex.Message);
            }
        }
     }
}

ここに電卓クラスがあります:

namespace calc.Calculator
{
    public interface ICalculator
    {
        Int32 Sum(Int32 x, Int32 y);        
        Int32 Sub(Int32 x, Int32 y);
    }

    public class Calculator : ICalculator
    {        
        public Int32 Sum(Int32 x, Int32 y)
        {
            return x + y;
        }

        [NonNegativeCallHandler] // Intercept this method and run tracing on it
        public Int32 Sub(Int32 x, Int32 y)
        {
            return x - y;
        }
    }
}

ここに私の CallHandler があります:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Practices.Unity.InterceptionExtension;

namespace calc.Tracing
{
    public class NonNegativeCallHandler : ICallHandler
    {
        public IMethodReturn Invoke(IMethodInvocation input,
                                GetNextHandlerDelegate getNext)
        {
            // Perform the operation
            var methodReturn = getNext().Invoke(input, getNext);

            // Method failed, go ahead
            if (methodReturn.Exception != null)
                return methodReturn;

            // If the result is negative, then throw an exception
            var result = (Int32)methodReturn.ReturnValue;

            if (result < 0)
            {
                var exception = new ArgumentException("...");
                var response = input.CreateExceptionMethodReturn(exception);

                // Return exception instead of original return value
                return response;
            }

            return methodReturn;
        }

        public int Order { get; set; }
    }
}

そして最後に

*ここに私の属性定義があります:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Practices.Unity.InterceptionExtension;
using Microsoft.Practices.Unity;

namespace calc.Tracing
{
     public class NonNegativeCallHandlerAttribute : HandlerAttribute
     {
         public override ICallHandler CreateHandler(IUnityContainer container)
         {
             return new NonNegativeCallHandler();
         }
     }
}

このコードが機能するためには、他に何を追加する必要があり、どこに (構成ファイルまたは内部コンストラクターなど) 追加する必要がありますか。

4

2 に答える 2

0

あなたのコードは、 Dino Esposito によるこの記事に由来するように見えます。構成に関するセクションを見逃したようです (Fluent コードの使用または構成によるポリシーの追加の段落)。


アップデート

MSDN のこのページはご覧になりましたか?

于 2012-04-23T06:44:28.950 に答える
0

解決策の1つを見つけました...プログラムクラスを変更してコンテナを登録しました..そして、追加の構成はまったく必要ないようです。変更されたプログラムは次のとおりです。

namespace calc
{
class Program
{
    static void Main(string[] args)
    {
        ICalculator iCal;
        try
        {

            iCal = ConfigurePolicyInjectionWithUnity();

            var t = iCal.Sub(8, 5);
        }
        catch (Exception ex)
        {
            System.Console.WriteLine(ex.Message);
        }
    }

    static ICalculator ConfigurePolicyInjectionWithUnity()
    {
        IUnityContainer container = new UnityContainer();

        container.AddNewExtension<Interception>();
        container.RegisterType<ICalculator, 
                           calc.Calculator.Calculator>().Configure<Interception>()
            .SetInterceptorFor<ICalculator>(new InterfaceInterceptor());

            // resolve
            return container.Resolve<ICalculator>(); ;
        }
    }
}

さて、ここで質問です...私が約20種類の電卓を持っているとしましょう。各クラスには、トレースするメソッドが約3〜4つあります。これらのメソッドにはそれぞれ固有の署名があります。したがって、3 ~ 4 メソッド x 20 クラス = トレースする一意のシグネチャを持つ ~80 メソッド。私がリードしているのは、これらすべてのメソッドを記述する単一のインターフェースを持つことができないということです...上記のソリューションから、少なくとも私の場合、インターセプターを実装するにはクラスごとにインターフェースが必要なようです。ロギングを行うためだけに 20 ~ 30 の新しいインターフェイスを導入するのは、あまり洗練されていないように見えます。この場合、傍受を使用することと、ロギングを行うヘルパー クラスを使用することの間に違いはありません。私は正しいですか?

インターフェイスを定義せずに傍受を使用できる他の方法はありますか? 必要なのは、メソッドの実行開始時刻と実行完了時刻をログに記録できることだけです。

ヘルプやアイデアをいただければ幸いです。

于 2012-04-26T04:13:18.973 に答える