So 99% of all DI examples using the Repository pattern with MVC (or Web API), show something similar to this below in a controller action (left out constructor injection code for _repository). The issue is there is the assumption that nothing needs to be processed 1st (like rules) and commencing persistence occurs immediately:
public ActionResult Create(Person person)
{
if (ModelState.IsValid)
{
_repository.Add(person);
}
return View(person);
}
The problem is, what if I need to process rules in the domain layer before persisting the person object? Obviously I don’t do that logic in the Controller, but rather need it in the domain layer. Which option below is better:
Option 1: Relegate all persistence details on the repository to be called in the domain / business layer and pull out of the controller. The updated code would look like this:
if (ModelState.IsValid)
{
using (busniessLogic = new MyApp.BusniessLogic(_repository))
{
busniessLogic.ProcessRulesAndSavePerson(person);
}
}
The domain layer might have a method like this:
public void ProcessRulesAndSavePerson(Person person)
{
//process some rules...
if(rules = true)
{
//use injected repository to add now that rules have passed
_repository.Add(person)
}
}
Option 2: Keep the same as now in the Controller, but just make a call to process the rules prior to saving on the repository. Updated code is like below:
if (ModelState.IsValid)
{
using (busniessLogic = new MyApp.BusniessLogic())
{
busniessLogic.ProcessRulesAboutPerson(person);
_repository.Add(person)
}
}
I’m open to other ideas too, but I am leaning toward Option #1. I like to keep the Controller thin and just pass along the injected _repository to the layer requiring it.
Any help on this is appreciated, thanks!
Both options will create a dependency on the business logic processor, you always have to be careful when using the
newkeyword because when you try to unit test your method, you almost always will run into problems, and that defeats the purpose of dependency injection.You are better of creating a service that handles complicated business logic and injecting that into your controller. If most of your logic is complicated, I would just skip passing the repository to the controller all together and just depend on the service to handle everything for me.
Controller:
PersonService: