Why is the container placement in the constructor so bad?
I assume that you want to pass the container as an argument to the constructor. This is actually a variant of the Service Locator pattern, which in this context is considered an anti-pattern. There are several reasons why you cannot do this.
First, users of your class will only know that the class needs a container to resolve its dependencies. This amount of information is not equal to any information, because you still do not know what the class will depend on. Do you want to write unit test for a class? You should look inside the class and see what types it allows, mock them and initialize the container for each test. It also means that changes to some code will allow it to compile, but may violate some tests: this is the case when the new code relies on a class that is not yet registered in the container, for example.
The secondary effect, which is common when using the Service Locator, is that you can never be sure that at runtime you will not get an exception when querying dependencies. Is each class registered correctly? Although some containers offer the ability to check whether each interface is registered, this does not mean that it is registered to the correct type. For example, it may happen that a type is registered twice with two different implementations, and it will be difficult to see if any piece of code can call the container.
The best solution for this is the Root composition template . This blog post also explains why Service Locator might not be a good idea.
EDIT in the light of new developments:
Apparently you are using a third-party library that relies on your classes having a default constructor. Suppose you have no way to influence the creation of your classes and that you must allow this structure to do its job. Keep in mind that this can be a big guess, please study the third-party library for the opportunity to do this first. At first glance, frameworks such as ASP.NET WebForms and WCF do not give you much chance, but there are ways to ease the pain for these cases.
I meant just to create a container in the constructor, add the appropriate dependency on the container and the resolution of the object, which can be done simply by creating an instance of the dependency object and use it to create the dependent object.
Maybe something is missing for me, but why do you need to register the dependency in the constructor? Could you just enable it in the constructor, but register it somewhere else? It will still be a service locator, but at least you're wrong.
Why is this happening in the constructor - is it a bad idea and does it good elsewhere?
Doing it anywhere, but in one place is a bad idea. Why do you need to distribute your container registration throughout the site? If you really feel the need to decide which interface implementation to use at run time, use something like Factory.
So why is this bad?
- the client class depends on both the implementation and the interface, which does not make it better than the new class in the constructor.
- now the client class also depends on the container, and there are problems with the Locator Service (see above), which makes this approach worse than the new class.
As @Steven said, you are losing all the benefits of Injection Dependency. The real main question: why do you absolutely want to do DI in this place? What advantages of this approach would you like to use? Based on the answer, there may be several solutions. Two examples from the head:
Solution 1 : lose DI for classes created by a third-party library.
Solution 2 Use the combination of Bastard Injection + Service Locator. In this case, two mistakes can make a right.
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 allowed by the service locator, so you have no implementation dependencies.