ASP.NET MVC Business Logic in Domain Model vs Service Layer
Asked Answered
A

5

37

I have been reading about where to put business logic in ASP.NET MVC Project for a while and I still can't get clear on some things.

1 - Domain models. What are these really? In my Model folder I have only a bunch of classes corresponding to my database. I am using EF code first. I assume these are my domain models.

2 - Service Layer. This answer suggests a service layer and I think this makes perfect sense. I had decided to go with this one. However, Martin Fowler's "Anemic Domain Models" article messed up my mind.

I am not really sure how can I add logic to my domain models.

I have gone through many business logic-related questions and each of them proposes either 1 or 2. What I don't understand is how I can implement the first one. Adding methods to entity classes (domain models for me) does not make sense at all. And why is the second approach considered bad?

Arbil answered 2/2, 2013 at 1:24 Comment(0)
A
28

First off, your Model folder in your Asp.Net MVC project should be used for ViewModels. These are the models that your Controllers send to your Views. They should be highly optimized for the View, meaning only the properties needed for the view, and nothing else.

What you are taking about, Domain Models, are the same as Business Models, and belong in your Business Layer. The Model folder in your Asp.Net MVC project are the models for your UI Layer.

The second approach, business logic in your service (really business) layer is not considered bad. It's a very nice buffer between your Data Layer and your UI Layer (3-tier architecture). Your data layer handles getting data, from either web services or a database, and your business/service layer handles translating that data into business/domain models. It also holds any business logic, like calculations, etc.

These business/domain models are usually POCOs, but they don't have to be. This is how I sometimes set up my business models:

public class BusinessObject
{
    private DataObject _dataObject;

    public BusinessObject(DataObject dataObject)
    {
        _dataObject = dataObject;
    }

    public int BusinessId
    {
        get {return _dataObject.Id;}
        set {_dataObject.Id = value;}
    }

    public string Name
    {
        get {return _dataObject.Description;}
        set {_dataObject.Description = value;}
    }
}
Alix answered 2/2, 2013 at 1:38 Comment(4)
thanks. I have ViewModel folder for my view models but I see your point. Just to clarify, Is DataObject in BusinessObject the actual class that maps to my database ? (Ef entity in my case)Arbil
BusinessObject is your Domain Model, and DataObject is a class in your data layer - in your case, one of your EntityObjects.Alix
thank you very much. You clarified most of things stucked in my head :)Arbil
Why would you preserve the underlying DataObject in your BusinessObject when instead you could have the POCO you mentioned and a very thin mapper method public static BusinessObject ToBusinessObject(this DataObject dataObject) { return new BusinessObject { BusinessId = dataObject.Id, ... }; } ?Troostite
B
14

I prefer to NOT have business logic in domain models. I keep my domain models usually as POCO's to represent my DB tables/schema.

Keeping the business logic away from the domain models will allow me to reuse my domain model with another project as well.

You may consider a middle layer between your controllers and your data access layer/ Repositary layer to handle this. I would call this as a service layer.

Betide answered 2/2, 2013 at 1:29 Comment(5)
Just to be clear, your domain model is a separate assembly which has no functionality? Isn't this the Anemic Domain Model anti-pattern?Jermyn
Those are POCOs. I Can reuse it any place/project i want.Betide
Yes, they're POCOs, but they're not "domain models" in the traditional sense. They're in-memory representations of your database. Not saying they're not useful, just that they'd fit more in line with Data Transfer Objects than Domain objects. martinfowler.com/eaaCatalog/domainModel.htmlJermyn
Im really confuse also with these Anemic Model and Domain Model thing. Because the more loose couple you have, the more anemic your model would be. And business rules can vary depending on the company. But I dont get it, why anemic model is bad. and what behavior should be put on domain model and domain service.Tunis
@Daskul - One of the reasons that anemic model is bad because you're not using object oriented to its full extent (objects should include behavior, not only data). The behavior in the domain model should be whatever related directly to the business objects you defined (your core business entities). The service layer includes behavior not related directly to business objects, e.g. doing an operation related to multiple business objects, or an operation which isn't directly suitable to your business object like filling the business object with data received from an external source etc.Gitagitel
A
10

I know this has already been answered, but I categorize models into 3 groups

ViewModels - These are light weight (often poco) classes that model the data needed by a page on your site. These classes handle the mundane boilerplate of what gets shown to the user, and changes when the data that you want to display changes.

DomainModels - These are normally heavy weight business logic classes. They normally model the core business rules for what you're doing. These classes are often highly cohesive and are where the majority of the work that makes your site special happens. I said these models are normally heavyweight but in reality if all your project does is take that data from the user and stick it in the database, this class is going to be a little data mapping class. Many times you'll see these classes being composed of persistence models and returning view models.

PersistenceModels - These are models of your persistence mechanism. For most of us this means modeling a database table, but could also be a complex nosql document or json (or whatever) data that's returned from an api request. Their responsibility is to handle the mundane boiler plate of what shape your external data takes.

Keep in mind also that you don't always need to have all three of these types of models present in your project. Sometimes your view model will be line for line what you're persistence model is. In that case you'd be wasting your clients money to write the whole thing twice and add a domain model to map one to the other. You're the developer and it's your job to know when to build a air-craft carrier to go to the store for groceries.

Armistead answered 25/3, 2014 at 16:6 Comment(0)
D
2

Domain models should be able to perform their work on their own and expose properties and methods that represent their state and functions. They act as roots (aggregate roots) to a hierarchy of information that is required by models to function. They remain hidden only available to services.

Services expose business/domain functionality to the outside world (web services, UI etc) as a set of APIs following the message pattern (requests/responses), by retrieving models from the repositories that encapsulate the data access layer, then calling methods/business functions on the models and finally saving them back to the repositories.

Some times it feels that services repeat methods of business objects, but in time and real practice that is not what really happens.

In a real domain driven design you need at least 3 sets of objects. Business Objects, Repositories of Business Objects and Services.

Think as if your requirement is always that each type of component is written by different teams. One team requires an exposed service without knowing the details and without the other having to write the logic on the service it self. The service could then be consumed by anyone that requires it without having to dig into the core model itself.

Davin answered 24/7, 2018 at 18:21 Comment(0)
I
-1

Application flow control logic belongs in a controller.

Data access logic belongs in a repository.

Validation logic belongs in a service layer.

A service layer is an additional layer in an ASP.NET MVC application that mediates communication between a controller and repository layer.

The service layer contains business validation logic.

For example, a product service layer has a CreateProduct() method.

The CreateProduct() method calls the ValidateProduct() method to validate a new product before passing the product to the product repository.

Source: http://www.asp.net/mvc/overview/older-versions-1/models-data/validating-with-a-service-layer-cs

Inharmonic answered 14/7, 2016 at 10:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.