I have a class which requires a lot of dependencies - in my terms, lot of dependencies is 8 and more. It looks ugly in IDE, because it breaks line and in one situation I have 3 line constructor signature:
1st step
public class FooClass
{
public FooClass(IDependency1 dependency1, IDependency2 dependency2, ..., IDependency8 dependency8, IDependency9 dependency9)
{
...
}
...
}
I decided to stop using such approach and created dictionary of dependencies. What have I achieved? Beautiful constructor signature, but possibility to get runtime exception easier.
2nd step
public class FooClass2
{
private IDictionary<Type, object> dependencyDictionary;
public FooClass2(IDictionary<Type, object> dependencyDictionary)
{
this.dependencyDictionary = dependencyDictionary;
...
}
...
public T GetObject<T>()
{
return (T)this.dependecyDictionary.FirstOrDefault(t => t.Key == typeof(T));
}
// USAGE
public void FooMethod()
{
IDependency1 = this.GetObject<IDependency1>();
...
}
}
But registration such type is ugly now. As an example, I'm using AutoFac, but any other dependency container has the same behavior.
var builder = new ContainerBuilder();
builder.Register(c => new FooClass2(new Dictionary<Type, object>{
{typeof(IDependency1), c.Resolve<IDependency1>()},
{typeof(IDependency2), c.Resolve<IDependency2>()},
...
{typeof(IDependency8), c.Resolve<IDependency8>()},
{typeof(IDependency9), c.Resolve<IDependency9>()},
})).As<FooClass2>();
Of course, to avoid using second approach, I can create a model, template or call it whatever you want, but it generates many additional classes which are used only for specifying dependencies.
3rd step
public class FooDependencyDefinition
{
public FooDependencyDefinition(IDependency1 dependency1, IDependency2 dependency2, ..., IDependency8 dependency8, IDependency9 dependency9)
{
this.dependency1 = dependency1;
...
}
public IDependency1 dependency1;
public IDependency2 dependency2;
public IDependency1 dependency1;
public IDependency2 dependency2;
...
public IDependency8 dependency8;
public IDependency9 dependency9;
}
public class FooClass
{
public FooClass(FooDependencyDefinition dependencyDefinition)
{
...
}
}
I know there is possibility to inject via properties, but I'd like to avoid it. Which of upper 3 approaches is considered as a good practice? Do you know any other way to pass big numer of dependencies to a class?
Clearly your Step1 is not good as it has too many dependencies. We need some other way.
I strongly discourage your 2nd step. Because the idea of using dependency injection is to make your dependencies obvious for the developer. With your approach, you create a hard to reason about api.
Step 3 is just a hack. It pushes the responsibly to some other class where it takes the ugly constructor. don't recommend it either.
Identify the responsibilities of the classes, refactor them to follow single responsibility principle. Then your class will not need too many dependencies.
Mark Seemann has an excellent article in this subject Refactoring to Aggregate Services.