ASP.NET Core 颿¥è³ªå 25éžïŒããã«ãŠã§ã¢ãDIãMinimal APIs ãå®å šæ»ç¥
ASP.NET Core ã®é¢æ¥ã§é »åºããããã«ãŠã§ã¢ãã€ãã©ã€ã³ãäŸåæ§æ³šå ¥ã®ã©ã€ãã¿ã€ã 管çãMinimal APIs ã«é¢ãã25ã®è³ªåãšå®è·µçãªã³ãŒãäŸãç¶²çŸ çã«è§£èª¬ããŸãã

ASP.NET Core ã¯ãã¯ãã¹ãã©ãããã©ãŒã 察å¿ã®é«æ§èœWebãã¬ãŒã ã¯ãŒã¯ãšããŠããšã³ã¿ãŒãã©ã€ãºéçºã®çŸå Žã§åºãæ¡çšãããŠããŸããæè¡é¢æ¥ã«ãããŠã¯ãããã«ãŠã§ã¢ãã€ãã©ã€ã³ãäŸåæ§æ³šå ¥ïŒDIïŒããã㊠Minimal APIs ã«é¢ããæ·±ãçè§£ãæ±ããããŸããæ¬èšäºã§ã¯ãASP.NET Core ã®é¢æ¥ã§é »åºãã25ã®è³ªåãå³éžããããããã®åçãšå®è·µçãªã³ãŒãäŸã亀ããŠè§£èª¬ããŸãã
ASP.NET Core ã®é¢æ¥ã§ã¯ãåãªãAPI ã®äœ¿ãæ¹ã ãã§ãªããããªããã®ããã«èšèšãããŠããã®ãããšããèšèšææ³ã®çè§£ãéèŠãããŸããããã«ãŠã§ã¢ã®å®è¡é åºãDI ã®ã©ã€ãã¿ã€ã 管çãMinimal APIs ãšåŸæ¥ã®ã³ã³ãããŒã©ãŒã®äœ¿ãåããªã©ãã¢ãŒããã¯ãã£ã¬ãã«ã®å€æåã瀺ãããšãåæ Œãžã®éµãšãªããŸãã
ããã«ãŠã§ã¢ãã€ãã©ã€ã³ïŒè³ªå 1ã6ïŒ
1. ASP.NET Core ã®ããã«ãŠã§ã¢ãšã¯äœã§ããããŸãããªã¯ãšã¹ããã€ãã©ã€ã³ã«ããã圹å²ã説æããŠãã ãã
ããã«ãŠã§ã¢ãšã¯ãHTTPãªã¯ãšã¹ããšã¬ã¹ãã³ã¹ãåŠçããããã«ãã€ãã©ã€ã³ã«çµã¿èŸŒãŸãããœãããŠã§ã¢ã³ã³ããŒãã³ãã§ããåããã«ãŠã§ã¢ã¯ããªã¯ãšã¹ããæ¬¡ã®ã³ã³ããŒãã³ãã«æž¡ãååŸã§åŠçãè¡ããå¿ èŠã«å¿ããŠãã€ãã©ã€ã³ãç絡ïŒshort-circuitïŒãããããšãã§ããŸãããã®ã³ã°ãèªèšŒãäŸå€åŠçãCORS ãªã©ã暪æçé¢å¿äºãåé¢ããããã®ä»çµã¿ãšããŠèšèšãããŠããŸãã
2. ããã«ãŠã§ã¢ã®å®è¡é åºã¯ãªãéèŠã§ãããæ£ããç»é²é åºã瀺ããŠãã ãã
ããã«ãŠã§ã¢ã¯ç»é²ãããé åºã§å®è¡ããããããé åºã誀ããšèªèšŒåã«ãšã³ããã€ã³ããå®è¡ããããªã©ã®ã»ãã¥ãªãã£äžã®åé¡ãçºçããŸãã以äžã¯æšå¥šãããç»é²é åºã§ãã
var app = builder.Build();
app.UseExceptionHandler("/error"); // 1. Outermost: catches all exceptions
app.UseHsts(); // 2. HTTP Strict Transport Security
app.UseHttpsRedirection(); // 3. Redirect HTTP to HTTPS
app.UseStaticFiles(); // 4. Serve static files (short-circuits if found)
app.UseRouting(); // 5. Match request to endpoint
app.UseAuthentication(); // 6. Identify the user
app.UseAuthorization(); // 7. Check permissions
app.MapControllers(); // 8. Execute the matched endpoint
app.Run();UseExceptionHandler ãæãå€åŽã«é
眮ããããšã§ããã€ãã©ã€ã³å
ã®ããããäŸå€ããã£ããã§ããŸããUseStaticFiles ã¯éçãã¡ã€ã«ãèŠã€ãã£ãå Žåã«ãã€ãã©ã€ã³ãç絡ããããããèªèšŒã®åã«é
眮ããã®ãäžè¬çã§ãã
3. ã«ã¹ã¿ã ããã«ãŠã§ã¢ã¯ã©ã®ããã«å®è£ ããŸãã
ã«ã¹ã¿ã ããã«ãŠã§ã¢ã¯ã¯ã©ã¹ããŒã¹ã§å®è£
ããŸããã³ã³ã¹ãã©ã¯ã¿ã§ RequestDelegate ãåãåããInvokeAsync ã¡ãœããã§åŠçãèšè¿°ããŸãã以äžã¯ãªã¯ãšã¹ãã®åŠçæéãèšæž¬ããããã«ãŠã§ã¢ã®äŸã§ãã
public class RequestTimingMiddleware
{
private readonly RequestDelegate _next;
private readonly ILogger<RequestTimingMiddleware> _logger;
public RequestTimingMiddleware(RequestDelegate next, ILogger<RequestTimingMiddleware> logger)
{
_next = next;
_logger = logger;
}
public async Task InvokeAsync(HttpContext context)
{
var stopwatch = Stopwatch.StartNew();
await _next(context); // Call the next middleware
stopwatch.Stop();
_logger.LogInformation(
"Request {Method} {Path} completed in {Elapsed}ms",
context.Request.Method,
context.Request.Path,
stopwatch.ElapsedMilliseconds);
}
}
// Registration in Program.cs
app.UseMiddleware<RequestTimingMiddleware>();ã³ã³ã¹ãã©ã¯ã¿ã§ DI ã³ã³ãããããµãŒãã¹ã泚å
¥ã§ããç¹ããã€ã³ã©ã€ã³ããã«ãŠã§ã¢ïŒapp.Use()ïŒãšã®å€§ããªéãã§ãã
4. app.Use() ãš app.Run() ãš app.Map() ã®éãã¯äœã§ãã
app.Use() ã¯ãã€ãã©ã€ã³ã«ã€ã³ã©ã€ã³ããã«ãŠã§ã¢ã远å ããnext() ãåŒã³åºããŠæ¬¡ã®ããã«ãŠã§ã¢ã«åŠçãæž¡ããŸããapp.Run() ã¯ã¿ãŒããã«ããã«ãŠã§ã¢ãšããŠæ©èœãããã€ãã©ã€ã³ãçµäºãããŸããapp.Map() ã¯ãªã¯ãšã¹ããã¹ã«åºã¥ããŠãã€ãã©ã€ã³ãåå²ãããç¹å®ã®ãã¹ã«å¯ŸããŠç°ãªãããã«ãŠã§ã¢ãã§ãŒã³ãæ§æã§ããŸãã
5. ããã«ãŠã§ã¢ã®ç絡ïŒshort-circuitingïŒãšã¯äœã§ãã
ç絡ãšã¯ãããã«ãŠã§ã¢ã next() ããªã²ãŒããåŒã³åºããã«ã¬ã¹ãã³ã¹ãè¿ãããšã§ãåŸç¶ã®ããã«ãŠã§ã¢ã®å®è¡ãã¹ãããããåäœã§ããäŸãã°ãUseStaticFiles ã¯èŠæ±ããããã¡ã€ã«ãååšããå Žåã«ãã€ãã©ã€ã³ãç絡ãããŸããèªèšŒããã«ãŠã§ã¢ããç¡å¹ãªããŒã¯ã³ãæ€åºããå Žåã« 401 ã¬ã¹ãã³ã¹ãè¿ããŠç絡ãããããšããããŸãã
6. äŸå€åŠçããã«ãŠã§ã¢ãšãã£ã«ã¿ãŒã®äœ¿ãåãã説æããŠãã ãã
äŸå€åŠçããã«ãŠã§ã¢ïŒUseExceptionHandlerïŒã¯ãã€ãã©ã€ã³å
šäœã®äŸå€ããã£ããããã°ããŒãã«ãªã»ãŒããã£ãããã§ããäžæ¹ãäŸå€ãã£ã«ã¿ãŒïŒIExceptionFilterïŒã¯MVCãã€ãã©ã€ã³å
ã§ã®ã¿åäœããã¢ã¯ã·ã§ã³ã®å®è¡äžã«çºçããäŸå€ãåŠçããŸããäžè¬çã«ã¯ãããã«ãŠã§ã¢ã§ã°ããŒãã«ãªäŸå€åŠçãè¡ãããã£ã«ã¿ãŒã§ãã¡ã€ã³åºæã®ãšã©ãŒãã³ããªã³ã°ãè¡ããšããçµã¿åãããæšå¥šãããŸãã
äŸåæ§æ³šå ¥ïŒè³ªå 7ã12ïŒ
7. ASP.NET Core ã«ããã DI ã®3ã€ã®ã©ã€ãã¿ã€ã ã説æããŠãã ãã
ASP.NET Core ã® DI ã³ã³ããã¯3ã€ã®ãµãŒãã¹ã©ã€ãã¿ã€ã ãæäŸããŸããTransient ã¯èŠæ±ããããã³ã«æ°ããã€ã³ã¹ã¿ã³ã¹ãçæããŸããScoped ã¯HTTPãªã¯ãšã¹ãããšã«1ã€ã®ã€ã³ã¹ã¿ã³ã¹ãå ±æããŸããSingleton ã¯ã¢ããªã±ãŒã·ã§ã³ã®ã©ã€ãã¿ã€ã å šäœã§1ã€ã®ã€ã³ã¹ã¿ã³ã¹ãç¶æããŸããã©ã€ãã¿ã€ã ã®éžæã¯ã¡ã¢ãªäœ¿çšéãã¹ã¬ããã»ãŒããã£ã«çŽæ¥åœ±é¿ãããããæ éãªå€æãæ±ããããŸãã
8. Scoped ãµãŒãã¹ã¯ã©ã®ãããªå Žåã«äœ¿çšããŸãã
Scoped ãµãŒãã¹ã¯ã1ã€ã®HTTPãªã¯ãšã¹ãå
ã§ã¹ããŒããå
±æããå¿
èŠãããå Žåã«é©ããŠããŸããå
žåçãªäŸãšããŠãEntity Framework Core ã® DbContext ããããŸããDbContext ã¯å€æŽè¿œè·¡ããã©ã³ã¶ã¯ã·ã§ã³ç®¡çã®ããã«ãªã¯ãšã¹ãã¹ã³ãŒãã§å
±æãããå¿
èŠããããŸããããªã¯ãšã¹ãéã§ã¯åé¢ãããã¹ãã§ãã
9. ãã£ããã£ãäŸåæ§ïŒCaptive DependencyïŒåé¡ãšã¯äœã§ãã
Singleton ãµãŒãã¹ã Scoped ã Transient ã®ãµãŒãã¹ã«äŸåãããšãçãã©ã€ãã¿ã€ã ã®ãµãŒãã¹ã Singleton ã«ãã£ãŠãææããããæ³å®ããé·ãçåããŠããŸããŸããããã«ãããã¡ã¢ãªãªãŒã¯ãã¹ã¬ããã»ãŒããã£ã®åé¡ãçºçããå¯èœæ§ããããŸããéçºç°å¢ã§ã¯ ValidateScopes ãæå¹ã«ããŠããã®åé¡ãèµ·åæã«æ€åºããããšãéèŠã§ãã
builder.Services.AddScoped<IUserRepository, UserRepository>();
builder.Services.AddSingleton<ICacheService, CacheService>(); // CacheService takes IUserRepository
// This throws at startup in Development when ValidateScopes is enabled:
builder.Host.UseDefaultServiceProvider(options =>
{
options.ValidateScopes = true; // Catches captive dependencies
options.ValidateOnBuild = true; // Validates all registrations at startup
});ValidateOnBuild ã true ã«ãããšãæªç»é²ã®ãµãŒãã¹ãžã®äŸåãèµ·åæã«æ€åºã§ãããããæ¬çªç°å¢ã§ã®ã©ã³ã¿ã€ã ãšã©ãŒãæªç¶ã«é²ãããšãã§ããŸãã
10. .NET 8 ã§å°å ¥ãããããŒä»ããµãŒãã¹ïŒKeyed ServicesïŒãšã¯äœã§ãã
ããŒä»ããµãŒãã¹ã¯ãåäžã€ã³ã¿ãŒãã§ãŒã¹ã®è€æ°ã®å®è£ ãããŒïŒæååïŒã§åºå¥ããŠç»é²ã»è§£æ±ºããæ©èœã§ããåŸæ¥ã¯æåã§ãã¡ã¯ããªãã¿ãŒã³ãå®è£ ããå¿ èŠããããŸããããããŒä»ããµãŒãã¹ã«ãã DI ã³ã³ããããã€ãã£ãã«ãµããŒãããããã«ãªããŸããã
builder.Services.AddKeyedSingleton<INotificationService, EmailNotification>("email");
builder.Services.AddKeyedSingleton<INotificationService, SmsNotification>("sms");
builder.Services.AddKeyedSingleton<INotificationService, PushNotification>("push");
// Resolving in a controller or service
public class OrderService
{
public OrderService(
[FromKeyedServices("email")] INotificationService emailService,
[FromKeyedServices("sms")] INotificationService smsService)
{
// Each parameter gets its specific implementation
}
}颿¥ã§ã¯ãããŒä»ããµãŒãã¹ãå°å
¥ããã以åã®è§£æ±ºçïŒãã¡ã¯ããªãã¿ãŒã³ã IEnumerable<T> ã®å©çšïŒãšã®æ¯èŒã説æã§ãããšãããæ·±ãçè§£ã瀺ãããšãã§ããŸãã
11. ãã³ã¬ãŒã¿ãŒãã¿ãŒã³ã DI ã§å®è£ ããæ¹æ³ã説æããŠãã ãã
ASP.NET Core ã®çµã¿èŸŒã¿ DI ã³ã³ããã¯ãã³ã¬ãŒã¿ãŒãçŽæ¥ãµããŒãããŠããŸãããããã¡ã¯ããªç»é²ã䜿ãããšã§å®çŸã§ããŸãã以äžã¯ããã£ãã·ã¥æ©èœããã³ã¬ãŒã¿ãŒãšããŠè¿œå ããäŸã§ãã
// Decorating IProductService with caching
builder.Services.AddScoped<ProductService>();
builder.Services.AddScoped<IProductService>(sp =>
{
var inner = sp.GetRequiredService<ProductService>();
var cache = sp.GetRequiredService<IMemoryCache>();
return new CachedProductService(inner, cache);
});ãã®ææ³ã«ãããå ã®ãµãŒãã¹ã®ã³ãŒãã倿Žããããšãªãããã£ãã·ã¥ããã®ã³ã°ãªã©ã®æšªæçé¢å¿äºã远å ã§ããŸããããè€éãªãã³ã¬ãŒã¿ãŒãã§ãŒã³ãå¿ èŠãªå Žåã¯ãScrutor ãªã©ã®ã©ã€ãã©ãªã®æŽ»çšãæšå¥šãããŸãã
12. DI ã³ã³ããã«åäžã€ã³ã¿ãŒãã§ãŒã¹ã®è€æ°ã®å®è£ ãç»é²ããå Žåãã©ã®ããã«è§£æ±ºãããŸãã
åäžã€ã³ã¿ãŒãã§ãŒã¹ã«å¯ŸããŠè€æ°ã®å®è£
ãç»é²ããå ŽåãæåŸã«ç»é²ããããã®ãããã©ã«ããšããŠè§£æ±ºãããŸãããã¹ãŠã®å®è£
ãååŸããã«ã¯ IEnumerable<T> ãæ³šå
¥ããŸããç¹å®ã®å®è£
ãéžæããã«ã¯ããŒä»ããµãŒãã¹ããŸãã¯ãã¡ã¯ããªãã¿ãŒã³ã䜿çšããŸãã
.NETã®é¢æ¥å¯Ÿçã¯ã§ããŠããŸããïŒ
ã€ã³ã¿ã©ã¯ãã£ããªã·ãã¥ã¬ãŒã¿ãŒãflashcardsãæè¡ãã¹ãã§ç·Žç¿ããŸãããã
Minimal APIsïŒè³ªå 13ã18ïŒ
13. Minimal APIs ãšã¯äœã§ãããåŸæ¥ã®ã³ã³ãããŒã©ãŒãšã®éãã説æããŠãã ãã
Minimal APIs ã¯ãASP.NET Core 6 ã§å°å
¥ããã軜éãªAPIæ§ç¯ã¢ãããŒãã§ããã³ã³ãããŒã©ãŒã¯ã©ã¹ãã¢ã¯ã·ã§ã³ãã£ã«ã¿ãŒã®ä»çµã¿ã䜿ãããProgram.cs ããšã³ããã€ã³ãã¯ã©ã¹ã«çŽæ¥ã«ãŒããã³ãã©ãŒãå®çŸ©ããŸãããã€ã©ãŒãã¬ãŒãã³ãŒãã倧å¹
ã«åæžãããäžæ¹ãã³ã³ãããŒã©ãŒãæäŸããã¢ãã«ãã€ã³ãã£ã³ã°ããã£ã«ã¿ãŒãã€ãã©ã€ã³ã®äžéšæ©èœã¯å©çšã§ããŸããããã€ã¯ããµãŒãã¹ãå°èŠæš¡APIã«é©ããŠããŸãã
14. Minimal APIs ã§ãšã³ããã€ã³ããã°ã«ãŒãåããæŽçããæ¹æ³ã瀺ããŠãã ãã
MapGroup ã䜿çšããããšã§ãå
±éã®ãã¬ãã£ãã¯ã¹ãèšå®ãæã€ãšã³ããã€ã³ããã°ã«ãŒãåã§ããŸãã以äžã¯ãæ©èœããšã«ãšã³ããã€ã³ããæŽçããæšå¥šãã¿ãŒã³ã§ãã
public static class ProductEndpoints
{
public static void MapProductEndpoints(this WebApplication app)
{
var group = app.MapGroup("/api/products")
.WithTags("Products")
.RequireAuthorization();
group.MapGet("/", GetAll);
group.MapGet("/{id:int}", GetById);
group.MapPost("/", Create);
}
private static async Task<IResult> GetAll(
IProductService productService, // Auto-resolved from DI
CancellationToken cancellationToken)
{
var products = await productService.GetAllAsync(cancellationToken);
return TypedResults.Ok(products);
}
private static async Task<IResult> GetById(
int id,
IProductService productService)
{
var product = await productService.GetByIdAsync(id);
return product is null
? TypedResults.NotFound()
: TypedResults.Ok(product);
}
private static async Task<IResult> Create(
CreateProductRequest request,
IProductService productService)
{
var product = await productService.CreateAsync(request);
return TypedResults.Created($"/api/products/{product.Id}", product);
}
}
// Program.cs â Clean registration
app.MapProductEndpoints();æ¡åŒµã¡ãœãããšããŠå®çŸ©ããããšã§ãProgram.cs ãã¯ãªãŒã³ã«ä¿ã¡ã€ã€ãæ©èœããšã®ã¢ãžã¥ãŒã«åãå®çŸã§ããŸãã
15. TypedResults ãš Results ã®éãã¯äœã§ãã
Results 㯠IResult ãè¿ãéçãã«ããŒã¡ãœãããæäŸããŸãããè¿åŽå㯠IResult ã®ãŸãŸã§ããTypedResults ã¯å
·äœçãªåïŒOk<T>, NotFound ãªã©ïŒãè¿ããããOpenAPI ããã¥ã¡ã³ãã®èªåçæãã³ã³ãã€ã«æã®åãã§ãã¯ã«åªããŠããŸããMinimal APIs ã§ã¯ TypedResults ã®äœ¿çšãæšå¥šãããŸãã
16. Minimal APIs ã§ããªããŒã·ã§ã³ãå®è£ ããæ¹æ³ã説æããŠãã ãã
Minimal APIs ã«ã¯ã³ã³ãããŒã©ãŒã®ãããªèªåã¢ãã«ããªããŒã·ã§ã³æ©æ§ããªãããããšã³ããã€ã³ããã£ã«ã¿ãŒã FluentValidation ãªã©ã®ã©ã€ãã©ãªã䜿çšããŸãããšã³ããã€ã³ããã£ã«ã¿ãŒïŒAddEndpointFilterïŒã䜿ãã°ããã³ãã©ãŒã®å®è¡åã«ããªããŒã·ã§ã³ããžãã¯ãæ¿å
¥ã§ããŸããå
±éã®ããªããŒã·ã§ã³ãã£ã«ã¿ãŒãäœæããMapGroup ã«é©çšããããšã§ãDRYååãå®ããªããããªããŒã·ã§ã³ãäžå
管çã§ããŸãã
17. Minimal APIs ã§ DI ã¯ã©ã®ããã«æ©èœããŸãã
Minimal APIs ã®ãã³ãã©ãŒãã©ã¡ãŒã¿ã¯ãDI ã³ã³ããããèªåçã«è§£æ±ºãããŸãããã©ã¡ãŒã¿ã®åãDIã«ç»é²ããããµãŒãã¹ãšäžèŽããå Žåããã¬ãŒã ã¯ãŒã¯ãèªåçã«ã€ã³ã¹ã¿ã³ã¹ã泚å
¥ããŸããã«ãŒããã©ã¡ãŒã¿ãã¯ãšãªæååããªã¯ãšã¹ãããã£ãšã®åºå¥ã¯ããã©ã¡ãŒã¿ã®åãšå±æ§ïŒ[FromQuery], [FromBody] ãªã©ïŒã«åºã¥ããŠè¡ãããŸãã
18. Minimal APIs ã§ããã«ãŠã§ã¢ãšãšã³ããã€ã³ããã£ã«ã¿ãŒãã©ã®ããã«äœ¿ãåããŸãã
ããã«ãŠã§ã¢ã¯ãã€ãã©ã€ã³å šäœã«é©çšãããã°ããŒãã«ãªåŠçã«é©ããŠããŸãããšã³ããã€ã³ããã£ã«ã¿ãŒã¯ç¹å®ã®ãšã³ããã€ã³ããã°ã«ãŒãã«å¯ŸããŠã®ã¿é©çšãããåŠçã«äœ¿çšããŸããäŸãã°ããªã¯ãšã¹ããã®ã³ã°ã¯ããã«ãŠã§ã¢ã§ãå ¥åããªããŒã·ã§ã³ã¯ãšã³ããã€ã³ããã£ã«ã¿ãŒã§å®è£ ããã®ãé©åã§ãã
å¿çšã»ç·ååé¡ïŒè³ªå 19ã25ïŒ
19. Options ãã¿ãŒã³ãšã¯äœã§ãããèšå®ç®¡çã®ãã¹ããã©ã¯ãã£ã¹ã説æããŠãã ãã
Options ãã¿ãŒã³ã¯ãappsettings.json ãªã©ã®èšå®å€ã匷ãåä»ãã®ã¯ã©ã¹ã«ãã€ã³ãããDI ãéããŠæäŸããä»çµã¿ã§ããIOptions<T>ãIOptionsSnapshot<T>ãIOptionsMonitor<T> ã®3çš®é¡ãããããããã SingletonãScopedïŒãªã¯ãšã¹ãããšã«åèªã¿èŸŒã¿ïŒããªã¢ã«ã¿ã€ã 倿Žéç¥ãšããç¹æ§ãæã¡ãŸããèšå®ã¯ã©ã¹ã«ã¯ããŒã¿ã¢ãããŒã·ã§ã³ã«ããããªããŒã·ã§ã³ãé©çšã§ããValidateOnStart ã§èµ·åææ€èšŒãå¯èœã§ãã
20. ãã«ã¹ãã§ãã¯ã®å®è£ æ¹æ³ãšããã®æŽ»çšå Žé¢ã説æããŠãã ãã
ASP.NET Core ã®ãã«ã¹ãã§ãã¯æ©èœïŒAddHealthChecksïŒã¯ãã¢ããªã±ãŒã·ã§ã³ãšãã®äŸåãµãŒãã¹ïŒããŒã¿ããŒã¹ãå€éšAPIãã¡ãã»ãŒãžãã¥ãŒãªã©ïŒã®çšŒåç¶æ³ãç£èŠããããã®ãšã³ããã€ã³ããæäŸããŸããKubernetes ã® Liveness Probe ã Readiness ProbeãããŒããã©ã³ãµãŒã®ãã«ã¹ãã§ãã¯ã«å©çšãããŸããã«ã¹ã¿ã ãã«ã¹ãã§ãã¯ã¯ IHealthCheck ã€ã³ã¿ãŒãã§ãŒã¹ãå®è£
ããŠäœæããHealthyãDegradedãUnhealthy ã®ããããã®ã¹ããŒã¿ã¹ãè¿ããŸãã
21. Rate Limiting ããã«ãŠã§ã¢ã®ä»çµã¿ãšèšå®æ¹æ³ã説æããŠãã ãã
.NET 7 ã§å°å
¥ãããçµã¿èŸŒã¿ã® Rate Limiting ããã«ãŠã§ã¢ã¯ãFixed WindowãSliding WindowãToken BucketãConcurrency ã®4ã€ã®ã¢ã«ãŽãªãºã ããµããŒãããŠããŸããAddRateLimiter ã§ããªã·ãŒãå®çŸ©ããUseRateLimiter ã§ãã€ãã©ã€ã³ã«è¿œå ããŸããMinimal APIs ã§ã¯ RequireRateLimiting("policyName") ã§ãšã³ããã€ã³ãããšã«ããªã·ãŒãé©çšã§ããŸãããŠãŒã¶ãŒåäœãIPã¢ãã¬ã¹åäœã§ã®å¶éããããŒãã£ã·ã§ã³ããŒãæå®ããããšã§å®çŸå¯èœã§ãã
22. Output Caching ãš Response Caching ã®éãã¯äœã§ãã
Response Caching 㯠HTTP ãã£ãã·ã¥ããããŒïŒCache-ControlïŒã«åºã¥ããŠã¯ã©ã€ã¢ã³ããäžéãããã·ã§ã®ãã£ãã·ã¥ãå¶åŸ¡ããä»çµã¿ã§ããOutput CachingïŒ.NET 7 以éïŒã¯ãµãŒããŒãµã€ãã§ã¬ã¹ãã³ã¹ããã£ãã·ã¥ããåŸç¶ã®ãªã¯ãšã¹ãã«å¯ŸããŠãã€ãã©ã€ã³ã®å€§éšåããã€ãã¹ããŠé«éã«ã¬ã¹ãã³ã¹ãè¿ããŸããOutput Caching ã¯ã¿ã°ããŒã¹ã®ç¡å¹åãã«ã¹ã¿ã ããªã·ãŒã«å¯Ÿå¿ããŠãããããæè»ãªãã£ãã·ã¥æŠç¥ãå®çŸã§ããŸãã
23. ããã«ãŠã§ã¢ã®åäœãã¹ãã¯ã©ã®ããã«å®è£ ããŸãã
ããã«ãŠã§ã¢ã®ãã¹ãã§ã¯ãDefaultHttpContext ã䜿çšããŠHTTPã³ã³ããã¹ããæ§ç¯ããã¿ãŒããã«ããªã²ãŒããšã㊠Task.CompletedTask ãè¿ãã©ã ããæž¡ããŸãã以äžã¯ RequestTimingMiddleware ã®ãã¹ãäŸã§ãã
[Fact]
public async Task Middleware_LogsElapsedTime()
{
var logger = new FakeLogger<RequestTimingMiddleware>();
var middleware = new RequestTimingMiddleware(
next: (ctx) => Task.CompletedTask, // Terminal delegate
logger: logger);
var context = new DefaultHttpContext();
context.Request.Method = "GET";
context.Request.Path = "/api/products";
await middleware.InvokeAsync(context);
Assert.Single(logger.LogEntries);
Assert.Contains("completed in", logger.LogEntries[0].Message);
}FakeLogger ã®ãããªãã¹ãçšã®ãã¬ãŒå®è£
ã䜿ãããšã§ããã°åºåãæ€èšŒã§ããŸããçµ±åãã¹ãã§ã¯ WebApplicationFactory ã䜿çšããŠããã€ãã©ã€ã³å
šäœã®åäœãæ€èšŒããããšãå¯èœã§ãã
24. Minimal APIs ãšåŸæ¥ã®ã³ã³ãããŒã©ãŒãåäžãããžã§ã¯ãã§å ±åãããããšã¯å¯èœã§ãã
å
±åã¯å®å
šã«ãµããŒããããŠããŸããProgram.cs ã§ app.MapControllers() ãš Minimal API ã®ãšã³ããã€ã³ãç»é²ã䜵èšããã ãã§å®çŸã§ããŸããæ®µéçãªãã€ã°ã¬ãŒã·ã§ã³æŠç¥ãšããŠãæ°ãããšã³ããã€ã³ãã Minimal APIs ã§è¿œå ãã€ã€ãæ¢åã®ã³ã³ãããŒã©ãŒããã®ãŸãŸç¶æããã¢ãããŒããå®è·µçã§ããã«ãŒãã£ã³ã°ã®ç«¶åã«æ³šæããOpenAPI ããã¥ã¡ã³ãã§ã¯ã¿ã°ã䜿ã£ãŠã°ã«ãŒãåãããããšãæšå¥šãããŸãã
25. ASP.NET Core ã¢ããªã±ãŒã·ã§ã³ã®ããã©ãŒãã³ã¹æé©åã«ãããŠãããã«ãŠã§ã¢ãš DI ã®èгç¹ããéèŠãªãã€ã³ãã¯äœã§ãã
ããã©ãŒãã³ã¹æé©åã«ãããŠã¯ã以äžã®èгç¹ãéèŠã§ããããã«ãŠã§ã¢ã®é åºãæé©åããç絡å¯èœãªåŠçïŒéçãã¡ã€ã«ããã«ã¹ãã§ãã¯ïŒãæ©ã段éã«é
眮ããããšãDI ã®ã©ã€ãã¿ã€ã ãé©åã«éžæããäžèŠãª Transient ç»é²ãé¿ã㊠Scoped ã Singleton ãæŽ»çšããããšãIServiceProvider ãçŽæ¥äœ¿çšãããµãŒãã¹ãã±ãŒã¿ãŒãã¿ãŒã³ãé¿ããã³ã³ã¹ãã©ã¯ã¿ã€ã³ãžã§ã¯ã·ã§ã³ã培åºããããšãéåæããã«ãŠã§ã¢ã§ã¯ async/await ãæ£ãã䜿çšããäžèŠãªã¹ã¬ããããŒã«ã®æ¶è²»ãé²ãããšããããã®èŠçŽ ãç·åçã«èæ
®ããããšã§ãé«ã¹ã«ãŒããããã€äœã¬ã€ãã³ã·ã®ã¢ããªã±ãŒã·ã§ã³ãå®çŸã§ããŸãã
25åãã¹ãŠãæèšããå¿ èŠã¯ãããŸãããéèŠãªã®ã¯ãããã«ãŠã§ã¢ãã€ãã©ã€ã³ã®èšèšååãDI ã©ã€ãã¿ã€ã ã®ãã¬ãŒããªããMinimal APIs ã®é©çšå€æãšãã£ãããªããã®éšåãèªåã®èšèã§èª¬æã§ããããšã§ããå®éã«ã³ãŒããæžããŠåäœã確èªããåã³ã³ã»ããã®é¢é£æ§ãäœç³»çã«çè§£ããããšãã颿¥ã§ã®èªä¿¡ã«ã€ãªãããŸãã
ãŸãšã
ASP.NET Core ã®é¢æ¥ã§æåããããã«ã¯ã以äžã®ãã€ã³ããæŒãããŠããããšãéèŠã§ãã
- ããã«ãŠã§ã¢ãã€ãã©ã€ã³: å®è¡é åºã®éèŠæ§ãç絡ã®ä»çµã¿ãã«ã¹ã¿ã ããã«ãŠã§ã¢ã®å®è£ ãã¿ãŒã³ãçè§£ãã
- äŸåæ§æ³šå ¥: 3ã€ã®ã©ã€ãã¿ã€ã ïŒTransientãScopedãSingletonïŒã®äœ¿ãåãããã£ããã£ãäŸåæ§ã®åé¡ãšæ€åºæ¹æ³ãããŒä»ããµãŒãã¹ããã³ã¬ãŒã¿ãŒãã¿ãŒã³ãææ¡ãã
- Minimal APIs: ã³ã³ãããŒã©ãŒãšã®éãã
MapGroupã«ãããšã³ããã€ã³ãã®æŽçãTypedResultsã®å©ç¹ããšã³ããã€ã³ããã£ã«ã¿ãŒã®æŽ»ç𿹿³ãç¿åŸãã - ãã¹ã:
DefaultHttpContextãWebApplicationFactoryãæŽ»çšããããã«ãŠã§ã¢ãšãšã³ããã€ã³ãã®ãã¹ãææ³ã身ã«ã€ãã - å¿çš: Options ãã¿ãŒã³ããã«ã¹ãã§ãã¯ãRate LimitingãOutput Caching ãªã©ãæ¬çªéçšã«äžå¯æ¬ ãªæ©èœãç¶²çŸ ãã
ãããã®ç¥èã¯ãåã«é¢æ¥ãçªç Žããããã ãã§ãªããå ç¢ã§ã¹ã±ãŒã©ãã«ãªASP.NET Core ã¢ããªã±ãŒã·ã§ã³ãèšèšã»æ§ç¯ããããã®åºç€ãšãªããŸããSharpSkill ã®æš¡æ¬é¢æ¥ã·ãã¥ã¬ãŒã¿ãŒããã©ãã·ã¥ã«ãŒããæŽ»çšããŠãå®è·µçãªåç圢åŒã§ãããã®æŠå¿µãç¹°ãè¿ã確èªããããšããå§ãããŸããäœç³»çãªæºåãã颿¥åœæ¥ã®ç¢ºããªèªä¿¡ãçã¿åºããŸãã
ä»ããç·Žç¿ãå§ããŸãããïŒ
颿¥ã·ãã¥ã¬ãŒã¿ãŒãšæè¡ãã¹ãã§ç¥èããã¹ãããŸãããã
ã¿ã°
å ±æ
é¢é£èšäº

