Question

I've got an ASP.NET MVC application, and I'm using the repository pattern, with service-specific repositories. I'm finding my setup is starting to feel very repetitive.

My layers look like this: UserController > UserService > UserRepository (the repository then uses entity framework)

The controller accepts the service in the constructor for testability: public UserController(IUserService userService)

The service accepts the repository: public UserService(IUserRepository)

The user might be able to update their business information, change their name, email, delete a contact address, etc.

So I end up with things like this in the service:

public class UserService {
    User CreateUser(....);
    User GetUserById(int id);
    void UpdateUser(User user);
    void DeleteUser(User user);
    Business CreateBusiness(...);
    Business GetBusinessById(int businessId);
    void UpdateBusiness(Business business);
    void DeleteBusiness(Business business);
    IEnumerable<Business> GetBusinessesByUserId();
    IEnumerable<BusinessType> GetBusinessTypes();
    ...
    ...
    ...

Each of these functions call functions like this in the repository layer:

public class UserRepository {
    User CreateUser(....);
    User GetUserById(int id);
    void UpdateUser(User user);
    void DeleteUser(User user);
    Business CreateBusiness(...);
    Business GetBusinessById(int businessId);
    void UpdateBusiness(Business business);
    void DeleteBusiness(Business business);
    IEnumerable<Business> GetBusinessesByUserId();
    IEnumerable<BusinessType> GetBusinessTypes();
    ...
    ...
    ...

Any time I need to do a CRUD/data access operation of any sort, I find myself doing the following:

  • Add the operation to the repository's interface
  • Implement and code the repository function
  • Add the operation to the service layer's interface
  • Implement and code the service function to call the above repository function

This is getting cumbersome, especially when there are multiple entities related to a particular service/repository. Multiply by multiple repositories and services throughout the application...

For background, I moved away from generic repositories to avoid the complexity of injecting multiple repositories left and right into service and/or controller constructors (or individual service functions).

It seems I am violating DRY, and constantly repeating myself. Is this as close as I can get, or is there a more efficient way to do this?? Thanks.

Was it helpful?

Solution

First. Service layer shouldn't repeat repository functions. Instead of UserService.UpdateUser function, there should be UserService.UpdateBasicData, UserService.UpdatePassword taking subset of User object fields. You generally shouldn't expose ORM layer objects in service. User object surely has many properties and UpdateUser function shouldn't change them, so it shouldn't mistake service consumer, that it may change them.

Second. You can still use generic repositories and make repository aggregation for injection. Example:

public class UserRelatedRepositories : IUserRelatedRepositories {
    IRepository<User> User { get; set; }
    IRepository<Business> Business { get; set; }
}

and then use

UserRelatedRepositories.User.Create()
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top