Konrad
Konrad

Reputation: 7208

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.

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.

Upvotes: 11

Views: 2063

Answers (2)

wheeler
wheeler

Reputation: 687

My approach/opinion to this topic:

Use a connection String in every top layer application using your DbContext like API/Backend/Frontend because they could run on different servers. So they should have their own settings file.

To handle Migrations from the Library without connection string you can use the following approach:

cd /projectWithContextImpl

dotnet ef -s "../projectWithConnString/" migrations list -c NameOfContext

I hope this somewhat answers your question.

Upvotes: 0

Nkosi
Nkosi

Reputation: 247153

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.

Upvotes: 3

Related Questions