How to Avoid Dependency Injection Constructor Madness

https://medium.com/@callmeyaz/how-to-avoid-dependency-injection-constructor-madness-net-65b48046bfd1

!assets/1yuVzMhCJyDENbyhwAsrkwA.png Private or broken link
The page you're looking for is either not available or private!

How to Avoid Dependency Injection Constructor Madness —ASP.NET Core 8.0

!assets/1pB2EJO-7n8i15lu9zgSKtQ.png Private or broken link
The page you're looking for is either not available or private!

Yaz

·

Follow

3 min read

·

Dec 2, 2023

If you are in the same boat as me, you might have come across a time when the number of injected dependencies grew exponentially, and the constructor parameters looked like a never-ending story.

public MyClass(SomeClass1 obj1, SomeClass2 obj2, SomeClass3 obj3, ....) {
  /* some code here */
}

A good example would be, injecting a large number of Repositories into a UnitOfWork class.

Of course, we could use the Service Locator design pattern but since that is now considered as an anti-pattern it should be avoided. Read more here to see how the implementation below is not a Service Locator design pattern.

So how to deal with this situation?

Well, if we use Factory Method of a Factory Method, and if we have designed the interface inheritance the right way this can be achieved.

Let us assume the above scenario where we need to inject a huge list of repositories into a UnitOfWork constructor. Since all those repositories are, well, repositories, they should follow the inheritance principle as follows:

/* Base interface */
public interface IRepository {}

/* Child 1 */
public interface IUserRepository: IRepository {
  /* Some interface specific declarations here */
}

/* Child 2*/
public interface IAddressRepository: IRepository {
  /* Some interface specific declarations here */
}

/* Child 3*/
public interface IOrderRepository: IRepository {
  /* Some interface specific declarations here */
}

In the above code, we have created a base Interface IRepository which is inherited by other child interfaces with their specific declarations.

We would assume that these child interfaces are implemented by their concrete implementations as follows:

/* Concrete Child 1 */
public class UserRepository: IUserRepository {
  /* Some interface specific implementation here */
}

/* Concrete Child 2*/
public interface AddressRepository: IAddressRepository {
  /* Some interface specific implementation here */
}

/* Concrete Child 3*/
public interface OrderRepository: IOrderRepository{
  /* Some interface specific implementation here */
}

Now the moment of truth; here is how we will inject the above dependencies into the UnitOfWork class:

public class UnitOfWork: IUnitofWork {

  // factory injected to resolve…