パイプラインビヘイビアー
ビヘイビアーで横断的な処理を追加します。
「パイプラインビヘイビアー」はCoddyKit上の無料C# Academyレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはC# Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 C# Academyコースには全4レッスンが含まれています。
横断的関心事
ロギング、検証、計測、トランザクションは多くのハンドラーに適用されます。そのコードを各ハンドラーにコピーすると、冗長でエラーが発生しやすくなります。
MediatR のパイプラインビヘイビアを使うと、共通ロジックですべてのリクエストをラップできます。
// One behavior runs around all handlersIPipelineBehavior
ビヘイビアは IPipelineBehavior<TRequest, TResponse> を実装します。その Handle メソッドは、リクエストと、パイプラインの残りを呼び出す next デリゲートを受け取ります。
public class LoggingBehavior<TRequest, TResponse>
: IPipelineBehavior<TRequest, TResponse>
where TRequest : notnull
{
public async Task<TResponse> Handle(
TRequest request,
RequestHandlerDelegate<TResponse> next,
CancellationToken ct)
{
// before
var response = await next();
// after
return response;
}
}next デリゲート
next() は次のビヘイビアを呼び出します。これが最後のビヘイビアの場合は、実際のハンドラーを呼び出します。呼び出しの前に記述したコードは処理の入り口で実行され、呼び出しの後に記述したコードは出口で実行されます。
// [Behavior A in] -> [Behavior B in] -> [Handler]
// <- [Behavior B out] <- [A out]ロギングビヘイビア
具体的なロギングビヘイビアでは、処理の入り口でリクエスト名を記録し、出口で経過時間を記録します。
public async Task<TResponse> Handle(
TRequest request,
RequestHandlerDelegate<TResponse> next,
CancellationToken ct)
{
var name = typeof(TRequest).Name;
_logger.LogInformation("Handling {Name}", name);
var sw = Stopwatch.StartNew();
var response = await next();
_logger.LogInformation("{Name} took {Ms}ms", name, sw.ElapsedMilliseconds);
return response;
}ビヘイビアの登録
オープンジェネリックのビヘイビアを DI に登録します。MediatR がすべてのリクエストに適用します。
builder.Services.AddTransient(
typeof(IPipelineBehavior<,>),
typeof(LoggingBehavior<,>));検証ビヘイビア
よく使われる用途の 1 つが、FluentValidation によるリクエスト検証です。ビヘイビアはハンドラーの実行前にすべてのバリデーターを実行し、1 つでも失敗すると例外をスローします。
public async Task<TResponse> Handle(
TRequest request,
RequestHandlerDelegate<TResponse> next,
CancellationToken ct)
{
var context = new ValidationContext<TRequest>(request);
var failures = _validators
.Select(v => v.Validate(context))
.SelectMany(r => r.Errors)
.Where(f => f is not null)
.ToList();
if (failures.Count != 0)
throw new ValidationException(failures);
return await next();
}ショートサーキット
ビヘイビアは next() を呼び出さずに戻ることで、ハンドラー全体をスキップできます。クエリ結果のキャッシュや、無効なリクエストの拒否に役立ちます。
if (_cache.TryGet(key, out TResponse cached))
return cached; // handler never runs
var response = await next();
_cache.Set(key, response);
return response;ビヘイビアの順序
ビヘイビアは登録された順序で実行されます。ロギングを最外側に置き、次に検証、最後にトランザクションを置くと、それぞれが正しく次の処理をラップします。
services.AddTransient(typeof(IPipelineBehavior<,>), typeof(LoggingBehavior<,>));
services.AddTransient(typeof(IPipelineBehavior<,>), typeof(ValidationBehavior<,>));
services.AddTransient(typeof(IPipelineBehavior<,>), typeof(TransactionBehavior<,>));トランザクションビヘイビア
コマンドハンドラーをデータベーストランザクションでラップし、操作全体をアトミックにコミットまたはロールバックできるようにします。
await using var tx = await _db.Database.BeginTransactionAsync(ct);
try
{
var response = await next();
await tx.CommitAsync(ct);
return response;
}
catch
{
await tx.RollbackAsync(ct);
throw;
}特定のリクエストへの適用
マーカーインターフェイスとジェネリック制約を使うと、適用を選択したリクエストにだけビヘイビアを適用できます。たとえば、トランザクションをコマンドだけに適用できます。
public interface ITransactional { }
public record CreateOrderCommand(...) : IRequest<int>, ITransactional;
// where TRequest : ITransactionalミドルウェアよりビヘイビアが適している理由
HTTP ミドルウェアとは異なり、ビヘイビアはメッセージごとに実行され、型付きのリクエストとレスポンスを扱えます。また、HTTP の外部(例:バックグラウンドジョブ)からリクエストをディスパッチした場合でも動作します。
// Strongly typed, transport-independent cross-cutting logic理解度チェック
ビヘイビアの動作を確認しましょう。
まとめ
パイプラインビヘイビアを学びました。
IPipelineBehavior<TRequest, TResponse>が共通ロジックですべてのリクエストをラップします。nextデリゲートがパイプラインを先に進めます。これをスキップするとハンドラーをショートサーキットできます。- 一般的な用途は、ロギング、検証、トランザクション、キャッシュです。
- ビヘイビアは登録順に実行され、強い型付けが適用されます。
次は、通知とイベントについて学びます。
よくある質問
「パイプラインビヘイビアー」レッスンは無料ですか?
はい。「パイプラインビヘイビアー」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、C# Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 C# Academyコースには全4レッスンが含まれています。
「パイプラインビヘイビアー」で何を学びますか?
ビヘイビアーで横断的な処理を追加します。 ブラウザで直接実行するハンズオンコードでC# Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
C# Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのC# Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。
「パイプラインビヘイビアー」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このC# Academyレッスンでコードを書いて実行できますか?
はい。すべてのC# Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- CQRSの概念
- MediatRによるコマンドとハンドラー
- パイプラインビヘイビアー
- 通知とイベント