Problem
My constructors are starting to resemble the following:
public MyClass(Container con, SomeClass1 obj1, SomeClass2, obj2.... )
with a growing list of parameters Why can’t I just do this, as “Container” is my dependency injection container:
public MyClass(Container con)
for each and every class? What are the drawbacks? It feels like I’m using a glorified static if I do this. Please give your thoughts on the craziness of IoC and Dependency Injection.
Asked by JP Richardson
Solution #1
When you utilize the container as a Service Locator, you’re right: it’s really a glorified static factory. This is an anti-pattern for a variety of reasons (also see this excerpt from my book).
One of the great things about Constructor Injection is that it highlights violations of the Single Responsibility Principle.
It’s time to refactor to Facade Services when this happens. In other words, make a new, coarser-grained interface that hides the interaction between some or all of the fine-grained dependencies you presently need.
Answered by Mark Seemann
Solution #2
Your class constructors should not contain a reference to your IOC container, in my opinion. This is the type of dependency IOC is attempting to avoid: an unwanted dependency between your class and the container.
Answered by derivation
Solution #3
It is not the difficulty of entering the parameters that is the issue. The issue is that your class is overworked and needs to be split up more.
Dependency Injection can serve as a warning sign that a class is becoming too large, due to the increasing discomfort of passing in all of the dependents.
Answered by kyoryu
Solution #4
I just came across a query concerning constructor-based dependency injection and how difficult it was to pass in all the dependencies.
Using the application facade pattern with a service layer is one way I’ve done in the past. There would be a rough API for this. If this service relies on repositories, the private properties would be injected via a setter. This necessitates the creation of an abstract factory and the transfer of the logic for building repositories to it.
Here is a link to a detailed code with an explanation.
In the complicated service layer, best practices for IoC
Answered by samsur
Solution #5
Problem :
1) A constructor with a growing number of parameters.
2) If a class is inherited (for example, RepositoryBase), modifying the constructor signature affects all derived classes.
Solution 1
IoC Container should be passed to the constructor.
Why
Why not
Solution 2
Make a class that contains all of the services and send it to the constructor.
public abstract class EFRepositoryBase
{
public class Dependency
{
public DbContext DbContext { get; }
public IAuditFactory AuditFactory { get; }
public Dependency(
DbContext dbContext,
IAuditFactory auditFactory)
{
DbContext = dbContext;
AuditFactory = auditFactory;
}
}
protected readonly DbContext DbContext;
protected readonly IJobariaAuditFactory auditFactory;
protected EFRepositoryBase(Dependency dependency)
{
DbContext = dependency.DbContext;
auditFactory= dependency.JobariaAuditFactory;
}
}
Derived class
public class ApplicationEfRepository : EFRepositoryBase
{
public new class Dependency : EFRepositoryBase.Dependency
{
public IConcreteDependency ConcreteDependency { get; }
public Dependency(
DbContext dbContext,
IAuditFactory auditFactory,
IConcreteDependency concreteDependency)
{
DbContext = dbContext;
AuditFactory = auditFactory;
ConcreteDependency = concreteDependency;
}
}
IConcreteDependency _concreteDependency;
public ApplicationEfRepository(
Dependency dependency)
: base(dependency)
{
_concreteDependency = dependency.ConcreteDependency;
}
}
Why
Why not
Solution 2 is simply a rough draft; if there is a compelling reason against it, a detailed response would be greatly welcomed.
Answered by tchelidze
Post is based on https://stackoverflow.com/questions/2420193/how-to-avoid-dependency-injection-constructor-madness