MVC Business Logic Organization [closed] - c#

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 2 years ago.
Improve this question
I'm trying to learn MVC with ASP.Net and am reading Steve Sanderson's book. One thing I'm confused about is where to place the business logic?
For example, when deleting a product all Sanderson has is a method in his CartController that calls the Delete method on the productsRepository. This is strange to me because if there were any business logic, such as ensuring that the product isn't in anyone's shopping cart first, etc. it would have to either be in the products repository or the CartController.
Both of these seem like bad places to put business logic; the products repository is meant to be easily replaced with another (switching from using a db to using a session) and using the Controller means you are putting the business logic in the UI layer.
Shouldn't he be using a class that contains the business logic and calls the repository's delete method instead? The repository being a member variable of the business logic class'?

I typically structure my MVC solutions in a way resembling the following:
X.Core
general extension methods, logging, and other non-web infrastructure code
X.Domain
domain entities and repositories
X.Domain.Services
domain services for orchestrating complex domain operations, such as adding a product to a shopping cart
X.Application.Core
application logic (initialization (route registration, IoC configuration, etc.), web-specific extensions, MVC filters, controller base classes, view engines, etc.)
X.Application.Models
view model classes
X.Application.Services
service classes that can return ViewModels by accessing repositories or domain services, as well as the other way around for updates
X.Application.Web
controllers, views and static resources
Some of these could be combined, but having them separate makes it easier to locate stuff and to ensure your layer boundaries are respected.
A typical controller action for showing the product cart might look like this:
public virtual ActionResult ProductCart()
{
var applicationService = <obtain or create appropriate service instance>
var userID = <obtain user ID or similar from session state>
var viewModel = applicationService.GetProductCartModel( userID );
return View( "Cart", viewModel );
}
A typical controller action for adding a product to the shopping cart might thus look something like this:
public virtual ActionResult AddProductToCart( int productID )
{
var domainService = <obtain or create appropriate service instance>
var userID = <obtain user ID or similar from session state>
var response = domainService.AddProductToCart( userID, productID );
return Json( new { Success = response.Success, Message = response.Message } );
}

I also read Sanderson's first version of his book and it was fantastic - a very easy way to pick up and start using ASP.NET MVC. Unfortunately, you can't jump straight from the concepts in his book to writing a large maintainable application. One of the biggest hurdles is figuring out where to put your business logic and other concerns that lie between the UI and persistent storage (a concept called Separation of Concerns or SOC).
If you are interested, consider reading up on Domain Driven Design. I won't suggest that I know it perfectly, but serves as a good transition from Sanderson's sample applications into something that successfully separates UI concerns, business logic, and storage concerns.
My solution has a separate service layer. The controllers communicate with the service layer (using Dependency Injection - Ninject). The service layer has access to my domain objects / business logic and my repositories (NHibernate - also spun up with Ninject). I have very little logic in my views or controllers - the controllers serve a purpose of coordinator and I strive to keep my controller actions as thin as possible.
My domain layer (entities, business logic, etc.) has no dependencies. It does not have references to my Web project or to my Repository project. It is what is often referred to as POCO or Plain Old C#/CLR Objects.
EDIT: I noticed in one of your comments you are using EF. EF does not support POCO without using something called Code First (was in Community Technology Preview status when I checked last August). Just FYI.

The reality is that there's no silver bullet to this answer, and it really is a contextual question at heart. I like to separate things as much as possible, and business logic is, if you think about it, just another layer in an app.
I worked up a BDD-inspired decisioning engine and released it as an OSS project available via NuGet. The project is called NDecision, and you can read about it on the NDecision project home page.
NDecision makes decision-tree business logic quite simple to implement, and if you're a fan of Gherkin syntax and Fluent coding practices you'll feel right at home using it. The code snapshot below is from the project site, and demonstrates how business logic could be implemented.
This might not be a solution for you, but the idea is, if you already have your domain model in one assembly - a great idea and common practice as suggested in another answer earlier, there's no reason why you can't have another assembly with your "decision tree." NDecision was written with that in mind, to separate the logic into one independent layer.
Hopefully that'll be of some assistance.

If you want scalability, it's bad practice to use data access objects directly from the GUI. So in the example you mentioned, I think you should replace the repository that directly reads or writes to the DB by some business logic class that supports business operations.

I'm trying to learn MVC with ASP.Net
and am reading Steve Sanderson's book.
One thing I'm confused about is where
to place the business logic?
In the model (M in MVC), or domain layer. These are a separate set of types (preferably in a separate project) that represent domain models, services and repositories.

Related

