質問
契約を履行するために2つの操作を行う必要があるBOメソッドがあります。
- データベースにレコードを挿入
- レコードのメタデータを含む電子メール通知を送信します
両方とも、アクションの完了を担当する個々のDAOメソッドの呼び出しで処理されます。
DAOで例外をトラップせず、BOで例外を処理して公開します。最初の呼び出しは、挿入するDAOへの呼び出しであり、NullReferenceExceptionまたはSQL例外の1つをスローできます。 emailメソッドは、多数の例外をスローできるSmtpClient.Sendを使用します。
属性を介して、電子メール機能を呼び出す子メソッドに、カスタムの例外を1種類のみ返すように強制することはできますか?
これを説明するには:
public void AddSupportTicket(SupportTicketDTO ticket)
{
try
{
supportTicketDAO.Insert(ticket);
email.SendNotification(ticket);
}
catch (ExceptionA exc) { ... } // both of the methods can throw exceptions that
catch (ExceptionB exc) { ... } // can overlap. I just care about returning
catch (ExceptionC exc) { ... } // a custom EmailException or DataException
}
各子メソッド呼び出しを独自のtry catchでラップして、必要なカスタム例外をスローできますが、それは、AddSupportTicketの別のtry catchにトラップされ、次にリダイレクトするUIのtry catchにトラップされる別のレベルのtry catchですインテリジェントなエラーなので、それは私には素晴らしいとは言えません。
正しいカスタム例外を効率的にスローするにはどうすればよいですか
解決
はい、それは非常に可能です。エンタープライズライブラリ例外処理ブロックをご覧ください。必要に応じて構成で処理できるようにポリシーを設定するだけでなく、レイヤー間での例外の発生、ラッピング、ログ記録に関する多くの優れた機能があります。ロギングアプリケーションブロックと組み合わせると、強力な組み合わせになります。
他のヒント
WCFを使用している場合、特定の関数からスローできる例外の種類を指定できるため、サービスインターフェイスには次のようなものがあります
[OperationContract]
[FaultContract(typeof(MemberAlreadyExistsException))]
void MemberInsert(Member mu);
属性については知りませんが、あなただけではできません:
try{
...
} catch(Exception ex) {
throw new MyException("Some biz msg", ex);
}
C#は、Javaの throws
キーワードのような機能を提供していません。コードがXMLドキュメント標準を介してスローする例外の種類をドキュメント化できますが、これを契約上強制する方法はありません。
あなたの最善の策は、適切なドキュメントと、アプリケーションのすべてのレベルでのインテリジェントな例外処理です。