0

私が必要としているのは、2人の親を持つクラスContextBoundObjectともう1つのクラスです。
理由ContextBoundOject:メソッド呼び出しをログに記録するには、にアクセスする必要があります。
作曲はうまくいきますか?現在のところ、ありません(特にタイプは認識されません)。
これを行う他の方法はありますか?はい。ただし、それほど自動化できず、サードパーティのコンポーネントがありません(T4でも可能かもしれませんが、私は専門家ではありません)。

より詳細な説明。

フレームワークの内部動作にアクセスするために、システムクラス(たとえば、およびの親用にすでに(の親である)を持っているものと、持っていないものがあります)を拡張して、メソッド呼び出しをログに記録できるようにする必要がありますMarshalByRefObject(今のところ、将来は変更される可能性があります)。ContextBoundObjectServiceBaseFileSystemWatcherExceptionTimer

この方法を使用する場合、すべてのメソッドにログ呼び出しを追加するのではなく、ログに記録するオブジェクトにクラス名を追加するだけで済みますが、明らかにこれを行うことはできません。

public class MyService:ServiceBase,ContextBoundObject,IDisposable{
    public MyService(){}
    public Dispose(){}
}

したがって、通常のソリューションであるインターフェイスを試すことができますが、Runを次のように呼び出すと次のようになります。

ServiceBase.Run(new MyService());

架空のインターフェイスIServiceBaseを使用すると、タイプServiceBaseがIServiceBaseにキャストできないため、機能しません。これは、どのインターフェイスからも継承されません。例外を除いて、問題はさらに悪化します。throwから派生した型のみを受け入れますException
逆に、IContextBoundObjectインターフェイスを生成することも機能しないようです。ロギングメカニズムはメソッドによって機能しないため、属性といくつかの小さな内部クラスだけを実装する必要はありません(そして、から継承しますContextBoundObject。からでもMarshalByRefObject、メタデータは実質的に同じものとして表示されます)。

私が見たところ、fromContextBoundObjectを拡張すると、拡張クラスがProxy(おそらく、この方法でメソッド呼び出しがSyncProcessMessage(IMessage)を使用するため、インターセプトしてログに記録できるため)、継承なしでそれを行う方法があるか、または可能性がありますロギング呼び出し(T4テキストテンプレートなど)を使用してメソッドを囲むために利用できるコンパイル前またはコンパイル後の手法であるかどうかはわかりません。

誰かがこれを見てみたい場合は、プログラムでカスタマイズされたバージョンのMSTestExtentionsを使用して、(メソッド呼び出しの)ロギングを実行しました。どんなアイデアでも大歓迎です。さらに説明が必要な場合がありますので、お尋ねください。

4

2 に答える 2

0

プロキシを試してみると、明示的な呼び出しをログに記録する方法を見つけました。
基本的にRealProxy、msdnで例のようなものを作成し、それを取得しTransparentProxyて通常のオブジェクトとして使用します。
ロギングは、カスタマイズされたクラスInvokeでオーバーライドされたメソッドで実行されます。RealProxy

static void Main(){
...
    var ServiceClassProxy=new ServiceRealProxy(typeof(AServiceBaseClass),new object[]{/*args*/});
    aServiceInstance=(AServiceBaseClass)ServiceClassProxy.GetTransparentProxy();
    ServiceBase.Run(aServiceInstance);
...
}

プロキシクラスでは、次のInvokeように実行されます。

class ServiceRealProxy:RealProxy{
...
    [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.Infrastructure)]
    public override IMessage Invoke(IMessage myIMessage){
        // remember to set the "__Uri" property you get in the constructor
    ...
        /* logging before */
        myReturnMessage = ChannelServices.SyncDispatchMessage(myIMessage);
        /* logging after */
    ...
        return myReturnMessage;

        // it could be useful making a switch for all the derived types from IMessage; I see 18 of them, from
        // System.Runtime.Remoting.Messaging.ConstructionCall
        // ... to
        // System.Runtime.Remoting.Messaging.TransitionCall
    }
...
}

私はまだ広範囲に調査する必要がありますが、ロギングが発生しました。から継承しないクラスでこれをテストする必要があるため、これは私の元の問題に対する答えではありませんMarshalByRefObject

于 2013-02-21T08:45:52.433 に答える
0

メソッド呼び出しのロギングは通常、属性を使用して、ロギングを有効にしたいクラスまたはメソッドに注釈を付けて行われます。これは、アスペクト指向プログラミングと呼ばれます。

これが機能するには、これらの属性を理解し、アノテーションが付けられたメソッド/クラスに必要なコードを追加してアセンブリを後処理するソフトウェアが必要です。

C# にはPostSharpが存在します。紹介はこちらをご覧ください。

于 2013-02-20T11:49:11.357 に答える