简体   繁体   中英

Repository pattern with business logic

I just have the intention to write demo application based on DDD. My repository uses Entity Framework ORM an everything is great. MVC and Windows Forms applications calls repository methods and that works. But What If I decide to replace Entity Framework with Dapper or NHibernate or my data comes through web service? I konw that I need to rewrite repostiory implementation, but what with my bussines logic. Business logic now is placed in Repository. Some examples have business logic in controller but I have more than one client. Do I need to put some layer above Repository? What is the name of that layer in concept of DDD.

I konw that I need to rewrite repostiory implementation, but what with my bussines logic. Business logic now is placed in Repository.

This kind of worries me. If your business logic is placed inside of your repository, then you aren't practicing Domain Driven Design at all. In DDD, your business logic is found in your domain entities. The purpose of a repository is simply to return populated domain objects. The Domain Objects shouldn't have any idea how they're saved (whether it's in a database, an xml file, or just created dynamically).

The whole purpose of Domain Driven design is to free you from being tied to any specific infrastructure. Your Domain Objects should be able to work, regardless of whether you're using Entity Framework or Dapper.

Typically, you can create a set of classes that represents your domain model. Then you will have a set of classes for the repository that will take the domain model class for read/write. This allows you to change one independent of the other.

For example, domain model:

class Vehicle
{
    string id; // or you can use an appropriate key
    int noOfWheels;
    int topSpeed;
    // etc.
}

class Car : Vehicle
{
    int passengerCapacity;
    int trunkCapacity;
    // etc.
    string Serialize();
    void Deserialize(string representation);
}

And your repository:

class VehicleRepository
{
    void Store(Vehicle v);
    Vehicle GetVehicle(string id);
    void Delete(string id);
    // etc.
}

I have avoided adding interfaces for code brevity. But, in general, this kind of a structure will allow you to modify your domain objects regardless of the repository and vice versa. Thus you can have a repository that will put your objects in NOSQL store (or file system for local testing) by serializing/deserializing objects, but another repository that will CRUD objects from a SQL store.

I have included serialization/deserialization methods on the object, which works in most cases. However, sometimes this has to be separated out in separate classes and hidden behind the repository for version control with the physical storage medium (ie your physical representation may change, but your domain objects should not be affected, and vice versa).

Do I need to put some layer above Repository?

Yes. The goal of a Repository is to simply remove knowledge of how data is persisted from the Domain layer. This is to enforce a separation of concerns and keep the Domain 'pure'. A Repository does this by providing an abstraction for your Domain objects whereby it presents them as nothing more than an in-memory collection.

Note however that the Repository's interface should be defined in the Domain, because the Repository is there to serve the Domain and only the Domain can define its contract with its data.

What is the name of that layer in concept of DDD?

Repositories belong in the Infrastructure layer. The layer above this is the Domain layer, where all business logic lives.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM