How to register dependency injection for set of interfaces as a group.

Vinod Rajendran 21 Reputation points
2022-03-16T18:38:57.743+00:00

We are following microservice architecture and we use a dotnet core dependency injection, over time the class constructor has more dependency injected even after separating the logics to different classes by considering the single responsibility. Is there any way we can group the injected dependencies in to single interface.

eg:

public class foo
{
   public foo(ISampleA aobj, ISampleB bObj.............up to 20 interfaces)
  {
  }
}

to==>

    public interface ISample
    {
        ISampleA SampleAinterfacea { get;  }
        ISampleB SampleBinterfaceb { get; }
        ISampleC SampleBinterfacec { get; }
    }

public class foo
{
  private readonly ISampleA sampleAobj;
  private readonly ISampleB sampleBobj;
  private readonly ISampleC sampleCobj;

  public foo(ISample groupObj)
  {
    this.sampleAobj = groupObj.SampleAinterface
    this.sampleBobj = groupObj.SampleBnterface
    this.sampleCobj = groupObj.SampleCinterface
  }
}

Is there any way to make the constructor have less dependency supplied? I know there is a way in autofac but I could not get anything from dotnet core documention to do something like this, see the below link.

aggregate-services.html

C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
11,093 questions
0 comments No comments
{count} votes

Accepted answer
  1. Michael Taylor 55,301 Reputation points
    2022-03-16T21:12:44.033+00:00

    The built in DI doesn't support it. You can continue to use Autofac if you want. It integrates with MS DI.

    But ultimately it is sign your design might be incorrect. Aggregation is the general solution to this but aggregating interfaces is an anti-pattern in many cases because you're not actually using the interface as an abstraction but a grouping construct. Autofac has no problem with this, and why it recommends that, because it is going to generate a dynamic proxy anyway. Honestly you might do better to just create a regular old class that accepts the interfaces as parameters (you're really just moving them from one bucket to another though). At least in this case you don't have to create 2 types (the interface and the impl that does nothing but group the interfaces together). You still have the same design issue but you've pushed it down to another type.

    Long term I would group related interfaces together and then accept those as parameters to your code. At that point I'd be using a regular class if it is just a grouping construct as an interface wouldn't make sense.

    0 comments No comments

1 additional answer

Sort by: Most helpful
  1. Bruce (SqlWork.com) 67,921 Reputation points
    2022-03-16T22:49:12.097+00:00

    sure just create a hosting component that is registered along with the other services:

    public class AppHandlers
    {
      private Interface1 if1;
      private Interface1 if2;
    
      public AppHelpers (private Interface1 if1, private Interface1 if2)
      {
         this.if11 = if1
         this.if12 = if2
      }
      public Interface1 Interface1 => if1; 
      public Interface1 Interface2 => if2; 
    }
    ...
    
    builder.Services.AddScoped<AppHandlers, AppHandlers>();
    
    ...
    
    public void Foo(AppHandlers app)
    
    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.