Where to keep business logics in MVC architecture? - c#

In my company we have recently started developing MVC application. Our task is to write the business logic layer and in future it should be with less maintenance.
We have couple of web services to add/update/delete user information.
Now we have to add the business logics like:
If Field1 on the page is 'xxxx' then field2 should be in the range of 1000 to 2000
If field3 is some department then field4 should be only in some sub departments.
So we have to design the layer so that in future our admin(who don't have programming knowledge) can go in and change the logics so that it will work. Please give me some suggestions.
So far what i have got is: Write all these conditions in Model and validate them when user click save button.
Thanks in advance.

Business logic should kept inside the model. You should aim to have a big Model and a small controller.
You may find this interesting to read this.
Also check Where does the “business logic layer” fit in to an MVC application?

Keep it in a separate assembly which doesn't know about your ui layer. Your models can go here and enforce business rules. I personally like building the business layer on top of the Csla framework, which lets you build rich models with powerful rules. Its geared toward ntier development but I believe its also compatible with ddd.

When you are talking about layering, your Business layer should be separated from Presentation Layer. ASP.NET MVC is a presentation technology; so, your Business Layer would be in different assembly. Additionally, your Business Model wouldn't be used directly in your views; you can use ViewModel to validate user input and when everything was OK, transfer ViewModel data into Business Entity.
If you are interested to obtain more information about layering in enterprise level applications I recommend you Microsoft Spain - Domain Oriented N-Layered .NET 4.0 Sample App.

I like to use Entity Framework and Fluent Validation to create a domain layer that contains both models and validators. The set up looks like this:
public abstract class DomainEntity
{
private IValidator validator;
protected DomainEntity(IValidator validator)
{
this.validator = validator;
}
public bool IsValid
{
get { return validator.IsValid; }
}
public ValidationResult Validate()
{
return validator.Validate();
}
}
public class Person : DomainEntity
{
public int Id { get; set; }
public string Name { get; set; }
public Person() : base(new PersonValidator())
}
public class PersonValidator() : AbstractValidator<Person>
{
public PersonValidator()
{
... validation logic
}
}
Using this set up, my models and validators live in the same layer but I don't muddy up my model classes with busines logic.

Business Logic should be in Model layer, and I don't think that anyone without programming knowledge can change business logic, he must have basic programming knowledge at least

You can use DataAnnotations to do this - in fact data annotations enable more than just server side enforcing of model validity. They can also give hints to Entity Framework and client side scripts in order for database/client side validation, and add metadata to methods and properties that MVC can inspect
e.g. for a model:
class PersonDetailsModel
{
[Required("Please enter a name")] // Don't allow no value, show the message when the rule is broken (if client side validation is enabled it shows when you tab off the control)
[DisplayName("Full Name")] // Hint for MVC - show this when using the helper methods e.g. in MVC4 Razor syntax #Html.LabelFor(model => model.Name)
public string Name { get; set; }
}
And yes, keep as much business logic in the business layer (model). Cross-cutting concerns aside, your components should be as loosely coupled as possible. This way there is a central place to make changes, your code is more testable and maintainable and it also helps you to keep your programming consistent (which helps newbies to your project get up to speed quickly)
If you have more complex rules, you can write EF validators.
http://msdn.microsoft.com/en-gb/data/gg193959.aspx
If you aren't using Entity Framework then you might want to consider it - if you are using another ORM then obviously use the tools that support that. If you aren't using an ORM, then there are alternatives but you'll have to write some plumbing code

Related

Naming convention for objects in multi-layer application with EF6, domain, DTO, ViewModel

I'm starting new project with multiple layers and multiple client types (WebApp, WebAPI, Xamarin and Windows). I want to try "Clean Architecture".
My previous applications had no application layer, my view models were directly coupled with an Entity Framework DbContext. I also have very little experience with ASP.NET and web development.
Yes, this is a question similar to these:
Naming conventions for model in multi layer application
File naming convention for layers
but I'm not asking how to organize my architecture, more about using objects with same class names from different layers in one file or eventually changing my convention to use UserBO naming in Domain layer for example.
The problem
So, in the Persistence layer I have POCO class called "User".
namespace Persistence.Entities
{
public class User
{
// (...)
}
}
In the Domain layer I also have class called "User".
namespace Domain.Entities
{
public class User
{
// (...)
}
}
In the Windows and Android clients I'll create ViewModels, but I can just name it "UserVM" and this is not a problem. In WebAPI there will be "UserDTO", so no problem too. But in the Application layer I want to create some method that uses two classes with same names:
using System.Collections.Generic;
namespace Application
{
public class Users
{
public List<Domain.Entities.User> GetConnectedUsers()
{
List<Persistence.Entities.User> usersFromDb = new List<Persistence.Entities.User>();
List<Domain.Entities.User> usersToReturn = new List<Domain.Entities.User>();
// take users from database, make domain objects
return usersToReturn;
}
}
}
I don't want to write Persistence.Entities.User and Domain.Entities.User in my Application layer.
What can I do to deal with this?
So far I figured out, that I can use alias for using in C# like this:
using Persistence = Persistence.Entities;
using Domain = Domain.Entities;
namespace Application
{
public class Users
{
public List<Domain.User> GetConnectedUsers()
{
List<Persistence.User> usersFromDb = new List<Persistence.User>();
List<Domain.User> usersToReturn = new List<Domain.User>();
// take users from database, make domain objects
return usersToReturn;
}
}
}
Maybe there is some better way dealing with this?
Or maybe I should add some suffix to my Domain layer objects? UserBO (for BusinessObject). Will this be correct? Sorry if this is stupid question, but as I wrote - I have no experience in development with that many layers.
I think that last thing I would do is naming change for my database entities because there will be much more tables than domain objects, so names short as possible will be more useful in Persistence layer than in Domain layer.
Short answer: I call my business layer "services", so a service that provice services around the User object I would call a UserService. The object you instantiate from the business/service layer is not "a" User, but a UserBO or UserService. The model/DTO object I'd either actually call a User, a UserModel or a UserDTO. I don't like abbrevations like BO, and I also do like the Service wording, so that's my preference. YMMV :-)

DTO vs. Domain Model, project organization

I have a project with a repository, a service layer, using EF6 and code-first POCOs. In the CustomerRepository, I am doing several projection queries that return objects.
I understand that the code-first POCO's are what would be considered "Domain Models", but if I were to do a projection query into a different model, what is that model considered? An example of this would be the CustomerOrderStats. Is that still a Domain Model, or should that be considered a DTO model?
Example
Object returned from Repository:
public class CustomerOrderStats
{
public string Name { get; set; }
public int Count { get; set; }
}
Query in the Repository
public CustomerOrderStats GetCustomerOrderStats(Guid customerGuid)
{
return customers
.Where(c => c.Guid == customerGuid)
.Select(new CustomerOrderStats
{
Name = c.Name,
Count = c.Orders.Count()
};
}
It could be either one, really. The definition of a model vs. a DTO isn't really a matter of how you organize any given framework, but rather what that object represents in the domain. If it has rich functionality or business logic or is an active part of the actual business process, it's probably a model. If, on the other hand, it's just a container of properties to move values from one place to another, it's probably a DTO.
The key here is whether the object is an active part of the business process. And a good rule of thumb here is often the name of the object.
Is it a name that non-technical business team members understand?
Is it a term they use to describe what the business does? (Even a very small part of the business)
Does it carry a meaning in the industry in general?
A DTO is generally something that exists for purely technical reasons. Component A needs to send data to Component B, but that operation is a technical one and not a business one. Data just needs to be, well, transferred. As a piece of the system, it's essentially built "from the bottom up" because it satisfies a low-level technical need.
A model describes a part of the business. It could be an element on a chart which defines the business process in non-technical terms, or an encapsulation of a business concept. As a piece of the system, it's essentially built "from the top down" because it is described generally by the business and then implemented specifically to meet that need.

Business logic layer needs its own models or not

I'm doing 3 tier application using asp.net mvc and I want to do everything as recommended.
So I've done MvcSample.Bll for business logic, MvcSample.Data for data and MvcSample.Web for website.
In Data I've my edmx file (I'm using database first approach) and my repositories. And in Bll I'm doing services which will called in web.
So my question is that:
Should I write other models in Bll or use that ones which are generated in edmx file?
It heavily depends on the type of problem that your application is trying to solve.
From my experience, it is very rare that the business logic returns model objects directly from Entity Framework. Also, accepting these as arguments may not be the best idea.
Entity Framework model represents your relational database. Because of that, its definition contains many things that your business logic should not expose, for example navigation properties, computed properties etc. When accepting your model object as an argument, you may notice that many properties are not used by the particular business logic method. In many cases it confuses the developer and is the source of bugs.
All in all, if your application is a quick prototype, proof of concept or a simple CRUD software than it might be sufficient to use EF model classes. However, from practical point of view consider bespoke business logic model/dto classes.
From my point of view you need another model for your Bll.
That would encapsulate your Bllcompletely.
I think there is no right or wrong answer for your question.
In my experience, I used both.
Let's see at below example:
I have an User table
public class User
{
public int Id{get;set;}
public string First_Name{get;set;}
public string Last_Name{get;set;}
public int Age{get;set;}
public string Password{get;set;} //let's use this for demonstration
}
I have a Method call DisplayAll() in Bll. This method should list down all users in my database by Full Names (FirstName + LastName) and their Ages.
I should not return User class because it will expose the Password, but rather, I create a new Class UserDto
public class UserDto
{
public string FullName{get;set;}
public int Age{get;set;}
}
So here is my DisplayAll():
public List<UserDto> DisplayAll()
{
List<UserDto> result = ctx.User //my DbContext
.Select(x => new UserDto()
{
FullName = x.First_Name + " " +Last_Name,
Age = x.Age
}
return result;
}
So as you can see, my method DisplayAll() uses both User and UserDto
My approach will be
MvcSample.Data
-- Model Classes
-- EDMX attach to model
MvcSample.Bll
-- Model Inheriting MvcSample.Data.Model
-- Business Logic Class - Using MvcSample.Bll.Model
MvcSample.Web
-- Controller using MvcSample.Bll.Model
It depends on your view about software design and how you want to take advantage of it. by separating BLL model, you will have your freedom to put story specific validation and calculation. By using only DLL model, it is sometimes tough as it is going to take effect in DB.
You can use 3 tier architecture in asp.net in this way
MvcSample.BLL - business logic layer
MvcSample.DAL - Data access layer
MvcSample.Domain - Domain layer
MvcSample.web - website
All your repository classes are including in .BLL layer.That means your logics are stored here.
Usually .DAL is used for storing .edmx classes. .Domain is using for recreate database objects that are useful for server side.That means if you are passing a json object from client to server,Then that object should be create on the server side.So those classes can be implement in the .domain

Having Separate Domain Model and Persistence Model in DDD

I have been reading about domain driven design and how to implement it while using code first approach for generating a database. From what I've read and researched there are two opinions around this subject:
Have 1 class that serves both as a domain model and a persistence model
Have 2 different classes, one implementing the domain logic and one used for a code-first approach
Now I know opinion 1) is said to simplify small solutions that do not have many differences between the domain and persistence models but I think it breaks the single responsibility principle and by that introduces a lot of issues when an ORM's conventions interfere with DDD.
What is a surprise to me is there are numerous code examples of how to implement opinion 1). But a haven't found a single example of how to implement opinion 2) and how to map the 2 objects. (Probably there are such examples but I failed to find a C# one)
So I tried to implement an example on my own but I am not sure if that's a good way to do it.
Let's say I have a ticketing system and tickets have expiration date. My domain model will look like this:
/// <summary>
/// Domain Model
/// </summary>
public class TicketEntity
{
public int Id { get; private set; }
public decimal Cost { get; private set; }
public DateTime ExpiryDate { get; private set; }
public TicketEntity(int id, decimal cost, DateTime expiryDate)
{
this.Id = id;
this.Cost = cost;
this.ExpiryDate = expiryDate;
}
public bool IsTicketExpired()
{
if (DateTime.Now > this.ExpiryDate)
{
return true;
}
else
{
return false;
}
}
}
The persistence model using Entity Framework as ORM will look almost the same but as the solution grows this might not be the case
/// <summary>
/// ORM code first Persistence Model
/// </summary>
public class Ticket
{
[Key]
public int Id { get; set; }
public decimal Cost { get; set; }
public DateTime ExpiryDate { get; set; }
}
Everything looking great so far. Now what I am not sure about is which is the best place to get a Ticket persistence model from the repository and how to map it to the TicketEntity domain model
I have done this in an application/service layer.
public class ApplicationService
{
private ITicketsRepository ticketsRepository;
public ApplicationService(ITicketsRepository ticketsRepository)
{
this.ticketsRepository = ticketsRepository;
}
public bool IsTicketExpired(int ticketId)
{
Ticket persistanceModel = this.ticketsRepository.GetById(ticketId);
TicketEntity domainModel = new TicketEntity(
persistanceModel.Id,
persistanceModel.Cost,
persistanceModel.ExpiryDate);
return domainModel.IsTicketExpired();
}
}
My questions are:
Are there any reasons opinion 1) would be preferred to opinion 2) other than speeding up development and reusing code.
Are there any issues in my approach of mapping the models? Is there something I missed that would bring up issues when a solution grows?
Are there any reasons opinion 1) would be preferred to opinion 2) other than speeding up development and reusing code.
Option 1 is just because of pure laziness and imagined increased development speed. It's true that those applications will get version 1.0 built faster. But when those developers reach version 3.0 of the application, they do not think it's so fun to maintain the application due to all compromises that they have had to do in the domain model due to the ORM mapper.
Are there any issues in my approach of mapping the models? Is there something I missed that would bring up issues when a solution grows?
Yes. The repository should be responsible of hiding the persistence mechanism. It's API should only work with domain entities and not persistence entities.
The repository is responsible of doing conversions to/from domain entities (to be able to persist them). A fetch method typically uses ADO.NET or an ORM like Entity Framework to load the database object/entity. Then convert it to the correct business entity and finally return it.
Otherwise you would force every service to have knowledge about persistence AND working with your domain model, thus having two responsibilities.
If you work with application services per the DDD definition you will probably want to look at the Command/Query separation pattern which can be a replacement of the application services. The code gets cleaner and you also get a much more lightweight API wrapping your domain model.
I got into this dilemma this year in a big project I was working at and it was a really tough decision to make... I would like to talk about this topic during hours, but I'll resume my thoughts for you:
1) Persistence and Domain model as the same thing
If you are in a new project with a database designed from zero for it I would probablly suggest this option. Yes, the domain and your knowledge about it will change constantly and this will demand refactoring that will affect your database, but I think in most cases it's worth it.
With Entity Framework as your ORM you can almost keep your domain models entirely free of ORM concerns using fluent mappings.
Good parts:
Fast, easy, beautiful (if the database is designed for that problem)
Bad parts:
Maybe the developers starts to think twice before to do a change/refactoring in the domain fearing that it will affect the database. This fear is not good for the domain.
If the domain starts to diverge too much from the database you will face some difficulties to maintain the domain in harmony with the ORM. The closer to the domain the harder to configure the ORM. The closer to the ORM the dirtier the domain gets.
2) Persistence and Domain model as two separated things
It will get you free to do whatever you want with your domain. No fear of refactorings, no limitations provinients from ORM and database. I would recomend this approach for systems that deal with a legacy or bad designed database, something that will probably end messing up your domain.
Good parts:
Completely free to refactor the domain
It'll get easy to dig into another topics of DDD like Bounded Context.
Bad parts:
More efforts with data conversions between the layers. Development time (maybe also runtime) will get slower.
But the principal and, believe me, what will hurt more: You will lose the main beneffits of using an ORM! Like tracking changes. Maybe you will end up using frameworks like GraphDiff or even abandon ORM's and go to the pure ADO.NET.
Are there any issues in my approach of mapping the models?
I agree with #jgauffin: "it's in the repository that the mapping should take place". This way your Persistence models will never get out from the Repository layer, in preference no one should see those entities (unless the repository itself).
Are there any reasons opinion 1) would be preferred to opinion 2)
other than speeding up development and reusing code.
I can see a big one (opinionated stuff ahead) : there is no "Persistence Model". All you've got is a relational model in your database, and a Domain object model. Mapping between the two is a set of actions, not data structures. What's more, this is precisely what ORM's are supposed to do.
Most ORM's now support what they should have provided from the start -- a way to declare these actions directly in code without touching your domain entities. Entity Framework's fluent configurations for instance allow you to do that.
You may be under the impression that no persistence model = violating SRP and trampling on DDD, because many implementations you can find out there do. But it doesn't have to be like that.

