.NET开发基础知识21-30
21. 自定义配置源
-
技术知识:除了默认的配置源(如
appsettings.json
),你可以自定义配置源,从不同的数据源(如数据库、网络服务等)加载配置信息,以满足多样化的配置需求。 -
案例:
CustomConfigSource.cs
using Microsoft.Extensions.Configuration;
using System;
public class CustomConfigSource : IConfigurationSource
{
public IConfigurationProvider Build(IConfigurationBuilder builder)
{
return new CustomConfigProvider();
}
}
public class CustomConfigProvider : ConfigurationProvider
{
public override void Load()
{
// 模拟从自定义数据源加载配置
Data["CustomSetting"] = "CustomValue";
}
}
Program.cs
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
var builder = WebApplication.CreateBuilder(args);
// 添加自定义配置源
builder.Configuration.Add(new CustomConfigSource());
var app = builder.Build();
var config = app.Services.GetRequiredService<IConfiguration>();
var customSetting = config["CustomSetting"];
Console.WriteLine($"Custom Setting Value: {customSetting}");
app.Run();
22. 配置绑定到对象集合
-
技术知识:可以将配置文件中的数组或列表数据绑定到对象集合,方便处理批量配置信息。
-
案例:
Program.cs
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System.Collections.Generic;
public class MyItem
{
public string Name { get; set; }
public int Value { get; set; }
}
var builder = WebApplication.CreateBuilder(args);
var myItems = new List<MyItem>();
builder.Configuration.Bind("MyItems", myItems);
var app = builder.Build();
foreach (var item in myItems)
{
Console.WriteLine($"Name: {item.Name}, Value: {item.Value}");
}
app.Run();
appsettings.json
{
"MyItems": [
{
"Name": "Item1",
"Value": 10
},
{
"Name": "Item2",
"Value": 20
}
]
}
23. 中间件委托
- 技术知识:中间件可以使用委托来定义,这种方式更加灵活,可以在不创建类的情况下实现中间件逻辑。
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Hosting;
using System.Threading.Tasks;
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
// 使用中间件委托
app.Use(async (context, next) =>
{
Console.WriteLine("Before processing request in delegate middleware");
await next();
Console.WriteLine("After processing request in delegate middleware");
});
app.Run(async context =>
{
await context.Response.WriteAsync("Hello from application");
});
app.Run();
24. 控制器模型绑定自定义
-
技术知识:可以自定义控制器的模型绑定规则,处理特殊的数据格式或复杂的对象绑定。
-
案例:
CustomModelBinder.cs
using Microsoft.AspNetCore.Mvc.ModelBinding;
using System.Threading.Tasks;
public class CustomModelBinder : IModelBinder
{
public Task BindModelAsync(ModelBindingContext bindingContext)
{
var valueProviderResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
if (valueProviderResult != ValueProviderResult.None)
{
var value = valueProviderResult.FirstValue;
if (!string.IsNullOrEmpty(value))
{
// 自定义绑定逻辑
bindingContext.Result = ModelBindingResult.Success($"Custom: {value}");
}
}
return Task.CompletedTask;
}
}
MyController.cs
using Microsoft.AspNetCore.Mvc;
[ApiController]
[Route("[controller]")]
public class MyController : ControllerBase
{
[HttpGet]
public IActionResult Get([ModelBinder(typeof(CustomModelBinder))] string input)
{
return Ok(input);
}
}
Program.cs
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
var app = builder.Build();
app.UseRouting();
app.MapControllers();
app.Run();
25. 基于策略的授权
-
技术知识:基于策略的授权允许你定义复杂的授权规则,将多个授权条件组合成一个策略,方便管理和复用。
MyController.cs
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
[ApiController]
[Route("[controller]")]
public class MyController : ControllerBase
{
[HttpGet]
[Authorize(Policy = "AdminPolicy")]
public IActionResult Get()
{
return Ok("Authorized as Admin");
}
}
Program.cs
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.IdentityModel.Tokens;
using System.Text;
var builder = WebApplication.CreateBuilder(args);
// 配置 JWT 认证
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = "YourIssuer",
ValidAudience = "YourAudience",
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("YourSecretKey"))
};
});
// 定义授权策略
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("AdminPolicy", policy =>
policy.RequireRole("Admin"));
});
builder.Services.AddControllers();
var app = builder.Build();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.Run();
26. 应用程序配置重载
- 技术知识:在应用程序运行过程中,可以手动触发配置的重载,以加载最新的配置信息,而无需重启应用。
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System;
using System.Threading;
var builder = WebApplication.CreateBuilder(args);
var config = builder.Configuration;
var mySetting = config["MySetting"];
Console.WriteLine($"Initial MySetting value: {mySetting}");
var reloadToken = config.GetReloadToken();
var cancellationTokenSource = new CancellationTokenSource();
// 模拟定时重载配置
new Thread(() =>
{
while (!cancellationTokenSource.Token.IsCancellationRequested)
{
Thread.Sleep(5000);
reloadToken = config.Reload();
mySetting = config["MySetting"];
Console.WriteLine($"Reloaded MySetting value: {mySetting}");
}
}).Start();
var app = builder.Build();
app.Run();
27. 路由约束
- 技术知识:路由约束可以对路由参数进行验证,确保只有符合特定条件的参数才能匹配路由,提高路由的准确性。
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.Hosting;
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapGet("/products/{id:int}", async context =>
{
var id = Convert.ToInt32(context.Request.RouteValues["id"]);
await context.Response.WriteAsync($"Product ID: {id}");
});
});
app.Run();
28. 依赖注入服务替换
- 技术知识:在某些情况下,你可能需要替换已注册的服务实现,以满足不同的需求或进行测试。
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
// 定义服务接口
public interface IMyService
{
void DoSomething();
}
// 定义默认服务实现
public class MyDefaultService : IMyService
{
public void DoSomething()
{
Console.WriteLine("Default service is doing something");
}
}
// 定义替换服务实现
public class MyReplacementService : IMyService
{
public void DoSomething()
{
Console.WriteLine("Replacement service is doing something");
}
}
var builder = WebApplication.CreateBuilder(args);
// 注册默认服务
builder.Services.AddTransient<IMyService, MyDefaultService>();
// 替换服务实现
builder.Services.AddTransient<IMyService, MyReplacementService>();
var app = builder.Build();
var service = app.Services.GetRequiredService<IMyService>();
service.DoSomething();
app.Run();
10. 配置变更通知
- 技术知识:当配置发生变更时,可以通过监听配置变更通知来执行相应的操作,如重新加载缓存、更新服务状态等。
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
var builder = WebApplication.CreateBuilder(args);
var config = builder.Configuration;
var mySetting = config["MySetting"];
Console.WriteLine($"Initial MySetting value: {mySetting}");
var changeToken = config.GetReloadToken();
changeToken.RegisterChangeCallback(state =>
{
var newConfig = (IConfiguration)state;
var newMySetting = newConfig["MySetting"];
Console.WriteLine($"MySetting value has changed to: {newMySetting}");
// 重新获取变更通知令牌
changeToken = newConfig.GetReloadToken();
changeToken.RegisterChangeCallback(state, newConfig);
}, config);
var app = builder.Build();
app.Run();