0

私たちのチームは、WCF サービスの例外処理とログ記録の実装を自動化するライブラリを作成しました。このライブラリを使用すると、開発者はカスタム属性でサービスを装飾し、いくつかの単純な構成ファイル エントリをセットアップするだけで、一般的な例外処理とログ メカニズムを利用できます。

ライブラリの使用方法の例を次に示します。

[ErrorHandlingBehavior (LogWriterOption.EmailLogWriter, LogWriterOption.SQLLogWriter)]
public class SampleService : ISampleService
{
    public string GetData(int value)
    {
        throw new DivideByZeroException();
        //return string.Format("You entered: {0}", value);
    }
}

ErrorHandlingBehavior クラスは、パラメーターで LogWriterOption 列挙型を取得する Logger オブジェクトを使用して、どこにログを記録するかを決定します。

私たちの最初の意図は、開発者が独自のロギング メカニズムを指定して ErrorHandlingBehavior に提供できるようにすることでした。これにより、Logger クラスに対するソリューションの依存関係を取り除くことができます (代わりに、ILogger を実装する任意のクラスを取り込みます)。ただし、以下の方法で属性を指定するとエラーが発生します。

 [ErrorHandlingBehavior (new Logger (new HashSet<LogWriterOptions> 

                             {LogWriterOption.EmailLogWriter, LogWriterOption.SQLLogWriter}))]

属性を指定するときに何もインスタンス化できないように思われるため、ユーザーに独自のロギング メカニズムを指定させることができなくなりました。

誰かがこれを回避する方法を知っていますか? 依存関係を配線する代わりに、ILogger を実装するクラスのインスタンスを属性に与えるにはどうすればよいでしょうか?

4

2 に答える 2

1

また、ロギングの例外処理動作についてもいくつか書きました。このような状況で、私はいつも自分自身に尋ねました:

log4netは何をしますか?

LogWriterOptions は、log4net アペンダーに変換されているようです。アペンダーは、環境によって要件が変わるため、一般に xml 構成を使用して行うのが最適です。(これは、WCF クライアント バインディングをコードに含めないことと同等のログ記録です。) つまり、ローカルで開発する場合は、電子メールを送信せず、ローカル テキスト ファイルに出力するだけです。QA で実行する場合: DB に出力しますが、テスターでメールを送信しないでください。意図的に何かを壊します。本番環境: まったく別のことを行います。Log4net アペンダーは、これらすべてのタイプのコンパイル後の変更 (およびそれ以上) をサポートします。

質問に戻る:

  • あなたのアプローチでは、ErrorHandlingBehavior に動作名を「StandardLogging」のような文字列として渡します。これにより、構成可能な動作が検索され、EmailLogWriter と SQLLogWritter が使用されます。
  • ロギング フレームワークで一般的な別の方法は、ロギングされるクラスの型を渡すことです。そのタイプが明示的に構成されていない場合、デフォルトのアペンダーが取得されます。

この構成アプローチには、次の追加の利点があることに注意してください。

  1. アプリケーション全体のログ出力オプションを一元化します。標準を変更しても、多くのクラス ファイルを更新する必要はありません。
  2. さまざまなコードが使用しているログ ライター オプションを標準化します。コード レビュー ミーティングでは、「標準のログ出力を使用していますか?」と尋ねるだけです。小切手。

「シンプルに保つ」というコメントに応じて更新します。

シンプルに保つことが目標である場合は、動作のコンストラクターに何も渡さないでください。代わりに、すべての log4net 構成情報を独自の log4net.config ファイルに入れ、それをソース管理の共通ログ ライブラリの一部として保存します。その後、新しいプロジェクト (またはジュニア開発者) を追加する必要があります。

<configuration>
     <log4net configSource="log4net.config" />
</configuration> 

app.config に。このアプローチの利点は、ビルド プロセスの一部として、さまざまな環境への展開用にさまざまな log4net.config ファイルを定義したことです。

于 2013-02-19T23:54:22.497 に答える
0

factory パターンを使用できます。ILoggerインスタンスを提供するために使用される型を開発者に指定してもらいます。

[ErrorHandlingBehavior(LoggerFactoryType = "FooBar.MyLoggerFactory")]

このタイプは、あなたのインターフェースを実装できます:

public interface ILoggerFactory
{
    ILogger GetLogger();
}

次に、カスタム属性内で、最初にメソッドを使用してファクトリ タイプを取得し、それがインターフェイスをType.GetType実装しているかどうかを確認し、メソッドを使用してファクトリをインスタンス化し、最後にそのインスタンスでメソッドを呼び出すことができます。ILoggerFactoryActivator.CreateInstanceGetLogger

于 2013-02-19T07:34:36.150 に答える