In most samples I have seen on the web, DI in MVC Controllers is done like this
public ProductController(IProductRepository Rep)
{
this._rep = Rep;
}
A custom ControllerFactory is used and it utilizes the DI framework of choice and the repository is injected.
Why is the above considered better than
public ProuctController()
{
this._rep = ObjectFactory.GetInstance<IProductRepository>();
}
This will get the same results but doesn't require a custom controller factory.
As far as testing is concerned the Test App can have a separate BootStrapper. That way when the controllers are being tested they can get the fake repositories and when they are used for real they will get the real ones.
Constructor injection (the first approach) is better than the service locator pattern (the second approach) for several reasons.
First, service locator hides dependencies. In your second example, looking at the public interface alone, there's no way to know that ProductControllers
need repositories.
What's more, I've got to echo OdeToCode. I think
IProductRepository repository = Mockery.NewMock<IProductRepository>();
IProductController controller = new ProductController(repository);
is clearer than
ObjectFactory.SetFactory(IProductRepository, new MockRepositoryFactory())
IProductController controller = new ProductController();
Especially if the ObjectFactory is configured in a test fixture's SetUp
method.
Finally, the service locator pattern is demonstrably sub-optimal in at least one particular case: when you're writing code that will be consumed by people writing applications outside of your control. I wager that people generally prefer constructor injection (or one of the other DI methods) because it's applicable for every scenario. Why not use the method that covers all cases?
(Martin Fowler offers a much more thorough analysis in "Inversion of Control Containers and the Dependency Injection Pattern", particularly the section "Service Locator vs Dependency Injection").
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