Separation of concerns and n-tiered architecture in ASP.NET 5/ASP.NET Core 1

asp.net asp.net-core asp.net-core-mvc dependency-injection entity-framework-core

Question

I'm struggling to find a graceful way to keep my DAL layer separate to my MVC/UI layer in ASP.NET 5 thanks to the new built in Dependency Injection which I want to use.

For example I have an ASP.NET 5 project, a Business Layer project and a Data Access Project where I have various Entity Framework code such as entities and contexts. in ASP.NET 5 to get the context set up and targeting a database the main documentation is suggesting I do something like this in my StartUp.cs class

services.AddEntityFramework()
    .AddSqlServer()
    .AddDbContext<BookContext>(options =>
    {
        options.UseSqlServer(Configuration.Get("Data:ConnectionString"));
    });

This means that I now have to reference my DAL in what is basically my UI layer, something which for years has always been bad practice according to the various experts and blog posts around.

One way I have worked around this is to create two new projects, one is a CompositeRoot project which contains factory classes to generate my business classes which then access the DAL and also a Utilities project with a Configuration class in which has a ConnectionString property which I can pass into my Context, I then use the built in DI to wire everything up and avoid referencing my DAL in my UI layer. But I've come across issues with the latest version of Entity Framework (beta 7) as it now doesn't seem possible to specify a connection string either in the constructor of the context or in the overrideable OnConfiguration method. Plus, all the documentation so far doesn't seem to care about this mixing of concerns at all. Is this just the way we do things now? Trust that developers won't do 'bad' things like reference DAL classes in the UI directly? Or is there a pattern people are employing to keep things SOLID with this new built in DI/configuration for ASP.NET 5?

Popular Answer

If you ask 10 civil architects to build you a bridge, you’ll end up having 10 different architectures. Not one will be the same and not one will be better than the other.

Regardless of how many best practices and design patterns they apply, each architect will justify their idea. Some will be overzealous while others will keep it simple and get the job done. Amongst other things, budget, delivery dates and craftsmanship will have a direct impact on type of architecture you decide.

The same rule applies with software architects.

I’ve seen my fair share of architects having the best intentions in the world only to realize that the UI layer has a dependency on the DAL. Perhaps the reasoning behind this is that:

  • They haven't thought of it
  • They don't really care about it
  • It facilitates DI since you see every layer which in turn makes it easy to map Interfaces to their Implementation.

Back in MVC 5, I had the following layers:

-Contoso.Core (Class Library)
-Contoso.Data (Class Library)
-Contoso.Service (Class Library)
-Contoso.Web (asp.net MVC 5)
-Contoso.Web.Configuration (Class Library)

The Web.Configuration layer had a dependency on Core, Data and Service. This layer is where I would configure my DI stuff.

The Web layer did not have a dependency on the Data layer and to get stuff started, I was using the Bootstrapper Nuget Package.

Perhaps you could achieve something similar with ASP.NET 5

I’d love for Microsoft (or anyone) to create a working project template that is more geared towards enterprise level samples using a decoupled approach or even something like an Onion Architecture sample.

In the end, whatever I consider like a reasonable decoupled architecture might be too much for some while not enough for others...

Feel free to share your findings as I’m curious to know how you’ve managed to make it work.



Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Is this KB legal? Yes, learn why
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Is this KB legal? Yes, learn why