以下.Net core 2.0控制台应用程序在运行serviceProvider.GetService<Application>();
时获得空值?
class Program
{
static void Main(string[] args)
{
var services = new ServiceCollection();
ConfigureServices(services);
var serviceProvider = services.BuildServiceProvider();
var app = serviceProvider.GetService<Application>(); // Got null value
Task.Run(() => app.Run()).Wait();
}
private static void ConfigureServices(IServiceCollection services)
{
ILoggerFactory loggerFactory = new LoggerFactory()
.AddConsole()
.AddDebug();
services.AddSingleton(loggerFactory); // Add first my already configured instance
services.AddLogging(); // Allow ILogger<T>
IConfigurationRoot configuration = GetConfiguration();
services.AddSingleton<IConfigurationRoot>(configuration);
// Support typed Options
services.AddOptions();
services.Configure<MyOptions>(configuration.GetSection("MyOptions")); // Error!
services.AddTransient<Application>();
}
private static IConfigurationRoot GetConfiguration()
{
return new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()).AddXmlFile("App.config", optional: true).Build();
}
public class MyOptions
{
public string Name { get; set; }
}
public class Application
{
ILogger _logger;
MyOptions _settings;
public Application(ILogger<Application> logger, IOptions<MyOptions> settings)
{
_logger = logger;
_settings = settings.Value;
}
public async Task Run()
{
try
{
_logger.LogInformation($"This is a console application for {_settings.Name}");
}
catch (Exception ex)
{
_logger.LogError(ex.ToString());
}
}
}
}
答案 0 :(得分:3)
我觉得它看起来不错,你只需要为你的选择提供一个单身。
var options = new MyOptions();
configuration.GetSection("MyOptions").Bind(options);
services.AddSingleton<MyOptions>(options);
然后,将您的应用转移到使用该单身人士。
public Application(ILogger<Application> logger, MyOptions settings)
编辑:IOptions模式怎么样?
似乎有人建议您在导入1.0.0-rc2-final版本的Microsoft.Extensions.Options.ConfigurationExtensions时可以使用该语法,但这也会级联到其他引用中。可能不值得它只是后期绑定选项类。
所有工作(较少的IOptions)
如果这是一个好方法,那么该部分中还有一些其他代码不起作用。清理下面的版本。希望有所帮助。
class Program {
static void Main(string[] args) {
var services = new ServiceCollection();
ConfigureServices(services);
var serviceProvider = services.BuildServiceProvider();
var app = serviceProvider.GetService<Application>(); // Got null value
Task.Run(() => app.Run()).Wait();
}
private static void ConfigureServices(IServiceCollection services) {
ILoggerFactory loggerFactory = new LoggerFactory()
.AddConsole() // Error!
.AddDebug();
services.AddSingleton(loggerFactory); // Add first my already configured instance
services.AddLogging(); // Allow ILogger<T>
IConfigurationRoot configuration = GetConfiguration();
services.AddSingleton<IConfigurationRoot>(configuration);
// Support typed Options
var myOptions = new MyOptions();
configuration.GetSection("MyOptions").Bind(myOptions);
services.AddSingleton<MyOptions>(myOptions);
services.AddTransient<Application>();
}
private static IConfigurationRoot GetConfiguration() {
return new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()).AddXmlFile("App.config", optional: true).Build();
}
public class MyOptions {
public string Name { get; set; }
}
public class Application {
ILogger _logger;
MyOptions _settings;
public Application(ILogger<Application> logger, MyOptions settings) {
_logger = logger;
_settings = settings;
}
public async Task Run() {
try {
_logger.LogInformation($"This is a console application for {_settings.Name}");
} catch (Exception ex) {
_logger.LogError(ex.ToString());
}
}
}
}