How to persist aggregates with repositories?

I am trying to learn some concepts about DDD and the part of persisting Aggregates is confusing me a bit. I have read various answers on the topic on SO but none of them seem to answer my question.
Let's say I have an Aggregate root of Product. Now I do not want to inject the ProductRepository that will persist this aggregate root in the constructor of the Product class itself. Imagine me writting code like
var prod = new Product(Factory.CreateProductRepository(), name, costprice);
in the UI layer. If I do not want to inject my repository via dependency injection in the Aggregate Root, then the question is where should this code go? Should I create a class only for persisting this AR? Can anyone suggest what is the correct & recommended approach to solve this issue?
My concern is not which ORM to use or how to make this AR ORM friendly or easy to persist, my question is around the right use of repositories or any persistence class.
Application Services
You are right, the domain layer should know nothing about persistence. So injecting the repository into Product is indeed a bad idea.
The DDD concept you are looking for is called Application Service. An application service is not part of the domain layer, but lives in the service layer (sometimes called application layer). Application services represent a use case (as opposed to a domain concept) and have the following responsibilities:
Perform input validation
Enforce access control
Perform transaction control
The last point means that an application service will query a repository for an aggregate of a specific type (e.g. by ID), modify it by using one of its methods, and then pass it back to the repository for updating the DB.
Repository Ganularity
Concerning your second question
Should I create a class only for persisting this AR?
Yes, creating one repository per aggregate is a common approach. Often, standard repository operations like getById(), update(), delete(), etc. are extracted into a reusable class (either a base class or by aggregation).
You can also create additional repositories for non-domain information, e.g. statistical data. In these cases, make sure that you don't accidentally miss a domain concept, however.

Which part of mvc design pattern represents the business logic?

I am a little confused about the definition of the business logic in programming because I used to develop without paying an attention to any of these terminologies but now I want to be a good developer.
While I was reading in Wiki about the definition of the business logic I have read the following definition:
In computer software, business logic or domain logic is the part of the program that encodes the real-world business rules that determine how data can be created, displayed, stored, and changed.
and in another website I have read the following definition with example:
Business logic is that portion of an enterprise system which determines how data is:
Transformed and/or calculated. For example, business logic determines how a tax total is calculated from invoice line items.
Routed to people or software systems, aka workflow.
So I am wondering about which part of the MVC represents the business logic, is it the controller or the model or another part could be in the MVC?
I know that the controller is responsible for sending commands to the model but is it responsible for applying the rules of the business?
For example let's take the above example of the tax:
Suppose that we got the invoice data from a form in a view, the data will be directed to the controller but where the tax will be calculated, will we calculate it in the controller or will we ask for the help of an external class to compute it or will we compute it in the model before updating the database?
Could Example would be appreciated.
You can put the tax calculation logic in the Controller, but you're better off putting it in the Model as it is more loosely coupled. It is reasonable to want to calculate tax on lots of pages, so don't put it in lots of controllers, put it in a model that can be re-used.
If you hear someone talking about "Fat" Controllers vs "Thin" Controllers, that is what they're talking about. Most devs will advocate having very little code in their controllers (making them "thin") and really just acting as a relay/orchestrator off to the Model.
I do think the term Model is a bit confusing though because in Service Oriented Architecture (and functional languages for that matter), they stress trying to have "dumb" objects that don't have any functionality and they frequently refer those dumb objects as "Models". But when it comes to MVC, the "Model" really refers to the Business Model, which incorporates dumb objects that hold values AND the services that work on top of them.
In Enterprise software development, must of time we use N-tier applications. They are 3 or more tiers.
1- Data tier:
2- Application tier (business logic, logic tier, or middle tier)
3- Presentation tier: it is a layer which users can access directly such as a web page, including simple control and user input validation or an operating systems GUI. , .
MVC is one of the seminal insights in the early development of graphical user interfaces, and one of the first approaches to describe and implement software constructs in terms of their responsibilities
This said that MVC is use as a presentation layer. They are others like MVP, MVVM..
Sometime time in small application, an MVC structure is use to separate layer where the model is use as data layer, the controller as Logic layer.

Using MVC + Repository Pattern, where Business Logic should be?

