运行`serviceProvider.GetService <application>();`时,.Net core 2.0控制台程序得到null值。

时间:2017-08-28 22:11:06

标签: c# .net .net-core

以下.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());
            }
        }
    }
}

1 个答案:

答案 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());
            }
        }
    }
}