将配置绑定到.NET Core 2.0中的对象图
我正在制作.NET Core 2.0应用程序,我需要对其进行配置。 我正在查看此文档 ,似乎在.NET Core 1.0中您可以这样做:
var appConfig = new AppSettings(); config.GetSection("App").Bind(appConfig);
在.NET Core 1.1中,您可以:
var appConfig = config.GetSection("App").Get();
但在.NET Core 2.0中既不存在Bind也不存在。 实现这一目标的新方法是什么?
谢谢,
玩笑
你仍然可以做这两件事。 由于您处于控制台应用程序中,并且因此可能不使用ASP.NET Core元数据包,因此您需要确保具有正确的依赖项。
要将配置绑定到对象,您需要Microsoft.Extensions.Configuration.Binder
包。 然后,两种解决方案都应该正常工作。
顺便说一句。 即使您在控制台应用程序中,您仍然可以使用ASP.NET Core附带的dependency injection容器。 我个人发现设置起来非常简单,所以如果你仍然可以修改你的应用程序来使用它,那么它可能是值得的。 设置将如下所示:
var configuration = new ConfigurationBuilder() .AddJsonFile("config.json", optional: false) .Build(); var services = new ServiceCollection(); services.AddOptions(); // add your services here services.AddTransient(); services.AddTransient(); // configure options services.Configure(configuration.GetSection("App")); // build service provider var serviceProvider = services.BuildServiceProvider(); // retrieve main application instance and run the program var program = serviceProvider.GetService(); program.Run();
然后,所有注册的服务都可以像在ASP.NET Core中一样使用依赖项。 然后,为了使用您的配置,您可以像IOptions
一样注入IOptions
类型。
直到今天我终于明白了,我仍然遇到了这个问题。
代码运行没有问题,但所有属性仍然为null,即使在绑定之后。 我这样做:
public class AppSettings { public string MyProperty }
事实certificate你必须这样做:
public class AppSettings { public string MyProperty { get; set; } }
它只适用于您的类具有属性而不是字段。 这对我来说并不清楚。
如果要在Startup
期间注册配置,请将此添加到Startup.cs
:
services.Configure(Configuration.GetSection("App"));
然后,您可以通过注入IOptions<>
的实例来访问它:
private readonly AppSettings _appSettings; public MyClass(IOptions appSettings) { _appSettings = appSettings.Value; }
为了更简单的配置,我创建了一个帮助程序类,它扫描配置对象以获取嵌套配置,然后尝试在已加载的程序集中查找相应的类,并使用给定的配置对其进行初始化。
appsettings.json:
{ "MyState": { "SomeSimpleValue": "Hello World", "MyTimeSpan": "00:15:00" } }
MyStateOptions.cs
// Class has same name as in appsettings.json with Options suffix. public class MyStateOptions { // Properties must be deserializable from string // or a class with a default constructor that has // only properties that are deserializable from string. public string SomeSimpleValue { get; set; } public DateTime MyTimeSpan { get; set; } }
Startup.cs
public class Startup { public IConfigurationRoot Configuration { get; } public Startup(IHostingEnvironment env) { // Create configuration as you need it... var builder = new ConfigurationBuilder() .SetBasePath(env.ContentRootPath) .AddJsonFile(...) .AddEnvironmentVariables(); // Save configuration in property to access it later. Configuration = builder.Build(); } public void ConfigureServices(IServiceCollection services) { // Register all your desired services... services.AddMvc(options => ...); // Call our helper method services.RegisterOptions(Configuration); } }
HelperClass.cs
public static class IServiceCollectionExtensions { public static void RegisterOptions( this IServiceCollection services, IConfiguration configuration) { // Create all options from the given configuration. var options = OptionsHelper.CreateOptions(configuration); foreach (var option in options) { // We get back Options : IOptions var interfaces = option.GetType().GetInterfaces(); foreach (var type in interfaces) { // Register options IServiceCollection services.AddSingleton(type, option); } } } }
OptionsHelper.cs
public static class OptionsHelper { public static IEnumerable
完成所有这些工作之后,您可以在服务集合中拥有一个服务,该服务在其构造函数中需要一个IOptions
并且您将获得它而无需显式配置您拥有的每个选项。 只需使用所需的服务和选项实例创建一个新项目。 将项目添加到主项目,并将所需的配置添加到appsettings.json。
ExampleService.cs
public class MyExampleService { private readonly MyStateOptions _options; public MyExampleService(IOptions options) { _options = options?.Value ?? throw new ArgumentNullException(nameof(options)); } }