Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Arranging dotnet core app for 3-tiers with data access layer

My typical .NET 4.5X web application structure has a minimum of 3 tiers: a web project (a .NET web application), a domain/business logic project (a class library), and a data access project (a class library). The web project references the business layer, and the business layer references the data access layer.

I like this approach since my web project does not have a reference to the data access project (it must go through the domain/business logic layer first). My web project shouldn't have any access to the context or repository classes.

In the 3-tiered .net 4.5.X app, I declare the connection string in the web.config and give the name of the DbContext as the name attribute of the connection string.

In the new Dotnet Core paradigm, every example I see has the DbContext configured in the Startup.cs like this:

public void ConfigureServices(IServiceCollection services)
{
    // Add framework services.
    services.AddMvc();
    services.AddEntityFramework()
        .AddSqlServer()
        .AddDbContext<MyApplicationContext>("myconnectionstring  or reference to it");
}

By giving the startup a concrete class to use for the dbcontext, I must reference the data access project, where the dbcontext is defined. I would prefer to only reference the middle tier, and avoid the reference to the DAL.

My question is: how should I arrange my solution structure so that I can avoid adding a reference from my web project to my data access project?

Can I use an appsettings.json property?

Can I add my Entity configuration another way?

Is there something major I am missing about dot net core?

Thank you in advance.

like image 807
rictionaryFever Avatar asked Apr 25 '16 03:04

rictionaryFever


1 Answers

I found a solution using EF6 and Dotnet Core that I am fairly comfortable with.

It doesn't use the services.AddSqlServer() call for EF7, but rather uses an EF6 configuration and registers the DbContext in a Bootstrap class called at Startup.

public static class BootstrapConfig
{
    public static void RegisterApplicationServices(this IServiceCollection services, IConfigurationRoot configuration)
    {
        // DbContext
        services.AddScoped<DbContext>(x => new ApplicationContext(configuration["Data:ApplicationContext:ConnectionString"]));
    }
}

This is called from the Startup.cs in the WebLibrary project as

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

    services.RegisterApplicationServices(Configuration);
}

enter image description here

WebLibrary is the dot net core web application (contains controllers, is the startup project).

Business logic is the service layer, and is the middle tier between the web app and the data access project.

Data Access is where the dbContext and repository classes exist for actually doing a query.

The Model project holds POCOs and Enums, not smart objects but containers that are used across the application.

The Bootstrap project has a reference to both the business logic and data access projects so that it can register the services and repositories for the IOC container.

Check out the github repo for the example solution. One problem I still have, specific to my application is this:

Even though the web library does not have a reference to the data access project, I can still instantiate an ApplicationContext from one of the controllers. The whole point of separating these projects out was so I could make it impossible to get a db context directly in the web project. I'm not sure if that's related to the new solution structure in Core or if I'm including something I am unaware of.

like image 135
rictionaryFever Avatar answered Sep 21 '22 01:09

rictionaryFever