1
votes

I have a big class hierarchy. When my app starts, I initialize UnityContainer object and configure it. After that I always passing it through constructors to another classes in hierarchy. Something like this :

Unity container has these classes as Registrations: IClassA, IClassB, IClassC, IClassD

All concrete implementations of interfaces have constructor with IUnityContainer parameter. For example,

    public class ClassA : IClassA
    {

        public ClassA(IUnityContainer unityContainer)
        {
        }
    }

So, every time when I'm creating a new instance of some class I must pass an object of IUnityContainer.

May I reduce amount of passing IUnityContainer object as constructor's parameter? Maybe by using Dependency attribute ?

2
Why are you passing the container to the constructors? This is a really bad code smell. - Jon

2 Answers

8
votes

Yes, you should reduce it.

You should reduce it to 0.

Using DI container like this is a bad practice. Don't treat DI container as a magical super factory.

You should only use the container to make it easier to compose your application at the composition root: read this

Your code shouldn't be aware that it is composed with a DI container, container is just a technology while DI is a technic. You should be able to compose your application without a container too.

So, how you can reduce it? Like this:

public class ClassA : IClassA
{
    public ClassA()
    {
    }
}

Then if your ClassA needs something (a dependency, an interface), then you should inject that via constructor for example.

public class ClassA : IClassA
{
    private readonly IComponent _component;        

    public ClassA(IComponent component)
    {
        _component = component;
    }
}

You can use another injection patterns too: property injection, method injection, ambient context.

If you use a container like in your question then you hide all the dependencies of the actual class. You can't figure out what that actual class needs to work because it will use the container to resolve something ad-hoc. It's completely againts dependency injection because you not inject dependencies, you just inject a generic factory (you can ask for anything) which is very dangerous and highly increases complexity for nothing.

I highly recommend this book: Dependency Injection in .NET - Mark Seemann

3
votes

What you are doing is abusing the container as a ServiceLocator. This is considered an anti-pattern in modern application architecture.

Use proper Dependency Injection instead. Martin Fowler gives a good introduction on the pattern.

Mark Seemann wrote a very good book on the topic called Dependency Injection in .NET.

And as @PeterPorfy already pointed out the concept of Composition Roots is important. You register all dependencies with your container there and then kickoff by resolving the root object of your application or service there.

You never hand the container to a class outside that composition root!