ASP.NET Core Advanced
2/1/24About 2 min
ASP.NET Core Advanced
Overview
ASP.NET Core is a cross-platform, high-performance open-source framework for building modern web applications. This article explores advanced features and best practices in ASP.NET Core.
1. Deep Dive into Dependency Injection
1.1 Service Lifetimes
ASP.NET Core supports three service lifetimes:
// Transient service - a new instance is created for each request
services.AddTransient<ITransientService, TransientService>();
// Scoped service - one instance is shared within each request scope
services.AddScoped<IScopedService, ScopedService>();
// Singleton service - one instance is shared for the entire application lifetime
services.AddSingleton<ISingletonService, SingletonService>();1.2 Constructor Injection
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;
private readonly IMyService _service;
// Constructor injection
public HomeController(ILogger<HomeController> logger, IMyService service)
{
_logger = logger;
_service = service;
}
}1.3 Custom Service Container
public void ConfigureServices(IServiceCollection services)
{
// Register a custom service
services.AddTransient<IMyService, MyService>();
// Create a service using the factory pattern
services.AddSingleton<IMyFactory>(sp =>
{
var config = sp.GetRequiredService<IConfiguration>();
return new MyFactory(config["MySetting"]);
});
}2. Middleware Development
2.1 Custom Middleware
public class CustomMiddleware
{
private readonly RequestDelegate _next;
public CustomMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task InvokeAsync(HttpContext context)
{
// Logic before request processing
Console.WriteLine("请求到达");
// Invoke the next middleware
await _next(context);
// Logic after request processing
Console.WriteLine("请求完成");
}
}
// Extension method
public static class CustomMiddlewareExtensions
{
public static IApplicationBuilder UseCustomMiddleware(
this IApplicationBuilder builder)
{
return builder.UseMiddleware<CustomMiddleware>();
}
}2.2 Using Middleware in Startup
public void Configure(IApplicationBuilder app)
{
app.UseCustomMiddleware();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}3. Advanced Routing Configuration
3.1 Attribute Routing
[ApiController]
[Route("api/[controller]")]
public class ProductsController : ControllerBase
{
[HttpGet]
public ActionResult<IEnumerable<Product>> Get() { ... }
[HttpGet("{id:int}")]
public ActionResult<Product> GetById(int id) { ... }
[HttpGet("search")]
public ActionResult<IEnumerable<Product>> Search([FromQuery] string keyword) { ... }
}3.2 Custom Route Constraints
public class SlugRouteConstraint : IRouteConstraint
{
public bool Match(HttpContext httpContext, IRouter route,
string routeKey, RouteValueDictionary values,
RouteDirection routeDirection)
{
if (values.TryGetValue(routeKey, out var value) && value is string slug)
{
return slug.All(c => char.IsLower(c) || char.IsDigit(c) || c == '-');
}
return false;
}
}
// Register the constraint
public void ConfigureServices(IServiceCollection services)
{
services.Configure<RouteOptions>(options =>
{
options.ConstraintMap.Add("slug", typeof(SlugRouteConstraint));
});
}4. Performance Optimization
4.1 Response Caching
[HttpGet]
[ResponseCache(Duration = 60, Location = ResponseCacheLocation.Client)]
public ActionResult<IEnumerable<Product>> Get() { ... }4.2 Output Caching (.NET 7+)
[HttpGet]
[OutputCache(Duration = 60)]
public ActionResult<IEnumerable<Product>> Get() { ... }4.3 Memory Caching
public class MyService
{
private readonly IDistributedCache _cache;
public MyService(IDistributedCache cache)
{
_cache = cache;
}
public async Task<string> GetCachedDataAsync(string key)
{
var cached = await _cache.GetStringAsync(key);
if (cached != null)
return cached;
// Fetch data and cache it
var data = await FetchDataFromDatabase();
await _cache.SetStringAsync(key, data, new DistributedCacheEntryOptions
{
AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(30)
});
return data;
}
}5. Error Handling and Logging
5.1 Global Exception Handling
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/error");
app.UseHsts();
}
}
// Error controller
[ApiController]
[Route("/error")]
public class ErrorController : ControllerBase
{
[HttpGet]
public ActionResult<ErrorResponse> GetError()
{
var exceptionHandlerPathFeature =
HttpContext.Features.Get<IExceptionHandlerPathFeature>();
return Problem(
detail: exceptionHandlerPathFeature?.Error.Message,
title: "An error occurred"
);
}
}5.2 Structured Logging
public class MyService
{
private readonly ILogger<MyService> _logger;
public MyService(ILogger<MyService> logger)
{
_logger = logger;
}
public void Process(int id, string name)
{
_logger.LogInformation("Processing item {Id} with name {Name}", id, name);
try
{
// Business logic
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to process item {Id}", id);
throw;
}
}
}6. Configuration Management
6.1 Strongly Typed Configuration
public class MySettings
{
public string ApiKey { get; set; }
public int Timeout { get; set; }
public DatabaseSettings Database { get; set; }
}
public class DatabaseSettings
{
public string ConnectionString { get; set; }
public string Provider { get; set; }
}
// Bind configuration
public void ConfigureServices(IServiceCollection services)
{
services.Configure<MySettings>(Configuration.GetSection("MySettings"));
}
// Use configuration
public class MyService
{
private readonly MySettings _settings;
public MyService(IOptions<MySettings> settings)
{
_settings = settings.Value;
}
}6.2 Environment-Specific Configuration
appsettings.json # Base configuration
appsettings.Development.json # Development environment
appsettings.Staging.json # Staging environment
appsettings.Production.json # Production environmentSummary
ASP.NET Core provides rich advanced features, including dependency injection, middleware, routing, caching, and logging. Mastering these advanced topics is essential for building high-quality enterprise applications.
Author: Lei Tao
Date: February 1, 2024