5

Just started using .Net Core and facing passing connection string information to Context console project.

I have 4 projects, created using .Net Core.

  1. MVC
  2. Service Layer
  3. Domain Layer
  4. Data Layer

In MVC project, I have Startup.cs file where i am reading appsettings.json file

    public void ConfigureServices(IServiceCollection services)
        {
            // Add framework services.
            services.AddApplicationInsightsTelemetry(Configuration);

            services.AddMvc();

            // Add appsettings
            services.Configure<AppSettingsConfig>(Configuration.GetSection("AppSettings")); 
}


public Startup(IHostingEnvironment env)
    {
        var builder = new ConfigurationBuilder()
            .SetBasePath(env.ContentRootPath)
            .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
            .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
            .AddEnvironmentVariables();

        if (env.IsDevelopment())
        {
            // This will push telemetry data through Application Insights pipeline faster, allowing you to view results immediately.
            builder.AddApplicationInsightsSettings(developerMode: true);
        }
        Configuration = builder.Build();
    }

In my 4th project (Data Layer), which Console Project and having following DBContext class. This project doesn't have Startup.cs as i MVC project having. Not created by default by VS 2015.

public class MyDWContext : DbContext
{
    public MyDWContext() : base ()
    {

    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);


    }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {            
        optionsBuilder.UseSqlServer(@"Data Source=localhost;Initial Catalog=MyDW; Persist Security Info = False; User ID = TempUser; Password = Temp123");
    }

    public DbSet<User> Users { get; set; }
    public DbSet<Class> Classs { get; set; }
}

I have been to other post as well but i believe its created using older version or RC version. So some time i cannot find correct object or .Net classes.

As i have connection string is in MVC project, how can i use connection string during my MVC call to Data layer.

I have Web.API (Core) project as well and that having own connection string (different user configuration in connection string which having only read access). How can i use Web2.API connection string when i am making call from Web2.API project.

0

1 Answer 1

5

Instead of passing connection string to DbContext, configuring DbContext in Startup.cs(if possible) is better way. See official docs to understand how to configure DbContext and use it via Dependency Injection.

EDIT : Below code is not good way

However, if you want to pass connection string to DbContext you can use options pattern.

Here is an example how to pass connection string with options pattern:

First you need an options class which accessible from Data Layer and MVC layer

public class ConnectionStringOption
{
     public string ConStr { get ; set; }
}

Then set option value

public void ConfigureServices(IServiceCollection services)
{
     services.AddOptions();
     services.Configure<ConnectionStringOption>(options=>
     {
         // set connection string from configuration  
         options.ConStr = Configuration.GetConnectionString("Default");
     });      
}

appsetting.json

{
  "ConnectionStrings": {
    "Default": "<your connection string>"
  }
}

Finally DbContext

    private readonly IOptions<ConnectionStringOption> _conStrOptions;

    protected YourDbContext()
    {
    }
    public YourDbContext(IOptions<ConnectionStringOption> conStrOptions, DbContextOptions options) 
        : base(options)
    {
        _conStrOptions= conStrOptions;
    }

Edit for another way

Using Static Service Locator may be a solution:

Create a DependencyResolver in Data Layer

public static class DependencyResolver
{
    private static IServiceProvider _provider;
    public static IServiceProvider ServiceProvider
    {
        get
        {
            return _provider;
        }
        set
        {
            if(_provider == null)
            {
                _provider = value;
            }
        }
    }
}

In ConfigureServices method

    public void ConfigureServices(IServiceCollection services)
    {
        // other stuff
        services.AddOptions();
        services.Configure<ConnectionStringOption>(options=>
        {
            // set connection string from configuration  
            options.ConStr = Configuration.GetConnectionString("Default");
        }); 
        DependencyResolver.ServiceProvider = services.BuildServiceProvider();
    }

And finally get option:

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{            
    var conStr = DependencyResolver.ServiceLocator.GetService<IOptions<ConnectionStringOption>>().Value.ConStr;
    optionsBuilder.UseSqlServer();
}

Final Edit for previous stupid way

public static class ConnectionStringGetter
{
    public static string ConStr{get;set;}
}

public Startup(IHostingEnvironment env)
{
    //...
    Configuration = builder.Build();
    ConnectionStringGetter.ConStr =  Configuration.GetConnectionString("Default");
}

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{            
    optionsBuilder.UseSqlServer(ConnectionStringGetter.ConStr);
}
Sign up to request clarification or add additional context in comments.

14 Comments

Don't mind second way, it seems it is not valid way.
Thanks for reply, But can i use _conStrOptions property into OnConfiguring function at Data Layer. <code> protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) {}</code>
Yes you can, but in this case you should use OnConfiguring to configure DbContext and your DbContext will depend on Database(such as SqlServer) provider. I think it is not good practice.
_ConStrOptions is null during following call. optionsBuilder.UseSqlServer(_conStrOptions.Value.ConStr);
Did you configure DbContext in Startup.cs like : services.AddDbContext<YourDbContextContext>();?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.