I am working on ASP.NET MVC3 solution that uses dependency injection with autofac. Our controllers are being created by autofac and properly and all required objects are being properly passed in. Those objects usually include services, repositories, and mappers converting domain object to MVC (view) models. So the controller constructor looks somewhat like:
public abcController(
ILogger logger,
IabcRepository abcRepository,
IabcService abcService,
IMapper<AbcDomain, AbcViewModel> abcMapper,
...
)
Unfortunately, in time, those constructor parameter lists tend to grow quite quickly. Some of our controllers expect now 60 or more parameters.
Did we create some anti-pattern here?
EDIT
I should have mentioned that we try to follow thin contoller pattern. Also most of those parameters tend to be mappers - around 66%. The control methods are usually very simple, and follow either this pattern:
Or this pattern:
I can't really speak to how you should rearchitect your controller, though I agree with most of the other answers - 60 incoming parameters is a lot.
Something that might help reduce the number of parameters but not the number of dependencies is the Aggregate Service support that Autofac has.
Instead of taking 60 parameters directly, you can take a single aggregate parameter that has 60 properties on it.
You create an interface (just the interface, you don't actually have to implement it) with the dependencies:
public interface IMyAggregateService
{
IFirstService FirstService { get; }
ISecondService SecondService { get; }
IThirdService ThirdService { get; }
IFourthService FourthService { get; }
}
Then modify your controller to take that aggregate interface:
public class SomeController
{
private readonly IMyAggregateService _aggregateService;
public SomeController(
IMyAggregateService aggregateService)
{
_aggregateService = aggregateService;
}
}
You can register your aggregate service interface, your dependencies, and your controller and when you resolve the controller, the aggregate service interface will automatically be implemented and resolved for you.
var builder = new ContainerBuilder();
builder.RegisterAggregateService<IMyAggregateService>();
builder.Register(/*...*/).As<IFirstService>();
builder.Register(/*...*/).As<ISecondService>();
builder.Register(/*...*/).As<IThirdService>();
builder.Register(/*...*/).As<IFourthService>();
builder.RegisterType<SomeController>();
var container = builder.Build();
Again, it doesn't speak to the larger issue of requiring that many dependencies, but if you are just looking to simplify your constructor and the number of properties on the controller so it's more manageable, this is one strategy Autofac offers to help in that.
Check out the wiki page for more details.
60 or more parameters is a lot.
In your question you stated "..Those objects usually include services, repositories, and mappers converting domain object to MVC (view) models..."
You've got a Fat Controller (not the Thomas The Task Engine kind) but a controller that is doing too much.
The balance I look for is Fat Model skinny controller. Ian Cooper talks about it well in this blog post
You can also look at things such as which parameters are actually cross cuttings concerns.
For instance Mapping and Logging in my mind are cross cutting concerns so you could potentially use Action Filters to clean up your controllers.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With