Frage

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?

War es hilfreich?

Lösung

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;}
    }
}

Andere Tipps

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.

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.

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.

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

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top