Why putting a container in a constructor is so bad? For example you want to resolve a class B in the constructor of another class (C) because you need the class (B) to be used with the dependencies resolved (you start using class C the way you want it like it were B but with the dependencies resolved).
Why putting a container in a constructor is so bad?
I suppose you mean to pass the container as a constructor argument. This is actually a variation of the Service Locator pattern, which in this context is considered to be an anti pattern. There are a couple of reasons why you may not want to do this.
First, the users of your class will only know that the class needs a container for resolving its dependencies. This amount of information is equal to no information at all, because you still don't know what the class is going to depend on. Do you want to write a unit test for the class? You have to look inside the class and see what types it is resolving, mock them and initialize the container for every test. This also means that changes on some code will let it compile but may break some tests: this is the case when the new code relies on a class which is not yet registered in the container, for instance.
A secondary effect which is common when using Service Locator is that you can never be sure that you won't be getting an exception at runtime while asking for dependencies. Is every class registered correctly? While some containers offer the possibility to check if every interface is registered, it doesn't mean it is registered to the correct type. For instance, it could happen that a type is registered twice with two different implementations and it is going to be difficult to notice if any piece of code could call the container.
A better solution to this is the Composition Root pattern. This blog post also explains why Service Locator may not be a good idea.
EDIT in light of the new developments:
Apparently you are using a third party library which relies on your classes having a default constructor. Let us assume that you have no way to influence the instantiation of your classes and that you have to let this framework do its job. Be aware that this may be a big assumption, please investigate the third party library for possibilities to do it first. At first glance, frameworks like ASP.NET WebForms and WCF don't give you many chances, but there are ways to ease the pain for these cases.
I meant just to create the container in the constructor, add the
respective dependency to the container and resolve the object, which
can be done by simply creating instance of the dependency object and
use it to create the dependent object.
I may be missing something, but why do you need to register the dependency in the constructor? Couldn't you just resolve it in the constructor but register it somewhere else? That would still be a Service Locator, but you would at least be doing the wrong thing right.
Why doing so in the constructor is a bad idea and doing so elsewhere
is fine?
Doing so anywhere but in one place is a bad idea. Why would you spread your container registration all over the place? If you really feel the need to decide what implementation of an interface to use at runtime, use something like a Factory.
So, why is it bad?
the client class depends on both implementation and interface, which doesn't make it better than newing the concrete class in the constructor.
the client class now also depends on the container, and the issues of Service Locator arise (see above), making now this approach worse than newing the concrete class.
As #Steven said, you lose all advantages of Dependency Injection. The real underlying question is: why do you absolutely want to do DI in this place? What advantages of the approach would you like to use? Based on the answer there could be several solutions. Two examples off the top of my head:
Solution 1: lose the DI for the classes being instantiated by the third party library.
Solution 2: Use a combination of Bastard Injection + Service Locator. Two wrongs could make a right in this case.
public class MyClass
{
public MyClass()
: this(Container.Resolve<IDependency>())
{
}
public MyClass(IDependency dep)
{
}
}
In this case you are not using a non-local dependency in the constructor, because it is resolved by the Service Locator, so you have no dependencies on the implementation.
Related
When should I use property injection?
Should I use by default constructor injection if instance creation in fully controlled?
Am I right that using a constructor injection I write container-agnostic code?
When should I use property injection?
You should use property injection in case the dependency is truly optional, when you have a Local Default, or when your object graph contains a cyclic dependency.
Property Injection however causes Temporal Coupling and when writing Line of Business applications, your dependencies should never be optional: you should instead apply the Null Object pattern.
Neither should you use a Local Default, which is:
"A default implementation of an abstraction that's defined in the same assembly as the consumer." [DIPP&P, Section 4.2.2]
Local Defaults should not be used in Line of Business applications, because it complicates testing, hides the dependency, and makes it easy to forget to configure the dependency.
Neither should object graphs have cyclic dependencies. This is an indication of a problem in your application design.
Should I use by default constructor injection if instance creation in fully controlled?
Yes. Constructor injection is the best way. It makes it very easy to see which dependencies a class has, makes it possible to make dependencies required, and prevents Temporal Coupling.
Am I right that using a constructor injection I write container-agnostic code?
This is correct. Constructor injection allows you to delay the decision of which DI library to use, and whether at all you use a DI library.
For a more detailed explanation of the above, and much more, read the book Dependency Injection Principles, Practices, and Pattern (DIPP&P) by Mark Seemann and myself.
The usefulness of property injection is so limited, that while working on the book, Mark and I even discussed labeling Property Injection an anti-pattern. In the end we felt we couldn't make a case that was as strong as, for instance, Ambient Context, which we did decide to describe as an anti-pattern in that edition. The case for Ambient Context was crystal clear, while being much muddier for Property Injection. But this is why, however, we added many warning notes to the Property Injection section (4.4), because we feel strongly Property Injection is not a good solution for the majority of cases.
There are several problems, though, that Property Injection seems to solve at first, such as the problem of Constructor Over-Injection (where a constructor contains many dependencies). Constructor Over-Injection, however, is almost always caused by design deficits, such as:
Class having too many responsibilities
Lack of natural clusters
Choosing inheritance over composition
Application of Cross-Cutting Concerns through base classes instead of Decorators or Interceptors
The accepted answer argues in favor of constructor injection and takes a rather critical stance toward property injection. As such, it does not put focus on addressing the problems that property injection actually solves, if used correctly. Therefore I want to take the opportunity to address some of these points and also to provide some counter arguments to the accepted answer.
When should I use property injection?
Imagine you have a project with 100+ controllers and all those controllers are extending a custom base controller (parent-service). In such a situation, where a service is extended by several child-services, employing constructor injection is a burden: For every constructor you create, you need to relay arguments to your parent-service's constructor. If you decide to extend your parent service's constructor signature you will also be forced to extend the signatures of all child-services' constructors.
To make this example more vivid, say you start your project with a base controller having a parameterless constructor.
Now after a month you decide you want a logger service in your base controller. → Not only will you have to change the base controller constructor's signature but also those of your 100+ child controllers.
Now again after a month you need access to a user service in your base controller → Again, you'll have to change the constructor signature of your 100+ child controllers.
you get the point...
With property injection you can easily circumvent this whole inconvenience by simply adding the necessary properties to your parent service and letting your DI-mechanism handle the injection via reflection. As a side effect, this also greatly reduces the risk of merge conflicts (since the files touched is reduced to a minimum).
So far, I have been talking mostly about controllers but this example counts for any situation in which you have a service hierarchy – the deeper or broader this hierarchy gets, the greater the burden of constructor injection. However, avoiding service-hierarchies altogether may not always be a reasonable choice in a project.
One could say the decision between property and constructor injection is really a decision between a pragmatism and OOP "purism".
From a "purist" OOP perspective, the rule is (as stated in the accepted answer) to initialize all required fields of a class via its constructor in order to avoid granting any access to the newly created instance in an "unfinished" state (which may result in an exception being later thrown).
With reference to this rule, an OOP-purist has a valid point in saying that property injection (temporarily) leaves your services in an "unfinished" state (the timespan between when your constructor has returned and the moment your property is injected) and that this increases the risk that your application may break.
However, when talking about services managed by an IoC/DI container, this risk is practically reduced to zero if you consider that your DI-mechanism is responsible for resolving the dependency graph and wiring everything up before any user-action or api-request actually makes it into your system or needs being processed. For example, at the time a controller's action is invoked you can be sure that your services were properly wired up and injected into your controller's properties (given of course, that you configured them correctly in advance).
Also the argument that it is only possible with constructor injection to make your dependencies "required" is rather weak in a world where you are not responsible for manually injecting services into your classes but delegate this task to your IoC mechanism. Even worse, you may get a false sense of security because you stated via constructor that a ServiceX requires ServiceY – but if you forgot to register your ServiceY with your DI-mechanism, you merely get null injected into your ServiceX's constructor.
Another "argument" against property injection is that it becomes harder for your fellow programmers to distinguish between properties that are managed by the DI mechanism and those which are simply non-DI-related. However, in this case you can just use a marker attribute to "opt-in" for DI or add short comments above your properties to clear things up, when the case is not clear. Also, in a service-class, it is rather unusual to have properties referring to other services that are not supposed to be manged by your DI mechanism.
Finally, as for saying that constructor injection makes unit testing easier (since you know what dependencies are required by a class), I would simply argue, that with property injection you will soon enough notice that you forgot to include a dependency when your tests begin to fail due to a certain service being undefined.
Should I use by default constructor injection if instance creation in fully controlled?
With all the above being said, I think I can answer your second question with: Not necessarily.
It depends on your project's size, the kind of service-hierarchy you employ, how often your parent-services' dependencies change and how much time and resources you are willing to invest in managing parameters and passing arguments up the service-hierarchy.
Am I right that using a constructor injection I write container-agnostic code?
Yes! – Under the premise that you are not injecting the container itself... which you shouldn't! ;)
All the above being said, here are some quotes from Martin Fowler's great discussion on dependency injection directly addressing the question of constructor vs setter/property injection, and I can fully subscribe to the last quote :)
If you have multiple constructors and inheritance, then things can get particularly awkward. In order to initialize everything you have to provide constructors to forward to each superclass constructor, while also adding you own arguments. This can lead to an even bigger explosion of constructors.
Despite the disadvantages my preference is to start with constructor injection, but be ready to switch to setter injection as soon as the problems I've outlined above start to become a problem.
This issue has led to a lot of debate between the various teams who provide dependency injectors as part of their frameworks. However it seems that most people who build these frameworks have realized that it's important to support both mechanisms, even if there's a preference for one of them.
A final remark: If you, for some reason, want to switch back from property injection to constructor injection, no problem, you can always add a constructor with the parameters to be injected and assign the properties via your constructor – dead-simple.
Suppose I have a BaseForm which depends on an ILogger or IResourceManager or something like that. Currently it resolves the correct implementation of the required service using the service locator which I know is an anti-pattern.
Is using the constructor injection the right way to resolve this kind of dependency?
Do I have to register my BaseForm (and its' derived types) in the container in order to create instances of them with resolved dependencies? Doesn't that complicate everything?
Is it bad to use a static factory wrapped around a service locator?
Unit-testing aside, will I really be punished because of using service locator anti-pattern?
Sorry about asking many questions at once. I've read the following SO questions and many others but reading them only added to my confusion:
How to use Dependency Injection and not Service Locator
What's the difference between the Dependency Injection and Service Locator patterns?
How to avoid Service Locator Anti-Pattern?
If possible, you should always go with dependency injection, since it has a few clear strength. With UI technologies however, it is not always possible to use dependency injection, since some UI technologies (in .NET space, Win Forms and Web Forms, for instance) only allow your UI classes (forms, pages, controls, etc) to have a default constructor. In that case you will have to fall back to something else, which is service locator.
In that case I can give you the following advice:
Only fall back to Service Locator for UI classes that can't be created by your container using dependency injection, and for stuff that you aren't unit testing anyway.
Try to implement as less logic as possible in those UI classes (as Humble objects with only view related stuff). This allows you to unit test as much as possible.
Wrap the container around a static method to hide the container from the rest of the application. Make sure that a call to this static method fails, when the dependency cannot be resolved.
Resolve all dependencies in the (default) constructor of that type. This allows the application to fail fast when one of its dependencies cannot be resolved when that type is created, instead of later on when some button is clicked.
Check during app start-up (or using a unit test), if all those UI types can be created. This saves you from having to go through the whole application (by opening all forms) to see if there is an error in the DI configuration.
When types cannot be built by the container, there is no reason to register them in the container. If they can be created by the container (such as with ASP.NET MVC Controller classes), it can be useful to register them explicitly, because some containers allow you to verify the configuration up front, which will detect configuration errors in those types right away.
Besides unit testing, there are two other important arguments against the use of the Service Locator, which are given by Mark Seemann in his famous blog post Service Locator is an Anti-Pattern:
Service Locator "hides a class’ dependencies, causing run-time errors instead of compile-time errors"
Service Locator is "making the code more difficult to maintain"
I am trying to figure out how to create multiple objects when using Dependency Injection. As far as I understand the standard approach is to inject a Factory which is then used to create the objects. The part I struggle with is how the Factory creates the objects. So far I see two possible solutions:
The Factory just uses new() to create the object.
Isn't DI supposed to free me of the use of new for non value objects?
What happens if the Object to be created has dependencies that could be resolved by the IoC?
Use the Container as Serviclocator
solves the problems of just newing objects at the cost of introducing an antipattern or is it no longer an antipattern if the use of the serviclocater is constraind within the factories?
It feels like i can coose between a bad and a bad solution. Is there something I am missing or do I understand somthing wrong here?
Edit Currently I am not using an Ioc at all but thinking about Ninject. Although the Autofac DelegateFactories sound very promising.
For starters, I don't consider using a container as service locator in factories an anti-pattern. There are genuine circumstances where it is entirely appropriate. Come to think about it, container aware factories are really container extensions, and those seem to be excluded from service locator bashing. Even the most pure IoC frameworks like AutoFac or Ninject have extensive extension capabilities. A most typical use case for this pattern is resolving to different implementations based on where the service is used.
With regards to using new to create instances inside factories, that is acceptable as well. The IoC/DI message got a bit distorted there and never using new is really a side effect, rather than the goal of DI. The first imperative of Dependency Injection is to externalise creation of dependencies from the component. A factory satisfies that imperative as long as it itself gets injected into component. The questions you need to ask yourself when evaluating such scenarios are:
Does the component itself create its dependencies? A: No, the factory does.
Can you make the component work with different dependencies without modifying it? A: Yes, by injecting a different factory.
I said this before, IoC containers are just factories on steroids. For 80% use case they work out of the box. The other 20% might require tweaks of the above two varieties. I tend to use container aware factories when I want to create components that require both registered dependencies and some input at run-time and new-ing factories when I create Domain objects that don't have dependencies on other services, but take all their construction parameters at run time.
Although the interface for your factory will be defined at the application level, you would typically define the implementation of that factory class close to your DI configuration, thus as part of your composition root. Although calling the container directly from your code is an implementation of the Service Locator anti-pattern, any code that is defined inside the compostion root is merely mechanics and is therefore not Service Locator. As long as newing up objects or calling into the container is done inside (or very close to) the composition root, this is not a problem, because the application will still be clean from any locator / container.
In other words: use the factory approach. Whether or not you need to new up objects directly inside your factory or make use of the container, depends on the objects. Letting the container create the objects is preferable, especially when they got dependencies on their own, but not all objects can be created by the container. In that case you need to revert to the new operation. Both are fine when the code is part of the composition root and not of the application. The factory itself can have dependencies of its own. This should not be a problem. You can let the container wire-up the factory instance.
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.
I'm fairly new to the DI concept, but I have been using it to some extent in my designs - mainly by 'injecting' interfaces into constructors and having factories create my concrete classes. Okay, it's not configuration-based - but it's never NEEDED to be.
I started to look at DI frameworks such as Spring.NET and Castle Windsor, and stumbled across this blog by Ayende.
What I got from this is
A) DI frameworks are awesome, but
B) It means we don't have to worry about how our system is designed in terms of dependencies.
For me, I'm used to thinking hard about how to loosely-couple my system but at the same time have some sort of control over dependencies.
I'm a bit scared of losing this control, and it being just a free-for-all. ClassA needs ClassB = no problem, just ask and ye shall receive! Hmmm.
Or is that just the point and this is the future and I should just go with it?
Thoughts?
One basic OO principle is that you want your code to depend on interfaces and not implementations, DI is how we do that. Historically, here is how it evolved:
People initially created classes they depended upon by "new'ing" them:
IMyClass myClass = new MyClass();
Then we wanted to remove instantiation so there were static methods to create them:
IMyClass myClass = MyClass.Create();
Then we no longer depended on the lifecycle of the class, but still depended on it for instantiation, so then we used the factory:
IMyClass myClass = MyClassFactory.Create();
This moved the direct dependency from the consuming code to the factory, but we still had the dependency on MyClass indirectly, so we used the service locator pattern like this:
IMyClass myClass = (IMyClass)Context.Find("MyClass");
That way we were only dependent on an interface and a name of a class in our code. But it can be made better, why not depend simply on an interface in our code? We can with dependency injection. If you use property injection you would simply put a property setter for the interface you want in your code. You then configure what the actual dependency is outside of your code and the container manages the lifecycle of that class and your class.
I wouldn't say that you don't have to think about dependencies, but using an IoC framework allows you to change the types which fulfill the dependencies with little or no hassle, since all the wiring is done in a central place.
You still have to think about what interfaces you need and getting them right is not always a trivial matter.
I don't see how a loosely coupled system could be considered lazily designed. If you go through all the trouble of getting to know an IoC framework, you're certainly not taking the shortcut.
I think that ideally, if you already have a loosley coupled system.., using a container will only move the place where you take the dependencies out of your code making them softer and let your system depend on the container building your object graph.
In reality, attempting to use the the container will probably show you that your system is not as loosley coupled as you thought it was.. so in this way, it may help you to create a better design.
Well, i'm a newbie at this subjet.. so maybe i'm not that right.
Cheers.
I must be high, because I thought the whole point of dependency injection is that the code that does stuff simply declares its dependencies so that someone who's creating it will know what to create with it for it to operate correctly.
How dependency injection makes you lazy is maybe it forces someone else to deal with dependencies? That's the whole point! That someone else doesn't need to be really someone else; it just means the code you write doesn't need to be concerned with dependencies because it declares them upfront. And they can be managed because they are explicit.
Edit: Added the last sentence above.
Dependency injection can be a bit difficult to get used to - instead of a direct path through your code, you end up looking at seemingly unconnected objects, and a given action traces it's path through a series of these objects whose coupling seems, to be kind, abstract.
It's a paradigm shift similar to getting used to OO. The intention is that your objects are written do have a focused and single responsibility, using the dependent objects as they're declared by the interface and handled by the framework.
This not only makes loose coupling easier, it makes it almost unavoidable, or at least nearly so, which makes it much simpler to do things like run your object in a mock environment - The IOC container is taking the place of the run environment.
I would disagree and say they lead to better design in many cases. Too often devs create components that do too much and have too many dependencies. With IOC developers i find tend to migrate to a better way of thinking and produce smaller simpler components that can be assembled together into an app.s
If they follow the spirit and do tests, they will further refine your components. Both exercises force you to write better testable components which fits very well with how IOC containers work.
You still have to worry. My team use Castle Windsor in our current project. It annoys me that it delays dependency lookup from compile time to runtime.
Without Castle Windsor, you write code and if you haven't sorted your dependencies out. Bang, the compiler will complain. With Castle Windsor you configure the dependencies in an xml file. They're still there, just separated out from the bulk of your code. The problem is, your code can compile fine if you make a mess of defining the dependencies. But, at runtime, Castle Windsor looks up a concrete classes to service requests for an interface by using reflection. If the dependency can't be found, you get an error at runtime.
I think Castle Windsor does check the dependencies exist when its initialized so that it can throw an error pretty quick. But, it's still annoying when using a strongly typed language that this fuss can't be sorted out at runtime.
So... anyway. Dependencies still seriously matter. You'll all most certainly pay more attention to them using DI than before.
We wrote custom DI framework, thought it took some time getting it right but it all worth the effort. We have divided the who systems into layers and the dependency injection in each layer is bound by rules. E.g. In the Log layer, CUD and BO interfaces cannot be injected.
We are still contemplating over the rules and some of these change every week while the others are remain the same.