.NET 10ïŒ2026幎çïŒïŒæ°æ©èœãNative AOTã颿¥å¯Ÿçå®å šã¬ã€ã
.NET 10ã®æ°æ©èœã培åºè§£èª¬ãNative AOTã®æ¬çªç°å¢å¯Ÿå¿ãC# 14ã®æ¡åŒµã¡ã³ããŒãfieldããŒã¯ãŒããEF Core 10ã®ååä»ãã¯ãšãªãã£ã«ã¿ãŒãªã©ã颿¥ã§å·®ãã€ããç¥èãç¶²çŸ ããŸãã

C#/.NET颿¥è³ªåéïŒ2026幎å®å šã¬ã€ã
C#ãš.NETã®æè¡é¢æ¥ã§é »åºã®17åã培åºè§£èª¬ãLINQãasync/awaitãäŸåæ§æ³šå ¥ãEntity Framework Coreããã¢ãŒããã¯ãã£ãã¿ãŒã³ãŸã§ãã³ãŒãäŸä»ãã§å®è·µçã«åŠã¹ãŸãã

.NET MAUI 2026幎å®å šã¬ã€ãïŒã¯ãã¹ãã©ãããã©ãŒã éçºãšé¢æ¥é »åºè³ªå
.NET MAUI 10ã«ããã¯ãã¹ãã©ãããã©ãŒã ã¢ããªéçºã®æé ãHandlersãMVVMãHybridWebViewãSafeAreaEdgesãšå ±ã«è§£èª¬ãã2026å¹Žã®æè¡é¢æ¥ã§é »åºãã質åãšåçãäœç³»çã«ãŸãšããŠããŸãã