Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MVC DDD: Is it OK to use repositories together with services in the controller?

most of the time in the service code I would have something like this:

public SomeService : ISomeService
{
    ISomeRepository someRepository;
    public Do(int id)
    {
        someRepository.Do(id);
    }
}

so it's kinda redundant

so I started to use the repositories directly in the controller

is this ok ? is there some architecture that is doing like this ?

like image 820
Omu Avatar asked Aug 26 '10 12:08

Omu


People also ask

Can we use repository in controller?

When you instantiate the repository in your controller, you'll use the interface so that the controller will accept a reference to any object that implements the repository interface.

Should I call repository in controller?

The reason you should not deal with the repository at the controller level is for flexibility in your architecture and to prevent tightly coupling your service to your protocol or your implementation.

When should I use service and repository?

Repository layer is implemented to access the database and helps to extend the CRUD operations on the database. Whereas a service layer consists of the business logic of the application and may use the repository layer to implement certain logic involving the database.

Can a repository be used as a service?

You definitely can. It's precisely the goal of repositories.


1 Answers

You lose the ability to have business logic in between.

I disagree with this one.

If business logic is where it should be - in domain model, then calling repo in controller (or better - use model binder for that) to get aggregate root and call method on it seems perfectly fine to me.

Application services should be used when there's too much technical details involved what would mess up controllers.


I've seen several people mention using model binders to call into a repo lately. Where is this crazy idea coming from?

I believe we are talking about 2 different things here. I suspect that Your 'model binder' means using model simultaneously as a view model too and binding changed values from UI directly right back to it (which is not a bad thing per se and in some cases I would go that road).

My 'model binder' is a class that implements 'IModelBinder', that takes repository in constructor (which is injected and therefore - can be extended if we need caching with some basic composition) and uses it before action is called to retrieve aggregate root and replace int id or Guid id or string slug or whatever action argument with real domain object. Combining that with input view model argument lets us to write less code. Something like this:

public ActionResult ChangeCustomerAddress
 (Customer c, ChangeCustomerAddressInput inp){
  c.ChangeCustomerAddress(inp.NewAddress);
  return RedirectToAction("Details", new{inp.Id});
}

In my actual code it's a bit more complex cause it includes ModelState validation and some exception handling that might be thrown from inside of domain model (extracted into Controller extension method for reuse). But not much more. So far - longest controller action is ~10 lines long.

You can see working implementation (quite sophisticated and (for me) unnecessary complex) here.

Are you just doing CRUD apps with Linq To Sql or trying something with real domain logic?

As You can (hopefully) see, this kind of approach actually almost forces us to move towards task based app instead of CRUD based one.

By doing all data access in your service layer and using IOC you can gain lots of benefits of AOP like invisible caching, transaction management, and easy composition of components that I can't imagine you get with model binders.

...and having new abstraction layer that invites us to mix infrastructure with domain logic and lose isolation of domain model.

Please enlighten me.

I'm not sure if I did. I don't think that I'm enlightened myself. :)


Here is my current model binder base class. Here's one of controller actions from my current project. And here's "lack" of business logic.

like image 180
Arnis Lapsa Avatar answered Oct 21 '22 12:10

Arnis Lapsa