Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ways to manage configuration in project with multiple tiers

ASP.NET Core project template comes with appsettings.json and appsettings.Development.json and it is added by default in CreateDefaultBuilder.

Because the project with DbContext is separate from my ASP.NET Core project (MyProject.Data) I am required to implement IDesignTimeDbContextFactory for my context in order for commands like Add-Migration and Update-Database to work. I don't want to hardcode my connection string for my IDesignTimeDbContextFactory but re-use the config in both projects.

I have few solutions for it but I want to know what's the most reasonable based on your experiences and opinions.

  • Implement IDesignTimeDbContextFactory in my ASP.NET Core (UI layer) project.
  • Implement IDesignTimeDbContextFactory in my MyProject.Data project, and move appsettings.json to some root directory, or configuration (located at root) directory shared between projects.
  • Create separate configuration file for database like database.json put it alongside my .sln file.

How should I share this?

EDIT:

There's similar question and answer here: ConnectionString from appsettings.json in Data Tier with Entity Framework Core but it doesn't answer my question. It doesn't say anything about data tier at all. I don't want to re-use logic for adding db context. I want to re-use connection string in two projects to avoid duplicating connection strings.

like image 875
Konrad Avatar asked Jun 07 '18 13:06

Konrad


1 Answers

While is it usually advised to have configuration in a central location, there is nothing restricting individual projects from managing their own configuration.

In the following example the connection string information is stored in an external datasettings.json file

{
  "ConnectionStrings": {
    "DefaultConnection": "connection string here"
  }
}

A simple example of a self contained setup extension for the layer could look like

public static class MyServiceCollectionExtensions {
    public static IServiceCollection AddMyDataLayer(this IServiceCollection services, string name = "DefaultConnection") {
        var builder = new ConfigurationBuilder()
            .SetBasePath(Directory.GetCurrentDirectory())
            .AddJsonFile("datasettings.json"); //<<< just an example

        var connectionStringConfig = builder.Build();

        services
            .AddEntityFrameworkSqlServer()
            .AddDbContext<YourDbContext>((serviceProvider, options) =>
                options
                    .UseSqlServer(connectionStringConfig.GetConnectionString(name))
            );
         return services;
    }
}

And added in Startup

using my.data.layer;

//...

public void ConfigureServices(IServiceCollection services) {

    //...

    services.AddMyDataLayer();

    //...
}

The data layer in this case manages its own configuration. Its settings file external to the application settings.

There is room for expansion as additional options could be managed locally as well and works well for drop-in turn key plug-in solutions for example.

The module nature of Configuration in ASP.NET Core allows for such flexibilities.

like image 83
Nkosi Avatar answered Nov 09 '22 23:11

Nkosi