简体   繁体   中英

Repository pattern and service layer implementation

I'm using the generic repository and unit of work pattern for my mvc4 website.

Now I have the situation, that I want to delete a user of my system. In the delete code I must delete some more entries in other tables (comments, accessrights, ..).

The simplest solution is to create a UserRepository which inherits from GenericRepository<User> and modify the delete method to delete the data in other tables. But that means my UserRepository would access to other tables, which should have their own repository classes, right?

I've read about a service layer, which is between my business logic and my repositories.

What is the best practise here and how looks a implementation of the service layer?

And is there still any requirement for have custom implemented repositores like UserRepository if I use a service layer or should I only have generic repositories and do my logic in the service class?

Example code:

class UserRepository
{
    public void Delete(User entity)
    {
        var userComments = Context.UserComments.Get(comment => comment.UserId == entity.Id);

        foreach (var comment in userComments)
        {
            Context.UserComments.Remove(comment);
        }

        //
        // same for access rights here
        //

        Context.Users.Remove(entity);
    }
}

The repository pattern was popularized with the DDD (Domain Driven Design) movement. In DDD, it is recommended that you DON'T create a repository per table, but one per aggregate root.. So, while you might have a table for a user, user orders, and user comments, you could decide that the User is an aggregate root and then you would only create a user repository and add your methods there.

Anyway, regardless of whether you care about DDD, I'd add the logic to your user repo, it makes sense to be there rather than any other repo.

You could create a service layer and create a service class for this, but service classes are really not useful for this - you're not really benefiting anything in this scenario.

Use

.WillCascadeOnDelete(true);

on modelBuilder

To answer your questions about services. You ideally want your service to perform additional logic on the entities/objects that your repository has retrieved for you. In this case, you don't really want a service to be deleting rows as this is the responsibility of your repository.

Services are good. In MVC, you call service methods from your controllers. Ideally, interfaces so you can test them easily.

As you said, service layer is help you to separate between business logic and repositories. The main idea here is dependency injection

public interface IUserService
{
    public void Delete(User entity);
}

//
// This class would be used Linq to Entities 
public class LinqUserService : IUserService 
{
    public void Delete (User entity)
    {
    }  
}

// 
// This class would be used Sql command
public class SqlUserService : IUserService
{
    public void Delete (User entity)
    {
    } 
}

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