パラメータの型に基づいて、いくつかのハンドラロジックを実装したいと思います。 WebAPIのために例外フィルタ属性を実装する、例えば取る:C#:ジェネリック型の異なる複数のハンドラ
public class ExceptionFilterAttribute : ExceptionFilterAttribute
{
public override void OnException(HttpActionExecutedContext context)
{
if (context.Exception is NotImplementedException)
{
context.Response = new HttpResponseMessage(HttpStatusCode.NotImplemented);
}
}
}
これは自分自身で完全に正常に見えますが、私がやりたいものを、例えば、例外の種類ごとに複数のハンドラを追加されますDbEntityValidationException
、またはビジネスロジックがスローする可能性のあるその他のカスタム例外があります。
もちろん、例外が特定のタイプであるかどうかを確認するために別のブロックを簡単に追加することはできますが、これを避けてさまざまな例外タイプの処理を別々のクラスに分割します。
そのようなクラスのためのインターフェイスがこの
public interface ExceptionHandler<T> where T : Exception {
void Handle(HttpActionExecutedContext context, T exception);
}
のようになります。私は今、ExceptionFilterAttribte
にコレクションにこれらExceptionHandler
秒の実装を追加したいと思いますので、ハンドラがある場合、私は確認することができます例外が発生した場合、適切なキャストを行い、ハンドラを呼び出します。しかし、私は単一のコレクション(例えばclass DbEntityValidationExceptionHandler : ExceptionHandler<DbEntityValidationException>
)に異なるジェネリック型でT
をExceptionHandler
インタフェースの実装を追加することはできませんので、私は、この部分を実装しなければならないか、把握することはできません。
private List<ExceptionHandler<Exception>> handlers = new List<ExceptionHandler<Exception>>()
{
new DbEntityValidationExceptionHandler() // does not compile...
};
どのようにすることができますコレクション内の私のExceptionHandler<T>
インターフェイスのさまざまな実装への参照を保持しますか?あるいは、このアプローチは完全に間違っていますか?そして、このような状況を処理するもっと良い方法がありますか?どんな提案も大歓迎です。あなたがバリアントジェネリックインターフェイスでこれを行うことができます
、彼らが実装することを、一般的な制約タイプ( 'Exception'を)かかり' Handle'方式と非ジェネリックインターフェイスを作成し、コレクションを作りますそのタイプ。 –
できません。ジェネリックは完全ではありません。フレームワークで一般的なほとんどのものは、インターフェイスの非ジェネリックフォームを実装しています(IEnumerable、すべてのコレクションでIEnumerableなど)。それは、何かがというものとは異なるタイプのものであるという事実に沸きます。。共通の基本タイプまたはインタフェースを共有しない限り、同じ方法で複数の型を処理することはできません。あなたのご意見をお寄せいただきありがとうございます。 –
Will
好奇心の念から、処理する例外の種類ごとに 'if'ブロックを追加するだけではなく、そのような振る舞いの実装についてどう思いますか? – forrert