Related
I have some questions about DI containers (Unity in particular) and how they actually aid in DI.
I believe I understand IoC/DI and have been using constructor based DI for some years. Usually with my use of DI it involved simply having a constructor on my class, say MyClassX that takes an interface as an argument say IDataService and then using the new operator to create an instance of an IDataService implementing class and pass it into MyClassX's constructor. This way MyClassX doesn't need to know the exact type of the IDataService it is using decoupling it from a specific type. Now correct me if I am wrong, but that's what I understand DI to be...though it does not have to be constructor based.
Now I have seen a stack of examples of Unity on the net, but I am finding it difficult to not only understand everything it does (it seems like a magic object factory to me) but also how it exactly aids in DI as I understand it. To me Unity seems more like a Factory implementation (or a Mock framework?) rather than anything to do specifically with DI. I think I have really missed something though and am waiting for an "ah ha" moment. I have done alot of Googling but examples don't help... I need an theoretical explanation.
Can someone explain to me what Unity is exactly for...the broad points of what it does and how it is related to DI as I understand it.
Your understanding of basic Dependency Injection is correct. Constructor injection is the most common pattern.
Some other DI Unity does:
Lifetime management – instance creation can be singleton, one per
thread, and other advanced models.
Handles dependency graphs - request a root object and Unity creates all its dependency’s
dependencies.
Enables method and property injection – requires a
Unity attribute in your business code (which I prefer to avoid)
Service locator pattern – generally considered an anti-pattern
1 and 2 are nice when you need them. I think #3 and #4 are to be avoided when possible because it adds dependencies in your code to your Unity container.
The big bang that you are missing is Aspect Oriented Programing enabled by Interception with Unity. This allows the implementation of cross cutting concerns. Logging is the classic example. If you want more, start reading all the Enterprise Library Call Handlers for exception handling, validation, etc. or just start searching the web for AOP.
When you combine constructor injection of dependencies with external implementation of cross cutting concerns, you can get very close to business objects that only contain business logic. In a large Enterprise development team, that’s a very big bang.
When the object graph is simple you may not see the obvious advantages of using a DI container.
Say you have a class MyClassX which depends on IExampleA, IExampleB. Now the Implementation of IExampleA and IExampleB may depend on some other classes and so on. Now, this kind of object graph is complex to handle manually when it comes to materialized/instantiate it.
This is where DI comes into play. Once registered(class and its depended classes), All you need to do is,
var myclassX = _container.Resolve<MyClassX>()
And, don't get me wrong here, DI can provide much more than just resolving dependency. For example managing the LifeStyle and LifeCycle of objects etc.
I am sure 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.
There are some cases in which unit test don't work for the project.
I'm studing the Inversion of Control and Dependency Injection utilities and I would like to know if there are good reasons for use it than for make unit tests easier.
--update
Ok, let's analysis 1 of the cited advanteges: less coupling.
You take out the coupling from the child type, and you add coupling to the handler type who need to create the objects to inject.
Without unit testing, what's the advantage in this coupling transfer (not coupling eliminate).
IOC/DI bring some very important features to your application
Plugability: with DI you can inject dependency into the code without explicitly knowing how the functionality is actually working.
For example: your class might get a ILog interface injected so that it can write logs. Since the class works with the ILog interface, it would be possible to implement a FileLog, MemoryLog or a DatabaseLog & inject this into your class. Any of these implementation will work fine as long as they implement the ILog interface
Testability: With DI in your class, you can inject mock objects to test the behaviour of your class without actually needing the concrete implementation.
For example: consider a Controller class which needs a Repository to perform data operations. In this case, the repository can be DI for the controller. If you need to write tests on the Controller class, you can pass a DI'd mock version of the repository without having to work with the actual repository class
Configurability: Some of the common DI frameworks like Castle Windor, Unity, Spring etc., allow doing DI along with lifetime management of the object created. This is a very powerful feature & allow you to manage the dependencies & their lifetime via configuration. For example consider your application needs a ICache dependency. Via the configuration for lifetime & object management, you will be able to configure the cache to be a Per-application or per-session or per-request etc. without having to explicitly bake the implementation in your code.
HTH
IoC reduces coupling, which has a correlation with defect rates in some studies. (If that really long link doesn't work, it's to Software Engineering Quality Practices by Ronald Kirk Kandt.)
Sure, here are a few reasons:
Dynamic generation of proxies for remoting and transactons
Aspect oriented programming
Layering using interfaces and separation of implementation
Enough?
From the IoC wikipedia article:
There is a decoupling of the execution of a certain task from implementation.
Every system can focus on what it is designed for.
Every system does not make assumptions about what other systems do or should do.
Replacing systems will have no side effect on other systems.
While I would call the above feature list a bit vague, you see most of the above benefits, even without testing.
If I had to say it in a nutshell, I would say that IoC significantly improves separation of concerns which is a valuable goal in software development.
Yes, dependency injection helps you make your classes more focused, clearer*, and easier to change, because it makes it easier to adhere to the single-responsibility principle.
It also makes it easier to vary parts of your application independently of one another.
When you use constructor injection in particular, it's easier to tell what your code needs to do its job. If the WeatherUpdater class requires an IWeatherRepository in its constructor no one is surprised that it uses a database.
* Again, constructor injection only.
Heyho,
There´s a question in my mind for some time now, which hopefully can be cleared quickly by some of you:
I am a big fan of MVC, ASP.Net Mvc in my case.
What I have noticed is the hype about interfaces. Every video, tutorial and book seems to solve any kind of abstraction with interfaces. I have adapted these patterns, understood why and how and I am basically very happy with it.
But I just don´t get why interfaces are used everywhere. I´ve almost never seen some abstraction being done with abstract base classes, which I don´t understand. Maybe I miss something? I know that you can only inherit from one base class while multiple interfaces are possible. But interfaces do have disadvantages, especially when some changes need to be done, which breaks your implementations.
In my projects so far, I only used to pick interfaces for completely different classes.
For example, the whole repository pattern could be done with an abstract base class, still providing testability and exchangeability, or did I miss something?
Please point me to the part where my brain laggs :)
Interfaces are used in tutorials, blogs and elsewhere because those authors are particularly influenced by a group of methodology called "design for testability".
Primarily, design for testability school of thoughts used interface every way because they want to be able to mock any component under tests. If you use concrete class, then a lot of mocking tools can't mock those class, and hence will make it difficult to test your code.
A Story
I once attended a Java user group
meeting where James Gosling (Java's
inventor) was the featured speaker.
During the memorable Q&A session,
someone asked him: "If you could do
Java over again, what would you
change?" "I'd leave out classes," he
replied. After the laughter died down,
he explained that the real problem
wasn't classes per se, but rather
implementation inheritance (the
extends relationship). Interface
inheritance (the implements
relationship) is preferable. You
should avoid implementation
inheritance whenever possible.
While using only or mostly Interfaces does have code reuse problems(as well as eliminating nice base classes), It makes it a lot easier to do Multiple Inheritance like things. As well as having widely different implementations that will work and where you don't have to worry about the base class changing or even what it does(you do have to implement the whole thing though so its a trade off).
P.S. I think the new Go language is based on interfaces rather then inheritance(looks sort of interesting).
If the language doesn't support multiple inheritance or mix-ins abstract base classes are limited in scope compared to interfaces. E.g. in .NET if you must inherit from some other type such as MarshalByRef, you can't use an abstract base class to implement a pattern. Interfaces do not impose this restriction.
Besides the fact you mentioned that you can inherit from a single base class only (which is pretty inconvenient if you want to use an existing class that already inherits from some class with the new framework base class), you also avoid the fragile base class problem if you use interfaces instead.
Coding against interfaces makes your design more flexible and extensible. For instance, plugin frameworks and dependency injection. Without interfaces, the extensibility of it is pretty much limited.
Read about interfaces, abstract classes, breaking changes, and MVC here: http://ayende.com/Blog/archive/2008/02/21/Re-Versioning-Issues-With-Abstract-Base-Classes-and-Interfaces.aspx.
One solution that is presented there (or somewhere else on Ayende's blog) is: do use interface but also provide abstract classes. Those who case about breaking changes can base their implementations on abstract classes. Those who need power of interfaces are also satisfied. But do make sure your methods accept interfaces, not abstract classes, as input.
I've been using StructureMap recently and have enjoyed the experience thoroughly. However, I can see how one can easily get carried away with interfacing everything out and end up with classes that take in a boatload of interfaces into their constructors. Even though that really isn't a huge problem when you're using a dependency injection framework, it still feels that there are certain properties that really don't need to be interfaced out just for the sake of interfacing them.
Where do you draw the line on what to interface out vs just adding a property to the class?
The main problem with dependency injection is that, while it gives the appearance of a loosely coupled architecture, it really doesn't.
What you're really doing is moving that coupling from the compile time to the runtime, but still if class A needs some interface B to work, an instance of a class which implements interface B needs still to be provided.
Dependency injection should only be used for the parts of the application that need to be changed dynamically without recompiling the base code.
Uses that I've seen useful for an Inversion of Control pattern:
A plugin architecture. So by making the right entry points you can define the contract for the service that must be provided.
Workflow-like architecture. Where you can connect several components dynamically connecting the output of a component to the input of another one.
Per-client application. Let's say you have various clients which pays for a set of "features" of your project. By using dependency injection you can easily provide just the core components and some "added" components which provide just the features the client have paid.
Translation. Although this is not usually done for translation purposes, you can "inject" different language files as needed by the application. That includes RTL or LTR user interfaces as needed.
Think about your design. DI allows you to change how your code functions via configuration changes. It also allows you to break dependencies between classes so that you can isolate and test objects easier. You have to determine where this makes sense and where it doesn't. There's no pat answer.
A good rule of thumb is that if its too hard to test, you've got some issues with single responsibility and static dependencies. Isolate code that performs a single function into a class and break that static dependency by extracting an interface and using a DI framework to inject the correct instance at runtime. By doing this, you make it trivial to test the two parts separately.
Dependency injection should only be used for the parts of the
application that need to be changed dynamically without recompiling
the base code
DI should be used to isolate your code from external resources (databases, webservices, xml files, plugin architecture). The amount of time it would take to test your logic in code would almost be prohibitive at a lot of companies if you are testing components that DEPEND on a database.
In most applications the database isn't going to change dynamically (although it could) but generally speaking it's almost always good practice to NOT bind your application to a particular external resource. The amount involve in changing resources should be low (data access classes should rarely have a cyclomatic complexity above one in it's methods).
What do you mean by "just adding a property to a class?"
My rule of thumb is to make the class unit testable. If your class relies on the implementation details of another class, that needs to be refactored/abstracted to the point that the classes can be tested in isolation.
EDIT: You mention a boatload of interfaces in the constructor. I would advise using setters/getters instead. I find that it makes things much easier to maintain in the long run.
I do it only when it helps with separation of concerns.
Like maybe cross-project I would provide an interface for implementers in one of my library project and the implementing project would inject whatever specific implementation they want in.
But that's about it... all the other cases it'd just make the system unnecessarily complex
Even with all the facts and processes in the world.. every decision boils down to a judgment call - Forgot where I read that
I think it's more of a experience / flight time call.
Basically if you see the dependency as a candidate object that may be replaced in the near future, use dependency injection. If I see 'classA and its dependencies' as one block for substitution, then I probably won't use DI for A's deps.
The biggest benefit is that it will help you understand or even uncover the architecture of your application. You'll be able to see very clearly how your dependency chains work and be able to make changes to individual parts without requiring you to change things that are unrelated. You'll end up with a loosely coupled application. This will push you into a better design and you'll be surprised when you can keep making improvements because your design will help you keep separating and organizing code going forward. It can also facilitate unit testing because you now have a natural way to substitute implementations of particular interfaces.
There are some applications that are just throwaway but if there's a doubt I would go ahead and create the interfaces. After some practice it's not much of a burden.
Another item I wrestle with is where should I use dependency injection? Where do you take your dependency on StructureMap? Only in the startup application? Does that mean all the implementations have to be handed all the way down from the top-most layer to the bottom-most layer?
I use Castle Windsor/Microkernel, I have no experience with anything else but I like it a lot.
As for how do you decide what to inject? So far the following rule of thumb has served me well: If the class is so simple that it doesn't need unit tests, you can feel free to instantiate it in class, otherwise you probably want to have a dependency through the constructor.
As for whether you should create an interface vs just making your methods and properties virtual I think you should go the interface route either if you either a) can see the class have some level of reusability in a different application (i.e. a logger) or b) if either because of the amount of constructor parameters or because there is a significant amount of logic in the constructor, the class is otherwise difficult to mock.