Eutherpy
Eutherpy

Reputation: 4571

Get instance of singleton service in startup

I have the following situation:

startup.cs

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

So, in order to create my context I need the connection string which this configurationManager provides to me. However, I would still like to keep the ConfigurationManager as a service.

Is there a way to do this without explicitly instantiating the configurationManager or is it perhaps even fine to leave it like this?

Upvotes: 6

Views: 24748

Answers (3)

panoskarajohn
panoskarajohn

Reputation: 1988

Also you can do sth similar to this. I am not familiar with what you do with your configuration manager to provide a precise answer.

Basically you can do a pre-config inside your Program.cs.

Build your configuration here. As you can see i am passing 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));
}

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

Upvotes: 1

M&#233;toule
M&#233;toule

Reputation: 14472

It's possible to access the IServiceProvider while building the context:

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

However, here your best options might be to read the Iconfiguration injected in Startup.cs:

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"));
        });
    }
}

Upvotes: 3

dunnel123
dunnel123

Reputation: 384

You can use the service provider to get instances of services:

Build the services provider - var provider = services.BuildServiceProvider();

Get specific service -

provider.GetService<T>();

Although a better option would be to use the IConfiguration .NET Core provides - https://learn.microsoft.com/en-us/aspnet/core/fundamentals/configuration/?view=aspnetcore-3.1

Using this method you can set IConfiguration to parse your config settings in the Startup method. From there you can then inject these settings into the required classes.

Upvotes: 4

Related Questions