WPFプロジェクトに使用するロギングヘルパーを作成しました。これは、多くの異なるコンポーネントを含む大規模なプロジェクトです。これは、MVVMの操作方法を学ぶ前のことでしたので、これがパターンを壊す場合は失礼します。このシステムは、さまざまなタスクを処理するために新しいコンポーネントで継続的に拡張されています。コンポーネントは、特定のタスクを処理するスタンドアロンユニットと考えることができ、メインコンポーネントがそれらすべてのマスターになります。このロギングにより、エラーが発生したコンポーネントに関係なく、エラーをログに記録することができました。それはやり過ぎかもしれませんが、私たちにとっては非常にうまくいきました。
同じ原則を使用して、すべてのシステム全体のイベント(ユーザーアクション、データ変更など)をログに記録しています
App.xaml.csで、未処理のエラーをすべてキャッチします。これはロギングの最後の手段であることに注意してください。例外が発生すると予想される場合は常にtrycatchを使用します(たとえば、db接続)。
public partial class App : Application
{
void Application_DispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
{
ErrorEvent errorEvent = new ErrorEvent();
errorEvent.LogErrorEvent(e.Exception);
e.Handled = true;
}
}
ErrorEventは、イベントルーティングを使用してエラーをログに記録するユーティリティdll内のクラスです。重大度に応じて、さまざまな種類のエラーが発生します。これらのエラーはすべてデータベースに記録され、データベース接続を認識する唯一のコンポーネントはメインコンポーネントです。これが、ルーティングイベントを使用して例外をメインコンポーネントに送信してログに記録する理由です。ErrorEventHelperが入力され、メインコンポーネントにルーティングされます。try catchsを使用している状況では、EventHelperを作成し、LogErrorEventメソッドを使用してログに記録するために渡します。ShowMessageプロパティは、ユーザーに例外を通知するか、ログに記録するだけにするかを決定するために使用されます。
public class ErrorEvent : UserControl
{
public delegate void ErrorEventEventHandler(object sender, RoutedCustomEventArgs e);
public static readonly RoutedEvent EventOccuredEvent = EventManager.RegisterRoutedEvent(
"EventOccured", RoutingStrategy.Bubble, typeof(ErrorEventEventHandler), typeof(ErrorEvent));
// Provide CLR accessors for the event
public event RoutedEventHandler EventOccured
{
add { AddHandler(EventOccuredEvent, value); }
remove { RemoveHandler(EventOccuredEvent, value); }
}
public void LogErrorEvent(ErrorEventHelper occuredEventDetails)
{
RoutedEventArgs newEventArgs = new RoutedCustomEventArgs(ErrorEvent.EventOccuredEvent, occuredEventDetails);
RaiseEvent(newEventArgs);
}
public void LogErrorEvent(Exception exception)
{
ErrorEventHelper occuredEventDetails = new ErrorEventHelper();
occuredEventDetails.ErrorType = ErrorEventHelper.EventTypes.Critical;
occuredEventDetails.ErrorValue = exception.Message;
occuredEventDetails.ErrorStack = exception.StackTrace;
occuredEventDetails.ShowMessage = true;
RoutedEventArgs newEventArgs = new RoutedCustomEventArgs(ErrorEvent.EventOccuredEvent, occuredEventDetails);
RaiseEvent(newEventArgs);
if (exception.InnerException != null)
{
LogErrorEvent(exception.InnerException);
}
}
public class RoutedCustomEventArgs : RoutedEventArgs
{
public ErrorEventHelper OccuredEventDetails { get; private set; }
public RoutedCustomEventArgs(RoutedEvent routedEvent, ErrorEventHelper occuredEventDetails)
: base(routedEvent)
{
this.OccuredEventDetails = occuredEventDetails;
}
}
}
public class ErrorEventHelper
{
public string ErrorValue { get; set; }
private EventTypes _ErrorType = EventTypes.Critical;
public EventTypes ErrorType
{
get
{
return _ErrorType;
}
set
{
_ErrorType = value;
}
}
public string ErrorStack { get; set; }
public bool ShowMessage { get; set; }
public enum EventTypes
{
Critical,
Warning,
Information
}
public void SendMessage()
{
ErrorEvent newEvent = new ErrorEvent();
newEvent.LogErrorEvent(this);
}
}
メインウィンドウで、イベントハンドラーを登録します。
EventManager.RegisterClassHandler(typeof(ErrorEvent),
ErrorEvent.EventOccuredEvent, new ErrorEvent.ErrorEventEventHandler(LogOccuredErrors));
そして最後にそれを処理します:
private void LogOccuredErrors(object sender, ErrorEvent.RoutedCustomEventArgs e)
{
ErrorEventHelper eventHelper = e.OccuredEventDetails;
//Call Database Helper to log to database or output to file and email
StringBuilder builder = new StringBuilder();
builder.AppendLine(eventHelper.ErrorType);
builder.AppendLine(eventHelper.ErrorValue);
builder.AppendLine(eventHelper.ErrorStack);
if (eventHelper.ShowMessage)
{
MessageBox.Show(eventHelper.ErrorValue);
}
//Create your log file and email it
File.WriteAllText(@"C:\log.txt", ControllerBuilder.ToString())
//email here
}