2

一部の「リスクの高い」データ操作をログに記録する必要があります。この場合、「高リスク」操作は、ERPシステムへの書き込みとして定義されます。これらのイベントをSQLServerデータベースに記録していることがあります。

擬似コード:

Public Class MyCompany.DAL.ERP {
  Public void WriteToERP(string msg) {
    // ... do the write
    MyCompany.Logging.Write("Wrote msg: " + msg);
  }
}

Public Class MyCompany.Logging {
  Public void Write(string msg) {
    MyCompany.DAL.ExecuteSQL("Insert INTO EventLog VALUES " + msg);
  }
}

この密結合を排除するためのベストプラクティスは何ですか?

4

7 に答える 7

3

うーん、IMHOロギングはインフラストラクチャの問題です。DALで使用できますが、ロガーはDALを使用しないでください。

ロガーがDALに依存していることを削除すると、他のプロジェクトでもロガーを使用できるようになります。

于 2009-01-20T19:19:09.187 に答える
1

カスタムTraceListener(System.Diagnostics)を作成して、会社のSQLServerデータベースに挿入できます。次に、アプリケーションのコードへのログインにTrace / TraceSource(System.Diagnostics)を使用します。その後、標準の.NET構成を使用して、設計時にカスタムTraceListenerを使用できます。そうすれば、イベントロギングを変更する必要がある場合は、TraceListenerを変更するだけで済みます。さらに、TraceListenerを他のアプリケーションで再利用できます。

エンタープライズライブラリのロギングアプリケーションブロックや他の多くのサードパーティのロギングソリューションを使用することもできます。

于 2009-01-20T19:20:33.520 に答える
0

実際、リスクの高いデータとは、それがデータであると想定されていることを知るための批判的/重要な意味であり、データベース(ある種のメタデータ)にログを保持する必要がある場合、ソリューションは他の人が提案したものとは完全に異なります。

私が説明した状況は、データベーストランザクションの結果には、いつでもログデータとデータベース内のデータ自体の両方が含まれている必要があることを意味します。一方を他方から独立して行うべきではありません。

結果として、この種の「ロギング」は単一のデータベーストランザクションの一部として実行する必要があり、DALは、両方のアイテムが同じトランザクションに同時に正しく挿入されることを確認する必要があります。

そうしないと、次の副作用が発生する可能性があります。

  • データまたはログの1つだけをデータベースに挿入します。
  • データまたはログの一方のみがデータベースに挿入されているということは、特定の状況では、両方が常に存在している必要があるという事実に依存しているシステムがランダムに失敗する可能性があることを意味します。
于 2009-01-20T20:46:31.223 に答える
0

循環依存DAL->Logger->DALを回避するために、「simpleDAL」と「loggingDAL」の2つのDALレイヤーを用意することをお勧めします。

「シンプルなDAL」は単なるDALではありません。「ロギングDAL」は「単純なDAL」に基づいています。単純なDALを使用してDBを操作し、また単純なDALを使用してデータをログに記録します。だからあなたは持っています:

[アプリケーションロジック]-uses->[logging DAL] --uses-> [simple DAL] --uses-> DB

ログに記録する必要のないものをDBに実行したい場合(「低リスク」操作;-))、「単純なDAL」を直接使用して、ログに記録するDALをバイパスできます。

于 2009-01-24T02:32:43.410 に答える
0

おそらく、ロギングコンポーネントを別のアセンブリに移動し(これはC#コードであると想定しています)、Logging.Write()を呼び出す前に呼び出し元が登録できるイベントを発生させることができます。Logging.Write()が戻ったら、イベントから登録を解除します。イベントハンドラーでは、MyCompany.DAL.ExecuteSQL( "Insert INTO EventLog VALUES" + msg)呼び出しを実行できます。

于 2009-01-20T19:18:27.237 に答える
0

私は以前、この状況を 2 つの方法で切り離しました: ステータス変更とログ イベントです。

最初の方法は、次のような IHaveStatus インターフェイスを作成することです。

/// <summary>
/// Interface for objects that have a status message 
/// that describes their current state.
/// </summary>
public interface IHaveStatus
{
    /// <summary>
    /// Occurs when the <seealso cref="Status"/> property has changed.
    /// </summary>
    event EventHandler<StatusChangedEventArgs> StatusChanged;
    /// <summary>
    /// The current status of the object.  When this changes, 
    /// <seealso cref="StatusChanged"/> fires.
    /// </summary>
    string Status { get; }
}

オブジェクトが処理を行うとき、Status プロパティを設定します。設定時に StatusChanged イベントを発生させるようにプロパティ セッターを構成できます。オブジェクトを使用する人は誰でも、ステータス変更イベントをリッスンし、発生したすべてをログに記録できます。

これの別のバージョンは、ログ イベントをオブジェクトに追加することです。

public event EventHandler<LogEventArgs> Log;

プリンシパルはほとんど同じですが、オブジェクトだけがステータス駆動型ログよりもおしゃべりが少なくなります (特に何かをログに記録したい場合にのみイベントを発生させます)。

これらのイベントを適切なログ (できれば DI を使用して設定) に接続するのは、DAL の外部の呼び出し元の責任であるという考えです。DAL は、これらのイベントを誰が、または何が消費しているのかを認識しないため、これらの懸念がうまく分離されます。

于 2009-01-20T19:24:38.580 に答える
0

回答に共通するのは、オブザーバー パターンのようなものを実装するという提案のようです。

(より良い要約文があれば教えてください。それに応じて更新します。)

于 2009-01-20T19:32:31.560 に答える