gpt4 book ai didi

c# - 如何从 C# Core 中的 DI 获取可用的 IOptions 列表?

转载 作者:太空宇宙 更新时间:2023-11-03 14:46:08 24 4
gpt4 key购买 nike

关注这篇文章:https://blog.bredvid.no/validating-configuration-in-asp-net-core-e9825bd15f10

我现在可以在服务需要时验证设置。我想做的是在 program.cs 中服务器启动时直接验证。

我不知道该怎么做?有没有办法获取注入(inject)到 DI 中的服务列表,然后验证类型是否可从 IOption 分配并注册?

以下是我如何将设置添加到 DI:

    //App settings
services.ConfigureAndValidate<AuthenticationSettings>(Configuration);
services.ConfigureAndValidate<SmtpSettings>(Configuration);

扩展代码:

public static class IServiceCollectionExtensions
{
public static IServiceCollection ConfigureAndValidate<T>(
this IServiceCollection serviceCollection,
IConfiguration config,
string section = null
) where T : class
{
var configType = typeof(T).Name;
if (string.IsNullOrEmpty(section)) {
section = configType;
}

return serviceCollection
.Configure<T>(config.GetSection(section))
.PostConfigure<T>(settings =>
{
var configErrors = settings.ValidationErrors().ToArray();
if (configErrors.Any())
{
var aggrErrors = string.Join(",", configErrors);
var count = configErrors.Length;
throw new ApplicationException($"Found {count} configuration error(s) in {configType}: {aggrErrors}");
}
});
}

private static IEnumerable<string> ValidationErrors(this object obj)
{
var context = new ValidationContext(obj, serviceProvider: null, items: null);
var results = new List<ValidationResult>();
Validator.TryValidateObject(obj, context, results, true);
foreach (var validationResult in results)
{
yield return validationResult.ErrorMessage;
}
}
}

这是我当前的启动器:

public class Program
{
public static async Task Main(string[] args)
{
var webHost = new WebHostBuilder()
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.ConfigureAppConfiguration((hostingContext, config) =>
{
config.AddEnvironmentVariables();

var env = hostingContext.HostingEnvironment;

config.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
})
.ConfigureLogging((hostingContext, logging) =>
{
logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
logging.AddConsole();
logging.AddDebug();
})
.UseStartup<Startup>()
.Build();

using (var scope = webHost.Services.CreateScope())
{
var services = scope.ServiceProvider;

/// <---- BEGIN / AN IDEA OF WHAT I WOULD LIKE TO DO ---->
/// <---- THIS CODE IS NOT WORKING ---->
var allServices = services.GetAllServices();
if (allServices != null)
{
foreach (var service in allServices )
{
if (service.ServiceType.IsAssignableFrom(IOptions))
{
services.GetRequiredService<service.ServiceType>()
}
}
}
/// <---- END ---->
}

await webHost.RunAsync();
}
}

如果您有任何建议,请在评论中告诉我。

感谢您的帮助。


编辑 1:感谢 Steven 的帮助,有了你的回答,它帮助我继续寻找答案,但仍然缺少一些东西。

现在,我所有的设置都继承自 ISettings,例如:

public class AuthenticationSettings : ISettings
{
[Required]
public string Issuer { get; set; }
[Required]
public string Audience { get; set; }
[Required]
public string SecretKey { get; set; }
[Required]
public int ExpirationDurationInDays { get; set; }
}

我像这样更新 Program.cs:

using Autofac;
using Autofac.Core;



var options = services.GetService<ILifetimeScope>()
.ComponentRegistry
.Registrations.SelectMany(e => e.Services)
.Select(s => s as TypedService)
.Where(s => s.ServiceType.IsGenericType && s.ServiceType.GetGenericTypeDefinition() == typeof(IConfigureOptions<>))
.Select(s => s.ServiceType.GetGenericArguments()[0])
.Where(s => typeof(ISettings).IsAssignableFrom(s))
.ToList();

所以现在我需要实例化选项中的每个选项并获取值。我还在努力。如果您有任何建议或解决方案,请告诉我:)

最佳答案

您可以通过迭代 IServiceCollection 实例来获取已配置选项类型的列表:

var configuredOptionTypes =
from descriptor in services
let serviceType = descriptor.ServiceType
where serviceType.IsGenericType
where serviceType.GetGenericTypeDefinition() == typeof(IConfigureNamedOptions<>)
let optionType = serviceType.GetGenericArguments()[0]
select optionType;

关于c# - 如何从 C# Core 中的 DI 获取可用的 IOptions 列表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54127217/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com