what's the point of Dependency Injection Frameworks?
I am s开发者_如何学Pythonure that I am somewhat lost in this area... my understanding is that Dependency Injection means initializing something that is required by a class..so for instance. If my controller is going to need a service and I want to be able to test it then I should define two Constructor methods for it... so, my question is... why do people use Frameworks to achieve this?? Im lost
public class CompaniesController : Controller
{
private ICompaniesService _service;
public CompaniesController()
{
_service = new CompaniesService();
}
public CompaniesController(ICompaniesService service)
{
_service = service;
}
A major reason is to better support unit testing and mocking out objects to create controlled tests.
By not specifying the implementation inside the class, you can 'inject' an implementation at run time. (In your example, the ICompaniesService interface).
At runtime, using an inversion of control/dependency injection container such as StructureMap, Unity or Castle Windsor, you can say "hey, anytime someone wants an instance of ICompaniesService give them a new CompaniesService object".
To unit test this class, you can mock our a ICompaniesService and supply it yourself to the constructor. This allows you to setup controlled methods on the mock object. If you couldn't do this, your unit tests for CompaniesController would be limited to using only the one implementation of your companies service, which could hit a live database etc, making your unit tests both slow and inconsistent.
People don't use a Dependency Injection Framework to generate the code that you provided in your example. That's still the work of the developer.
The Dependency Injection Framework is used when somebody calls the constructor. The Framework will Inject the concrete implementation of the ICompaniesService rather than the developer explicitly calling the constructor.
While it is a specific product, the nInject Homepage actually has some really good examples.
From Wikipedia:
Without the concept of dependency injection, a consumer who needs a particular service "ICompaniesService" in order to accomplish a certain task would be responsible for handling the life-cycle (instantiating, opening and closing streams, disposing, etc.) of that service. Using the concept of dependency injection, however, the life-cycle of a service is handled by a dependency provider/framework (typically a container) rather than the consumer. The consumer would thus only need a reference to an implementation of the service "ICompaniesService" that it needed in order to accomplish the necessary task.
Read this one too:
What is dependency injection?
People use Dependency Injection frameworks because otherwise you have to write a metric ton of boring, repetitive factory classes (if using dependency injection, that is).
It can be done, it's just very, very annoying.
I think your understanding is only partly correct. Dependency Injection is "injecting" a dependency of a component into it. Its a more specific form of inversion of control. During this process some dependencies can also be initialized before injecting.
With DI, the onus of looking up the dependency is not on the component (as in ServiceLoacator pattern) but upto the container in which the component is running. The pattern has following advantages:
- Dependency lookup code can be eliminated from the component.
- Some frameworks providing auto-wiring, injecting saving you from manually creating your component hierarchies (Answers one of your questions)
- Allows you to interchange implementations of your dependencies. (without using Factories)
- Testing (replacing dependencies with mock implementations)
In your code example, a dependency can be injected by a DI container at runtime via the second constructor. Other forms of injections are also possible (depending on the DI container). e.g. Field injection, setter injection, etc.
There's a good article by martin fowler who coined the DI term
You dont have to have a DI framework, but at some point in your codebase a concrete implementation is going to need to be instantiated and injected into your constructors/properties. It can get very messy if you dont have a DI framework, I recommend looking at Castle Windsor although as mentioned there are others that will perform the same functionality. Or if you could role your own....:)
I'll pitch in:
You can accomplish dependency injection simply by having a parameterized function definition.
However, in order to make that work consistently, everyone has to actually do that. Many find that's its easier to enforce the convention by using a factory design pattern.
Dependency injection frameworks solve the problem of reducing the boilerplate of writing those factories.
I would say that dependency injection through a factory, is non-ideal. In my opinion factories add an extra layer of indirection and in a sense make deterministic functions in-deterministic in the sense that they are now a function of the inputs, plus state from the rest of the program (your di setup) which you cannot see from the function definition alone. Factories make code harder as they add an extra layer of indirection I'd argue that in many cases it's really not too hard to follow the convention and manually inject classes via the function arguments. Again though, for a large codebase, it's probably easier to enforce the rule through a factory.
..that being said sometimes I do wonder if these large codebases would even be this large if they didn't write so many things which try to preemptively solve problems that they don't have in the first place.
精彩评论