配置从基本选项 class 或接口 .NET Core 派生的所有选项
Configure all options derived from base option class or interface .NET Core
我在 appsettings.json 文件中有带变量的代码,所以我通过配置方法在 IServiceCollection 中注册了所有选项:
public static void Configure(IServiceCollection services, IConfiguration configuration, bool useHangfire = true)
{
services
.Configure<AuthSettings>(configuration.GetSection(AuthSettings.SectionName))
.Configure<CacheSettings>(configuration.GetSection(CacheSettings.SectionName))
..... and so on
我想创建一个基础(抽象)class 或接口,例如
public interface ISettings
{
public const string SectionName = "DefaultSettings";
}
public class AuthSettings: ISettings
{
public const string SectionName = "AuthSettings";
public int ConfirmCodeLength { get; set; }
public string AllowedChars { get; set; }
public TimeSpan ConfirmCodeExpiry { get; set; }
}
并像这样配置所有设置
foreach (var type in
Assembly.GetAssembly(typeof(ISettings)).GetTypes()
.Where(myType => myType.IsClass && !myType.IsAbstract && myType.IsSubclassOf(typeof(ISettings))))
{
var currentSettings = (ISettings)Activator.CreateInstance(type);
services.ConfigureOptions(currentSettings);
}
我已经对 hangfire 作业的注册做了同样的事情,但这个案例看起来有点不同。
不幸的是,这个版本不起作用,因为 currentSetting 应该实现 IConfigureOptions 但它没有。此外,我不确定此代码是否从 JSON 获取值。
有人做过这样的事吗?
因此,如果您有很多设置,您可以为所有设置创建基础 class,它具有定义部分名称的方法
public class BaseSettings
{
public virtual string SectionName => this.GetType().Name;
}
很多settings-classes喜欢这样
public class AuthSettings:BaseSettings
{
public int ConfirmCodeLength { get; set; }
public string AllowedChars { get; set; }
public TimeSpan ConfirmCodeExpiry { get; set; }
}
然后在 ServiceCollection 扩展 class set 方法中找到所有继承的 classes 并将其添加到 IServiceCollection
public static IServiceCollection AddAllOptions(this IServiceCollection services, IConfiguration configuration)
{
foreach (var type in
Assembly.GetAssembly(typeof(BaseSettings)).GetTypes()
.Where(myType => myType.IsClass && !myType.IsAbstract && myType.IsSubclassOf(typeof(BaseSettings))))
{
var configurationInstance = (BaseSettings)Activator.CreateInstance(type);
if (configurationInstance != null)
{
var configurationSection = configuration.GetSection(configurationInstance.SectionName);
var configureMethod = typeof(OptionsConfigurationServiceCollectionExtensions).GetMethods()
.Where(x => x.Name == "Configure")
.Single(m => m.GetParameters().Length == 2)
.MakeGenericMethod(type);
configureMethod.Invoke(null, new object[] { services, configurationSection });
}
}
return services;
}
你终于可以在你的StartUp中使用这个方法了class
service.AddAllOptions(configuration);
我在 appsettings.json 文件中有带变量的代码,所以我通过配置方法在 IServiceCollection 中注册了所有选项:
public static void Configure(IServiceCollection services, IConfiguration configuration, bool useHangfire = true)
{
services
.Configure<AuthSettings>(configuration.GetSection(AuthSettings.SectionName))
.Configure<CacheSettings>(configuration.GetSection(CacheSettings.SectionName))
..... and so on
我想创建一个基础(抽象)class 或接口,例如
public interface ISettings
{
public const string SectionName = "DefaultSettings";
}
public class AuthSettings: ISettings
{
public const string SectionName = "AuthSettings";
public int ConfirmCodeLength { get; set; }
public string AllowedChars { get; set; }
public TimeSpan ConfirmCodeExpiry { get; set; }
}
并像这样配置所有设置
foreach (var type in
Assembly.GetAssembly(typeof(ISettings)).GetTypes()
.Where(myType => myType.IsClass && !myType.IsAbstract && myType.IsSubclassOf(typeof(ISettings))))
{
var currentSettings = (ISettings)Activator.CreateInstance(type);
services.ConfigureOptions(currentSettings);
}
我已经对 hangfire 作业的注册做了同样的事情,但这个案例看起来有点不同。 不幸的是,这个版本不起作用,因为 currentSetting 应该实现 IConfigureOptions 但它没有。此外,我不确定此代码是否从 JSON 获取值。 有人做过这样的事吗?
因此,如果您有很多设置,您可以为所有设置创建基础 class,它具有定义部分名称的方法
public class BaseSettings
{
public virtual string SectionName => this.GetType().Name;
}
很多settings-classes喜欢这样
public class AuthSettings:BaseSettings
{
public int ConfirmCodeLength { get; set; }
public string AllowedChars { get; set; }
public TimeSpan ConfirmCodeExpiry { get; set; }
}
然后在 ServiceCollection 扩展 class set 方法中找到所有继承的 classes 并将其添加到 IServiceCollection
public static IServiceCollection AddAllOptions(this IServiceCollection services, IConfiguration configuration)
{
foreach (var type in
Assembly.GetAssembly(typeof(BaseSettings)).GetTypes()
.Where(myType => myType.IsClass && !myType.IsAbstract && myType.IsSubclassOf(typeof(BaseSettings))))
{
var configurationInstance = (BaseSettings)Activator.CreateInstance(type);
if (configurationInstance != null)
{
var configurationSection = configuration.GetSection(configurationInstance.SectionName);
var configureMethod = typeof(OptionsConfigurationServiceCollectionExtensions).GetMethods()
.Where(x => x.Name == "Configure")
.Single(m => m.GetParameters().Length == 2)
.MakeGenericMethod(type);
configureMethod.Invoke(null, new object[] { services, configurationSection });
}
}
return services;
}
你终于可以在你的StartUp中使用这个方法了class
service.AddAllOptions(configuration);