連載
|
|
Page1
Page2
|
Exception Handling Application Blockが提供する機能
●例外情報の出力
Enterprise Library 1.0のリリース以前にも例外管理用のApplication BlockとしてException Management Application Block(以下EMAB)が存在していたのだが、EMABはイベント・ログへの例外情報の出力機能しか有していなかった。
このため、EMABは手軽に導入できる半面、実際の業務アプリケーションの開発で利用する際に、テキスト・ファイルへのログ出力などを行いたい場合は、パブリッシャ(例外情報の出力を管理するクラス)を独自に作成する必要があった。
しかしEHABでは、依存関係にあるLogging & Instrumentation Application Block(以下LoggingAB)の機能を使うことでイベント・ログやテキスト・ファイルへ例外情報を出力することができるようになっている。
以下は前回の「LoggingABを使用した場合のサンプル・プログラム」に実装されている例外処理(catchブロック内の処理)をEHABで置き換えたものである。
|
|
EHABを使用した場合のサンプル・プログラム(C#) | |
事前にConfigurationコンソールでPostHandlingActionプロパティに「NotifyRethrow」を設定しているので、HandleExceptionメソッドは常にtrueを返す。なおこのサンプル・プログラムを実行するには、以下のアセンブリを参照設定に追加する必要がある。 | |
・Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.dll | |
・Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Logging.dll |
前回のLoggingABを利用したサンプル・プログラムでは、以下のようにまずLogEntryをインスタンス化してから、捕捉した例外が保持している例外情報を設定し、それをLoggerクラスのWriteメソッドへパラメータとして渡す必要があった。
catch (SqlException ex)
{
LogEntry log = new LogEntry();
log.Message = ex.Message;
Logger.Write(log);
}
しかしEHABを使用した場合は、ExceptionPolicyクラスのHandleExceptionメソッドの第1パラメータに、捕捉した例外を渡すだけで、必要な例外情報を自動的に出力してくれるのである。
従来のEMABを使った例外情報のログ出力と比べると、EHABではコード記述量の減少、Configurationコンソールと依存関係にあるLoggingABを使ったプログラムレスな振る舞いの変更など、それなりに高機能になっている。しかしEnterprise Library対応として生まれ変わったEHABの真骨頂は、次に解説する例外ハンドラ機能にこそあるのである。
●例外ハンドラ機能
ではEHABが提供する例外ハンドラ機能とは何だろうか? その解説をする前に、先ほど例外を伝播させる場合のベスト・プラクティスで解説したことを思い出していただきたい。
EHABが提供する例外ハンドラ機能とは、捕捉した例外を伝播させるに当たってのさまざまな機能をカプセル化し、ソース・コードを変更することなく例外の伝播方法を変更することができる機能なのである。
以下がEHABで提供されている例外ハンドラの一覧である。
例外ハンドラ | 機能説明 |
Logging handler | 補足した例外が保持している例外情報を出力する例外ハンドラ |
Replace handler | 捕捉した例外を任意の例外に置換する例外ハンドラ |
Wrap handler | 捕捉した例外を任意の例外にラッピングする例外ハンドラ |
EHABで提供されている例外ハンドラの一覧 |
例外ハンドラ機能は、単体では使いどころが難しいかもしれないが、これは明確な例外ポリシーと組み合わせることで効果を発揮することになる。
例えばAAfN(Application Architecture for .NET)が推奨するレイヤ・アーキテクチャにおいて、ビジネス層をさらにアプリケーション・ロジック層とビジネス・ロジック層に分離した、論理4階層のASP.NET Webアプリケーションにおける例外ポリシーを以下のように定めたとする。
レイヤ名 | 例外ポリシー |
プレゼンテーション層 | ・ApplicationLayerException例外を捕捉した場合は、集約エラー・ハンドリング機能を使ってユーザーに通知する ・レイヤ内で発生した例外については、集約エラー・ハンドリング機能を使ってログ出力を行い、ユーザーに通知する |
アプリケーション・ロジック層 | ・下位のレイヤから伝播してきた例外のうち、BusinessLogicException例外またはDataLayerException例外を捕捉した場合はログ出力を行い、その後ApplicationLayerException例外に置換し、ユーザー通知用のメッセージを付加して上位レイヤへ伝播させる ・レイヤ内で発生した例外で復旧可能な場合は同レイヤ内でログ出力を行い、ApplicationLayerException例外に置換し、ユーザー通知用のメッセージを付加して上位レイヤへ伝播させる |
ビジネス・ロジック層 | ・レイヤ内で発生した例外で復旧可能な場合はBusinessLogicException例外にラッピングして追加情報を付加し上位レイヤへ伝播させる |
データ層 | ・レイヤ内で発生した例外で復旧可能な場合はDataLayerException例外にラッピングして追加情報を付加し上位レイヤへ伝播させる |
論理4階層ASP.NET Webアプリケーションにおける例外ポリシーの例 | |
表中のポリシーは本稿のために便宜上作成した例外ポリシーであり、必ずしもP&Pが示すベスト・プラクティスを踏襲していないことにご注意いただきたい。 |
この例外ポリシーを図にすると以下のようになる。
論理4階層ASP.NET Webアプリケーションの例外ポリシーの概念図 |
この例外ポリシーに従ってEHABを構成した場合の設定は以下の表のようになる。
ノード | プロパティ | 設定値 | ||
Exception Policy1 | Name | Exception Policy1 | ||
SqlException | PostHandlingAction | ThrowNewException | ||
Wrap handler | WrapExceptionTypeName | DataLayerException | ||
DataLayerException | PostHandlingAction | ThrowNewException | ||
Wrap handler | WrapExceptionTypeName | BusinessLayerException | ||
BusinessLayerException | PostHandlingAction | ThrowNewException | ||
Logging handler | LogCategory | True | ||
Replace handler | ReplaceExceptionTypeName | ApplicationLayerException | ||
ApplicationLayerException | Logging handler | LogCategory | True | |
Exception Policy2 | Name | Exception Policy2 | ||
DataLayerException | PostHandlingAction | ThrowNewException | ||
Logging handler | LogCategory | True | ||
Replace handler | ReplaceExceptionTypeName | ApplicationLayerException | ||
例外ポリシーに従ったEHABの構成 | ||||
・アプリケーション・ロジック層でDataLayerException例外を捕捉した場合は、HandleExceptionメソッドの第2パラメータにException Policy2を設定する。 | ||||
・1つの例外ノードに複数のhandlerを追加可能である。例えばBusinessLayerExceptionノードにLogging HandlerノードとReplace handlerノードが設定されているが、この場合には、まず例外情報のログ出力が実行されてから、ApplicationLayerException例外に置換されることになる。 |
ではここで、例外ポリシーが「データ層でSqlException例外が発生した場合はDataLayerException例外へラッピングするのではなくて置換する」に変更されたとしよう。
もしEHABを使用せずにある程度コードを書き進めてしまっていた場合は、恐らくデータ層に属するクラスの中で、例外処理を記述しているすべてのメソッドを修正することになってしまうだろう。この場合、1カ所でも修正をし損ねてしまったら例外ポリシーの一貫性を保てなくなってしまう。
しかしEHABであれば、例外処理の振る舞いは必ずしもソース・コードの中に記述する必要はない。Configurationコンソールを使ってSqlExceptionノードに対応する例外ハンドラをWrap HandlerからReplace Handlerに変更するだけで簡単に振る舞いを変更できてしまうのである。
このようにEHABを利用することでアプリケーションの開発における例外ポリシーに一貫性を持たせることが可能になる。しかし先にも述べたが、例外ポリシーそのものは業務要件に大きく影響してくるところであり、たとえEHABを利用したとしても根本のポリシーが誤っていては適切な運用を行うことは不可能である。そのことを踏まえて、まずは業務要件にあった適切な例外ポリシーの策定を行い、それからEHABの利用を検討することこそが本当の意味でのベスト・プラクティスということになるだろう。
■
以上、今回は例外管理におけるベスト・プラクティスを簡単に解説し、それからEHABの導入手順、例外情報の出力機能と例外ハンドラ機能について解説した。
次回は、Enterprise Libraryを構成するコアのApplication Blockから少し離れて、2005年3月にリリースされたUpdater Application Block 2.0を使ったモジュールの自動更新処理について、.NET Framework2.0から提供されるClickOnce機能などとの比較も交えて解説する予定である。
INDEX | ||
連載:Enterprise Library概説 | ||
一貫した例外管理機能を実装しよう | ||
1.例外管理のベスト・プラクティス | ||
2.Exception Handling Application Blockが提供する機能 | ||
「Enterprise Library概説」 |
- 第2回 簡潔なコーディングのために (2017/7/26)
ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている - 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう - 第1回 明瞭なコーディングのために (2017/7/19)
C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える - Presentation Translator (2017/7/18)
Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
|
|