How to add custom methods with database logic

I created an application with this architecture:
MyProject.Model: Contains POCO. Example:
public class Car
{
public int Id { get; set; }
public string Name { get; set; }
}
MyProject.Repositories: Contains repositories and UnitOfWork
public class UnitOfWork
{
// ...
public Repository<Car> Cars { get; set; }
// ...
}
public class Repository<T>
{
// ...
// Add / Update / Delete ...
// ...
}
MyProject.Web: ASP.Net MVC application
Now I want to find a way to interact with data by using methods. For example in MyProject.Model.Car I want to add a method that will get data with non-navigation properties, a method named `GetSimilarCars()'. The problem is that the repository cannot interact with other repositories and thus cannot perform operations on the database.
I don't really know how to do this in a simple manner and what is the best place in my architecture to put this.
Another example could be UserGroup.Deactivate(), this method would deactivate each user and send them a notification by email. Of course I can put this method in the Web application Controller but I think this is no the place to put such code that could be called in many places in the application.
Note: I am using Entity Framework.
Any suggestion on how to implement such operations?
This type of stuff goes into your DAL (essentially your unit of work and repository, in this limited scenario). However, this is a pattern that bit me when I first starting working with MVC. Entity Framework already implements these patterns; your DbContext is your unit of work and your DbSet is your repository. All creating another layer on top of this does is add complexity. I personally ended up going with a service pattern instead, which merely sits on top of EF and allows me to do things like someService.GetAllFoo(). That way, the use of Entity Framework is abstracted away (I can switch out the DAL at any time. I can even remove the database completely and go with an API instead, without having to change any code in the rest of my application.) but I'm also not just reinventing the wheel.
In a service pattern, you're specifically only providing endpoints for the things you need, so it's a perfect candidate for things like GetSimilarCars, as you simply just add another method to the service to encapsulate the logic for that.
I would assume that your Business Layer (BL) would be communicating with your Data Access Layer (DAL). That way from your BL you could reach out to different repositories in DAL. That would solve your problem of repositories not being able to share data (that data would be shared through BL).
See here: N-tier architecture w/ EF and MVC
I did not quite get you question but this is how you assign the values. And add it into a collection
public class Repository<T>
{
List<car> _lstCar=new List<car>();
//Add
car cobj=new car();
cobj.Id="1234";
cobj.Name="Mercedes";
_lstCar.Add(cobj);
}

Categories