Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

.NET Core Dependency Injection giving "Ambiguous Constructor" errors after update to version 5.0.0

I have a number of classes that consume API services and whose constructors follow the pattern below:

public class SomeClass
{
    public SomeClass(IHttpClientFactory factory, ILogger<SomeClass> logger = null)
    {
        // ...
    }
        
    public SomeClass(HttpClient client, ILogger<SomeClass> logger = null)
    {
        // ...
    }
}

The first constructor is the one used by .NET Core's built-in dependency injection (by calling IServicesCollection.AddHttpClient() from the Startup.ConfigureServices() method, and then calling IHttpClientFactory.CreateClient() in the constructor); the second constructor is mostly used for unit testing, to allow a HttpClient (or mock) to be passed in. This has worked fine until now, but this morning I started getting errors like the one below:

An unhandled exception has occurred

System.InvalidOperationException: Unable to activate type 'Service'. The following constructors are ambiguous:Void .ctor(System.Net.Http.IHttpClientFactory, Microsoft.Extensions.Logging.ILogger`1[Service])Void .ctor(System.Net.Http.HttpClient, Microsoft.Extensions.Logging.ILogger`1[Service]) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateConstructorCallSite(ResultCache lifetime, Type serviceType, Type implementationType, CallSiteChain callSiteChain)

... long stack trace elided...

This was working up till now. It seems strange that the dependency injection mechanism considers the constructors to be ambiguous when IHttpClientFactory and HttpClient do not share any common interfaces.

I updated both Visual Studio 19 to the latest version (16.8.2) and all NuGet packages in the solution at the weekend. The Microsoft.Extensions.DependencyInjection package is now version 5.0.0; previously it was version 3.1.9. I have worked around the issue for now by removing the constructors that take the HttpClient argument and replaced the code in my tests to use a mock IHttpClientFactory instead, so the actual impact was low. However, it would help my peace of mind, if nothing else, to understand why this broke in the first place. Is there some aspect of configuring .NET Core dependency injection that I have overlooked? Or has the strategy to resolve dependencies changed subtly between versions 3.1.9 and 5.0.0?

like image 405
Ken Keenan Avatar asked Oct 16 '25 12:10

Ken Keenan


1 Answers

I faced this error on .net 7. But after reading Microsoft blog about .Net Dependency Injection, it got me to understand.

For my workground is that I need to instantiate my logic with both Dependency Injection and Dependency Inversion or we could call it hybrid. This way I can use my logic for both long-running task and normal HttpRequest thread rather than duplicate logic separately.

Update

As Ken Karen demonstrated to the right point in the comment is that "The constructor with the most parameters where the types are DI-resolvable is selected".

We have to accept both parameters of constructors to avoid ambiguity.

    public class SomeClass: ISomeClass
    {
       //constructor that we intend to inject using DI
       //The constructor with the most parameters, going to be selected
       public SomeClass(HttpClient client, IHttpClientFactory factory, ILogger<SomeClass> logger = null)
       {
           // ...
       }
       //construtor that we intend to instantiate using DPI
       public SomeClass(HttpClient client, ILogger<SomeClass> logger = null)
       {
           // ...
       }
    }

OtherClass.cs

   public class OtherClass
   {
      private readonly SomeClass someClass;
      private readonly ISomeClass _someClass;

      //using DI to get "SomeClass" instance
      public OtherClass(ISomeClass iSomeClass)
      {
         _someClass = iSomeClass;
         //dependency inversion (DPI)
         someClass = new SomeClass(httpClient, logger);
      }

   }

Maybe your problem has been resolved for long time ago, but I hope it would be helpful for solution finders with similar situation.

like image 62
sambath999 Avatar answered Oct 18 '25 06:10

sambath999



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!