【问题标题】:Get instance of singleton service in startup在启动时获取单例服务的实例
【发布时间】:2019-12-13 13:42:19
【问题描述】:

我有以下情况:

startup.cs

services.AddSingleton<IConfigurationManager, ConfigurationManager>();
ConfigurationManager configurationManager = new ConfigurationManager();
services.AddDbContext<MyContext>(options => 
    options.UseSqlServer(configurationManager.DatabaseConnectionString));

所以,为了创建我的上下文,我需要 configurationManager 提供给我的连接字符串。但是,我仍然希望将ConfigurationManager 保留为服务。

有没有办法在不显式实例化configurationManager 的情况下做到这一点,或者像这样离开它甚至可以吗?

【问题讨论】:

  • 使用 IConfiguration 注入到 ASP.NET Core 中的 Startup 方法中

标签: c# asp.net-core dependency-injection entity-framework-core dbcontext


【解决方案1】:

您可以使用服务提供者来获取服务实例:

构建服务提供者 - var provider = services.BuildServiceProvider();

获取特定服务-

provider.GetService&lt;T&gt;();

虽然更好的选择是使用 .NET Core 提供的 IConfiguration - https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/?view=aspnetcore-3.1

使用此方法,您可以设置 IConfiguration 以解析 Startup 方法中的配置设置。然后,您可以从那里将这些设置注入所需的类。

【讨论】:

  • 服务定位是最好的方式吗?
  • 不,我会一直走 IConfiguration 路线,我假设这个问题是不可行的,所以我将其附加到我的答案中
  • 但是,这个调用(GetService 或 GetRequiredService)会导致类重新生成,即使它是用 AddSingleton 添加的
【解决方案2】:

在构建上下文时可以访问IServiceProvider

services.AddDbContext<MyContext>((serviceProvider, options) =>
{
    var configManager = serviceProvider.GetService<IConfigurationManager>();
    options.UseSqlServer(configManager.DatabaseConnectionString);
});

但是,在这里您最好的选择可能是阅读Startup.cs 中注入的Iconfiguration

public class Startup
{
    public IConfiguration Configuration { get; }
    public IHostingEnvironment HostingEnvironment { get; }

    public Startup(IConfiguration configuration, IHostingEnvironment env)
    {
        Configuration = configuration;
        HostingEnvironment = env;
    }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddDbContext<MyContext>(options =>
        {
            options.UseSqlServer(Configuration.GetConnectionString("MyContext"));
        });
    }
}

【讨论】:

    【解决方案3】:

    你也可以做类似的事情。 我不熟悉您如何使用配置管理器来提供准确的答案。

    基本上您可以在 Program.cs 中进行预配置。

    在此处构建您的配置。如您所见,我正在传递IConfigurationBuilder

    Program.cs
    
     public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration(AddDbConfiguration)
            .UseStartup<Startup>();
    
    
    private static void AddDbConfiguration(WebHostBuilderContext context, IConfigurationBuilder builder)
    {
        var configuration = builder.Build(); // you could instantiate you Configuration manager here and append to the configuration.
        var connectionString = configuration.GetConnectionString("Database");
        builder.AddDemoDbProvider(options => options.UseSqlServer(connectionString));
    }
    

    来源:https://medium.com/@dneimke/custom-configuration-in-net-core-2-193ff6f02046

    【讨论】:

    • 这是一个不同的场景:在提供的示例中,目标是加载存储在数据库中的配置。 ASP.NET Core 应用程序无法访问生成的数据库。
    • @Métoule 你是对的。当然,他可以轻松地修改代码以适应他的解决方案。我使用的代码与我引用的源代码中的代码相同。这就是我的配置方式。我觉得它非常灵活。他还可以在 Program 中实例化以构建更好的 IConfiguration。这已经在 asp.net 等的 DI 中了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-05-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-15
    • 2023-03-20
    相关资源
    最近更新 更多