MediatR & Controllers | DI Constructor Madness

Long Parameter List is absolutely a bad design, e.g.

public DashboardController( ICustomerRepository customerRepository, IOrderService orderService, ICustomerHistoryRepository historyRepository, IOrderRepository orderRepository, IProductRespoitory productRespoitory, IRelatedProductsRepository relatedProductsRepository, ISupportService supportService, ILog logger ) 

Normally, more than 5 dependencies is too many.

Does MediatR helps us to avoid this smell? Let’s see

public class UserController : Controller { private readonly IMediator _mediator; public UserController(IMediator mediator) { _mediator = mediator; } [HttpPost] public ActionResult Register(RegisterUser registerUser) { bool registered = _mediator.Send(registerUser); return View(); } } 

A very tiny controller, isn’t it? And the only dependency is IMediator.

So at first glance it all seems pretty cool, but MediatR uses Service Locator. And it’s definitely bad design.

Reading this article on StackOverflow

All MediatR does is service locate a handler for a request. That is not the mediator pattern. The “mediator” in this instance, does not describe how two objects communicate, it uses inversion of control that is already being used in an application and just provides a useless layer of abstraction that only serves to make an application harder to reason about as a whole. You already achieve decoupling by using standard constructor injection with IoC. I don’t understand why people buy into this. Let’s create multiple composite roots just so we don’t have to put interfaces in our constructor.

Now, pay attention to this particular bit

it uses inversion of control that is already being used in an application and just provides a useless layer of abstraction

So, the bottomline is: MediatR is next to useless.

Just one simple thing

If you want to avoid DI Constructor Madness – just split DashboardController into several smaller controllers whose name starts with Dashboard~ and inject fewer dependencies into each.

And design your service classes so that stuff like ILogger is injected into those services, rather than into one controller along with all those services.

Really, we must be designing small service classes and injecting them into controllers via Constructor Injection in order to avoid Service Locator.

You can rename those service classes so they end with ~Handler and continue implementing CQRS just as you did.

Your Handlers are injected into tiny controllers and they accept parameters whose types end with ~Query / ~Command.

Too many controllers? I know. But it’s still better than Service Locator.

submitted by /u/alexherman_rdt
[link] [comments]

Leave a Reply