Design – How to Separate Business Logic Layer from MVC

Architecturebusiness-logicdesignmvc

We are currently refactoring our controller methods in ASP.NET MVC application.

At the beginning we've separated data access layer (our goal was to remove LINQ from controllers entirely). Now we are thinking about another step – how to create a business logic layer to reduce number of lines and logic in controller. Currently we have something like this:

public ActionResult CustomerProjects(some parameters)
{
    var collectionOfSomeType = this.CustomerRepository.GetSomeData();
    var anothercollection = this.ProjectsRepository.GetAnotherData(collectionOfSomeType);

    var viewModel = CreateSomeViewModel(anotherCollection);

    return View("Index", viewModel);
}

Of course it's just an example with four lines of code. We have some methods which are bigger (but still IMO not so bad). We injected our helper classes through IoC container, more complex logic sits there. But now we'd like to remove even that parts.

Is it worth our time to create another layer which would be our 'last gate' before controllers? The final result would be:

public ActionResult CustomerProjects(some parameters)
{
    var viewModel = someSource.PrepareCustomerProjectsViewModel(params);

    return View("Index", viewModel);
}

What do you think?

Best Answer

For me there is no question to be answered here, you should always strive to separate out your components as much as possible.

At a bare minimum, for every new project I create I do the exact following steps:

  • 1) Create a blank visual studio solution
  • 2) Add an MVC project to it
  • 3) Add a class library to it called the Business layer
  • 4) Add a class library to it called the Data layer

By doing this your following the good principles of n-Tier design. Add into this some form of AOP (For example post-sharp or MVC Attributes) to handle any elements that are cross-cutting the layers, and you have a good solid architecture to work from.

NO RAW Data from your data layer should ever make it into your presentation layer (The MVC App) everything should be combined and flattened in your business layer.

The business layer should only ever handle DTO objects between itself and presentation, with raw data that it brings in from the data layer and then applies various rules too that are specific to your application domain.

With EF code first, and Nu-get packages such as auto-mapper, all of this is incredibly easy these days.

Use EF in your DAL to get your data using Linq, ADO or whatever you need.

Use auto-mapper to transform that data into DTO's to be passed to the business layer, then do any work you need before finally using auto-mapper to pass the resulting DTO up to your presentation.

Even if your NOT using MVC, adopting this strategy is win/win , even for WPF, Webforms, Winforms and much more.

If you do it correctly then the MVC portion essentially becomes a brain dead display of what the business layer is doing, and the ease with which you can remove your MVC app and put another UI on in it's place is frighteningly simple.

Update 14/11/2014

After reading the most recent comment added to this thread, I felt that adding this additional part to my answer was well warranted.

Good Architecture is about much more than just "Pretty Code".

If you get your architecture wrong it can be the difference between crashing and burning and flying high in a blaze of glory.

I've been doing I.T & Software development in one form or another now since about 1979, and believe me I've seen my fair share of failures and successes in that time.

When I first started, and I was still wet behind the ears, Object Oriented Programming wasn't even a thing, you lumped EVERYTHING into one source file, then you ran it through a compiler, then a linker with no kind of GUI stuff to help you.

Some of the code I wrote during these times, was incredibly messy, inefficient and completely horrible. As I grew, and learned however, I began to understand why this kind of code caused the problems it did, and while writing nice easy to read code is certainly an important skill, it's also very important to make sure that your surface area is also minimal and follows good standards.

I've seen so many great projects fail (or at the very least struggle greatly) over the years, and each time it's been because of bad choices made at the architecture design level, I can't stress just how important it is to get the design and the plans right before you even touch a single line of code.

And while I'm on the subject, code generators are just as dangerous. If your code generator creates code from templates that YOU control, then great guns, but IF you depend on templates, where you have no control over how the output is generated, then your asking for trouble. Visual Studio is a great tool, and amazing for creating fast solutions, but please make sure you know EXACTLY what it's creating behind the scenes when you click that button to do something.

If I get a library to develop against, the last thing I want to do, is to have to delve into the sources to tell me how it works, I depend on the architect who designed it, to guide me, by making logical choices, that are formed from a knowledge of great solid software craftsmanship practices.

I simply wouldn't trust anything that passed strings and discreet values around as though they where candy at a Christmas party, because... well how can I be sure what the type and responsibility of the variable/property/method actually is.

Who would you trust more to buy a house off? A professional company who hired an Architect to survey, plan and design a complete set of plans, which a professional team of Builders, Roofers, Plasterers etc then worked as a team to implement, or the guy that lives at the end of your street who works in the building trade and knows a thing or two about building houses?

I know which my choice would be.