我正在编写一个通用扩展方法,例如我的 .net aspire 项目中的 AddCors()
ServiceDefaults
以避免为每个服务重写。然而,属性可能因服务而异。以下是到目前为止我的代码:
public static class CorsExtensions
{
/**
* appsettings.json configuration
*
* CorsPolicy:{
* "PolicyName": "",
* "AllowedHosts": "*",
* "AllowedOrigins": "http://localhost:4200",
* "AllowedHeaders": "content-type",
* "AllowedMethods": "GET,POST,PUT,DELETE"
* }
*/
public static IServiceCollection ConfigureCors<T>(this IServiceCollection services) where T: class
{
var configuration = services.BuildServiceProvider().GetService<IConfiguration>();
var corsPolicy = services.Configure<T>(configuration!.GetSection("CorsPolicy"));
services.AddCors(options =>
{
options.AddPolicy(name: corsPolicy.PolicyName,
policy => policy.WithOrigins(corsPolicy.AllowedOrigins)
.AllowCredentials()
.WithHeaders(corsPolicy.AllowedHeaders)
.WithMethods(corsPolicy.AllowedMethods)
);
});
return services;
}
public static WebApplication AddCorsMiddleware<T>(this WebApplication app)
{
app.UseCors(T.PolicyName);
return app;
}
}
在服务A中,我尝试如下消费:
builder.Services.ConfigureCors<CorsPolicy>();
public class CorsPolicy
{
public string PolicyName { get; set; }
public string AllowedHosts { get; set; }
public string AllowedMethods { get; set; }
public string AllowedHeaders { get; set; }
public string AllowedOrigins { get; set; }
}
如前所述,属性可能因服务而异,模型是在服务项目中声明的。
如何编写扩展方法来动态读取属性并进行相应配置。
您不能执行 T.PolicyName。 T 是一种类型,而不是对象。
如果我正确理解了这个问题,您可以创建一个接口并让每个策略来实现它,然后您可以将接口与相应的类进行类型匹配:
public class MyPolicy: ICorsPolicy
{
public string PolicyName { get; set; }
public string AllowedHosts { get; set; }
public string AllowedMethods { get; set; }
public string AllowedHeaders { get; set; }
public string AllowedOrigins { get; set; }
}
public interface ICorsPolicy {
public string PolicyName { get; set; }
...
}
...
public static WebApplication AddCorsMiddleware(this WebApplication app, ICorsPolicy policy)
{
if (policy is CorsPolicy corsPolicy) {
...
}
...
return app;
}
ConfigureCors 中相同。
当然你也可以做一个工厂并相应地构造对象。