I want to know the right concept about it. If I have a MVC application with Repository Pattern, where the BL should be?
Should it be inside the Model? Model should have all the business
logic before call the unitofwork to insert or not the data into
database?
Should it be in the controller? Before call the model?
Should I have a service layer to do the business logic and decide if
I should call the Model to call the UnitOfWork to save the data?
A good explanation will help a lot too.
The short answer - it depends. If it's a fairly complex or sizable application, I like to create a service layer project with the repositories as dependencies. If it's a small application, I'll put the logic in the controller. In my opinion, if it takes more time and effort to create the service layer than it would be to create the application (i.e. one or two controllers), then it doesn't make sense to me to go that route. You also need to consider the likelihood that the application will grow. What might start small could grow into something much bigger and in that case, again, it might be more beneficial to create the separate service layer.
The third one... and then some.
Your application structure could look like this (each in different projects):
Data storage layer (e.g. SQL database)
ORM (e.g. NHibernate or Entity Framework)
Domain (including abstract repositories and entities)
Service layer (and optionally business)
MVC application (which has it's own models relating to the entities)
but there are many ways to go about this depending on the complexity and size of your application.
There is no "correct" answer to this question, it is primarily opinion-based. You can read about my opinion in the following project wiki:
https://github.com/danludwig/tripod/wiki/Why-Tripod%3F
https://github.com/danludwig/tripod/wiki/Dependency-and-Control-Inversion
https://github.com/danludwig/tripod/wiki/Tripod-101
https://github.com/danludwig/tripod/wiki/Testing,-Testing,-1-2-3
https://github.com/danludwig/tripod/wiki/Command-Query-Responsibility-Segregation-(CQRS)
Another piece of advice I would like to offer is never put any business logic in viewmodels or entities. These classes should not have methods, only properties to contain data. Separate your data from behavior. Use models for data, and other types for behavior (methods).

web api controller in n-layer architecture

In my n-tier .Net Application I got next layers:
Data Access Layer (EF)
Business Layer (Validation & Business Logic)
Presentation Layers (1 MVC Controller and many API Controllers)
I found, that my Business Services only validate business objects, call CRUD DAO methods and return results to Api Controllers.
So, I doubt: may be Web Api Controllers should be used as Business Services?
Interesting, just answered a similar question...
So I woudn't do it I were you.
Here's just a few disadvatages of the approach from the top of my head:
Performance - a redundant HTTP roundtrip in Web MVC project.
Separation of concerns - most of the time the functionality provided
by API differs greatly form UI for the same project/application. You
might want to limit the API to a few methods with a strict contract.
In case you want Web API to be a layer between Web MVC and your DAL
you will have to expose all functionality you need for UI as well.
Also you might want to have different authorization and
authentication mechanisms. Very often API exceptions handling is
also different as well as input validation.
Maintanance - everytime you need to make a change required for UI
only you have to make sure it doesn't brake your API clients. Also
API versioning is a very important topic and mixing it with most UI
changes makes this process even more difficult.
Probably for now you application is not that complex but from the design perspective your solution is much more flexible now than it will be if you decide to put Web API between your UI and DAL layers.
N-Tier applications and multi-layer are not popular among the new wave of developers. Keep in mind, that just because something is not popular, among a group, does not mean that it does not have merit.
Pros of MVC:
Separation of Concerns
Unit Testing
Does a multi-layer MVC application using a Web.API have merit:
I know this will be met with some discontent and disagreement. However, my concern is that single purpose application developers are not giving consideration to enterprise development. Enterprise development, load balancing, manageable code maintenance, and true Separation of Concerns are only possible with multi-layer applications that can easily lend themselves to N-tier.
Many developers are operating in environments that demand that they design and implement data structures in SQL, create and maintain models and CRUD functionality, develop controllers and design good looking and friendly views. The MVC model utilizing Entity Framework makes this a manageable task for these small to moderate platform developers.
In the Enterprise, separating the Business and Data Access layers from the User Interface makes real good sense. Right now MVC is a popular and very functional platform for efficient and usable User Interface development. What will be the UI platform in ten years? Separating the UI from the other layers gives more life to the work spent developing the business logic. Not to mention, that it allows for accessing data on multiple platforms today.
Multi-layer MVC using Web.API has these advantages:
True Separation of Concerns
Supports Unit Testing
Makes the Business logic and Data Access logic more scalable and reusable than MVC alone.
Supports data processes without page refresh. (REST)
CONS:
- Does not easily support use of Entity Framework. (Which is not ready for the enterprise yet anyway)
You could have your code as part as your model, and that would even be considered as good separation of concerns since MVC is build for that.
But what my preferred thing to do is keep logic in a Business Layer of it's own. The reason for that is, I think, better separation of concerns. I like using IoC, so there might be different configurations that I route thought different running solutions. Or, I might have another UI/API/Project that uses the same logic layer.
As for the overhead, it has a little overhead, but I think worth the trouble comparing to the actual overhead in code it creates.
I agree with others here, looking into using strongly typed views, the controllers would only create an instance of the viewmodel and send it on to the view. The view model then is the intermediary to the data services layer. I personally create all my entities using EF in a different project just to separate function. The view model can either call EF directly or you can add another layer of pre-canned EF queries which the Viewmodel uses just to populate the view collections. This would look like this:
[View]-[Controller]-[Viewmodel]-[Optional repository and interface to EF]---[EF]
In the interface to EF you would catch all DB errors when trying to get information and post back to the view according to your design.
The beauty of strongly typed views is that they post back and forth from the View and can contain methods which you can call at will. Because they are a pseudo model for the view, they can also have properties specific to the view which may be used at the business layer. I pass view models around quite a bit were warranted. (After all they are just a pointer)...
You can implement business logic/validation/calucations in the actual model/entity classes rather than ApiControllers, otherwise you will end up with so much code in your controller which is not really a good thing.
Also you can use DataAnnotations Attributes to perform your validation which sits outside of your controller. for.e.g. http://msdn.microsoft.com/en-us/library/ee256141(v=vs.100).aspx

Best practice for database methods in MVC 4

I am pretty new to MVC 4, and I have worked mostly with web forms up to this moment in C#. I understand the pattern of MVC, the routing, calling actions and so on.
But what about the actions which are responsible for fetching data from the database, for example by firing stored procedures? I have seen some tutorials where they put the logic for connecting to the database directly in the actions.
However I am thinking of a more centralized way to do it. For example, I can put all the functions which are firing stored procedures in a separate class named DatabaseCoordinator.cs in a folder named Helpers for example. Then I can call them from the actions in the controllers.
In that way I will know that I can find all of my methods for the database in one class, which is a very clean solution, I think (or at least in web forms). However I want to follow the pattern of MVC, and use only models, views and controllers as the name of the pattern itself implies.
So what is the best practice for that? Should I make a separate class for this, or implement the logic directly in the controllers, or perhaps somewhere else?
You should certainly make a separate repository class to contain all of your data access operations.
There is a good worked example here:
http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application
I recommend that you put your data access code somewhere other than in your controller. The controller's primary purpose is to gather together the information for display on a page or the reverse - to take the data from the page that is posted back and feed it to the code responsible for business rules and data access.
For most MVC projects (heck, for most projects really!) I build separate class library projects - at minimum one for business rules and data access, though typically I'll make those two separate projects. The purpose of separating the logic is really for simpler future maintenance and reusability. If you keep your various logical parts separate, you can easily swap them out if your logic or database needs to change, or you can easily consume the business rules and data from a new type of user interface; for example, if you decided to implement your project as a Windows forms application in addition to your web system, you could (theoretically) just reuse your business logic and data access logic libraries and only rebuild the user layer. However, if you build your logic into your controller, you really can't reuse that logic without extracting it and converting it to the new application model you're using.
So, simply put, definitely keep 99% of your logic and data access out of your controller. Only put what you must put into your controller, the rest in a separate class, or where appropriate, in separate class libraries.
Good luck!
The Controllers and Views tend to stay within the same project, but it's common to split the data access classes and models into their own seperate class library, as this allows other projects to utilise them.
This will allow you, in the future, to maybe add a windows forms/wpf interface or maybe a mobile device interface, leveraging the work you already have in the standalone class library.
Another thing to consider, is looking into how to use ViewModels in your MVC application. It's a common technique when Views require more than one domain object. Using View Models in MVC.
Check out the Unit of Work Pattern (UOW) combined with the Repository Pattern. It doesn't matter if you ultimately call a stored procedure or an inline linq query to return results, your caller shouldn't know or care how GetPersons is ultimately implemented. The UOW pattern combined with the Repository pattern is a very popular way to expose an Entity Framework database in the ASP.NET community. You will find different ways to do it, some are over-kill and some just create dependencies with no actual benefit but you will find a way that feels right to you with those patterns.
After more experience, I would like to change my answer and state that the Repository Pattern and thus the Unit of Work pattern are pointless layers of abstraction to prevent you from working with Entity Framework, which is your data layer abstraction! directly.
Other than being able to swap out databases from say Microsoft SQL PostgreSQL (when would this ever happen in the real world?) and control the structure of complex queries that you don't want repeated in your code, I see no real value to the repository pattern. To include CreatedBy,ModifiedBy values on Insert/Update you need only override EntityFramework. To encapsulate queries that include business rules such as where active = 1 and isdeleted = 0 just extend Linq queries with extension methods.

Categories