概要
AmazonLinux2023インスタンス上にコンテナで.NETを利用したサーバをたてる
そのお勉強メモ6
ミドルウェアを使ってみる
グローバルなミドルウェア
どのルートであっても必ず通るようになるミドルウェア
xx.xx.xx.xx/helloにアクセスして、コンテナログに「GlobalMiddleware start」と「GlobalMiddleware end」が出力されていればok
var app = builder.Build();
app.UseMiddleware<GlobalMiddleware>(); // これ追加
app.MapGet("/", () => "Hello, World!");
app.MapControllers();
app.Run();
public class GlobalMiddleware
{
private readonly RequestDelegate _next;
public GlobalMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context)
{
Console.WriteLine("GlobalMiddleware start");
await _next(context);
Console.WriteLine("GlobalMiddleware end");
}
}
特定ルートにだけ適用するミドルウェア
ついでに、Program.csにミドルウェアがまとまらないようにミドルウェア適用用のクラス作ってみる
var app = builder.Build();
app.RegisterMiddlewares(); // これ追加
app.MapGet("/", () => "Hello, World!");
app.MapControllers();
app.Run();
public static class MiddlewareFactory
{
public static void RegisterMiddlewares(this IApplicationBuilder app)
{
MiddlewareFactory.RegisterGlobalMiddleware(app);
MiddlewareFactory.RegisterHelloMiddleware(app);
}
private static void RegisterGlobalMiddleware(IApplicationBuilder app)
{
app.UseMiddleware<GlobalMiddleware>();
}
private static void RegisterHelloMiddleware(IApplicationBuilder app)
{
// /helloから始まるルート全部に適用
app.UseWhen(
context => context.Request.Path.StartsWithSegments("/hello", StringComparison.OrdinalIgnoreCase),
appBuilder => {
appBuilder.UseMiddleware<HelloMiddleware>();
}
);
}
}
public class HelloMiddleware
{
private readonly RequestDelegate _next;
public HelloMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context)
{
Console.WriteLine("HelloMiddleware start");
await _next(context);
Console.WriteLine("HelloMiddleware end");
}
}
その他メモ
拡張メソッド
.NETではなくC#の言語機能で、既存のクラスに新しいメソッドを追加する機能だそう
Traitみたいなものか?
MiddlewareFactoryの関数をapp.RegisterMiddlewares()という呼び出し方ができているのはこれのおかげ
this修飾子をつけると、その後に設定したクラスに対して新しいメソッドを追加できる
ルート、アクション指定の処理指定方法
・useWhen以外にMapWhenもある
・Controller/Actionごとに設定するActionFilterというのもあるらしい
使い分けとか、動きの違いとか追って調査したい
ざっくりActionFilterの書き方こんな感じ
using Microsoft.AspNetCore.Mvc;
[ApiController]
[Route("[controller]")]
public class HelloController : ControllerBase
{
[HttpGet]
[HelloMiddlewareFilter] // これ
public string index() => "Hello index";
}
でも、ミドルウェアも完全パス指定できるらしい
どうしたもんだろう
app.UseWhen(
context => context.Request.Path.StartsWithSegments("/hello"),
appBuilder => {
appBuilder.UseMiddleware<HelloMiddleware>();
}
);
雑記
ここまで勉強してみて思ったけど、すごいlaravelに似てる
DIだし、まだやってないけどORMもあるみたいだし、ミドルウェアあるし
割と理解しやすいかも?
C#とPHPの言語の差はかなり感じるけど