12

ロギングを追加して、メソッドの開始と終了が、何らかの形でトレース目的でパラメータとともに自動的に記録されるようにする方法はありますか? どうすればいいですか?

Log4Net を使用しています。

4

7 に答える 7

8

この種のことを実現する最善の方法は、インターセプトを使用することです。これを行うにはいくつかの方法がありますが、いずれもやや侵襲的である傾向があります。1 つは、すべてのオブジェクトを ContextBoundObject から派生させることです。 この種のアプローチを使用する例を次に示します。もう 1 つのアプローチは、既存の AOP ライブラリの 1 つを使用してこれを実現することです。Castle Projectの DynamicProxy のようなものが、これらの多くの中核を成しています。ここにいくつかのリンクがあります: Spring.Net PostSharp Cecil

おそらく他にもいくつかありますが、私はCastle WindsorNinjectの両方が IoC 機能に加えて AOP 機能を提供していることを知っています。

AOP が整ったら、log4net へのメソッド呼び出しに関する情報を書き込むインターセプター クラスを作成するだけです。

AOP フレームワークの 1 つがそのような機能をすぐに提供できるとしても、私は実際には驚かないでしょう。

于 2008-10-05T01:17:28.827 に答える
5

あなたの実際のニーズが何であるかはわかりませんが、ここに低家賃のオプションがあります. 正確には「自動」ではありませんが、StackTrace を使用して、引数を渡す必要のない方法で探している情報を剥がすことができます-インターセプトに関する ckramer の提案と同様:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Diagnostics;

namespace TracingSample
{
    class Program
    {
        static void Main(string[] args)
        {
            DoSomething();
        }

        static void DoSomething()
        {
            LogEnter();

            Console.WriteLine("Executing DoSomething");

            LogExit();
        }

        static void LogEnter()
        {
            StackTrace trace = new StackTrace();
            if (trace.FrameCount > 1)
            {
                string ns = trace.GetFrame(1).GetMethod().DeclaringType.Namespace;
                string typeName = trace.GetFrame(1).GetMethod().DeclaringType.Name;
                Console.WriteLine("Entering {0}.{1}.{2}", ns, typeName, trace.GetFrame(1).GetMethod().Name);
            }
        }

        static void LogExit()
        {
            StackTrace trace = new StackTrace();
            if (trace.FrameCount > 1)
            {
                string ns = trace.GetFrame(1).GetMethod().DeclaringType.Namespace;
                string typeName = trace.GetFrame(1).GetMethod().DeclaringType.Name;
                Console.WriteLine("Exiting {0}.{1}.{2}", ns, typeName, trace.GetFrame(1).GetMethod().Name);
            }
        }
    }
}

上記の例のようなものを継承と組み合わせて、基本型で非仮想パブリック メンバーを使用してアクション メソッドを示し、仮想メンバーを呼び出して実際に作業を行うことができます。

public abstract class BaseType
{
    public void SomeFunction()
    {

        LogEnter();
        DoSomeFunction();
        LogExit();
    }

    public abstract void DoSomeFunction();
}

public class SubType : BaseType
{
    public override void DoSomeFunction()
    {
        // Implementation of SomeFunction logic here...
    }
}

繰り返しますが、これについてはあまり「自動」ではありませんが、すべてのメソッド呼び出しでインストルメンテーションを必要としない場合は、限定的に機能します。

お役に立てれば。

于 2008-10-05T01:45:24.200 に答える
4

見て:

C# でメソッド呼び出しをインターセプトするにはどうすればよいですか? PostSharp - 織る - 思考

また、SO で「AOP」または「Aspect Oriented Programming」と PostSharp を検索すると、興味深い結果が得られます。

于 2008-10-05T01:40:51.493 に答える
3

Postsharpのようなポストコンパイラを使用できます。ウェブサイトのサンプルでは、​​メソッドに出入りするためのトレーサーの設定について説明しています。これは、必要なものと非常によく似ています。

于 2008-10-05T01:18:02.507 に答える
0

メソッド呼び出しの開始と終了をマークする LogInjector を持つ CodePlex でオープン ソース フレームワークCInjectを使用できます。

または、 IL を使用したメソッド呼び出しのインターセプトに関するこの記事に記載されている手順に従い、C# で Reflection.Emit クラスを使用して独自のインターセプターを作成することもできます。

于 2012-12-11T02:28:24.047 に答える