HostingService not receiving HttpClient through DI
aeos opened this issue · 4 comments
Hi,
I have a functional IHostedService that relies on an HttpClient, When I have the client defined in the service, everything works. However, if I use dependency injection like the code below, I get the error that follows. I am not quite sure what I am doing wrong. I am running a hosted service beside a webapi.
public void ConfigureServices(IServiceCollection services)
{
services.AddHttpClient<PCSyncService>( c => {
// configuration removed
});
services.AddHostedService<PCSyncService>();
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}
Exception has occurred: CLR/System.InvalidOperationException
An unhandled exception of type 'System.InvalidOperationException' occurred in System.Private.CoreLib.dll: 'Unable to resolve service for type 'System.Net.Http.HttpClient' while attempting to activate 'charismata.io.directory.api.v1.Services.PCSyncService'.'
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateArgumentCallSites(Type serviceType, Type implementationType, CallSiteChain callSiteChain, ParameterInfo[] parameters, Boolean throwIfCallSiteNotFound)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateConstructorCallSite(Type serviceType, Type implementationType, CallSiteChain callSiteChain)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.TryCreateExact(ServiceDescriptor descriptor, Type serviceType, CallSiteChain callSiteChain)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.TryCreateEnumerable(Type serviceType, CallSiteChain callSiteChain)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateCallSite(Type serviceType, CallSiteChain callSiteChain)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateArgumentCallSites(Type serviceType, Type implementationType, CallSiteChain callSiteChain, ParameterInfo[] parameters, Boolean throwIfCallSiteNotFound)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateConstructorCallSite(Type serviceType, Type implementationType, CallSiteChain callSiteChain)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.TryCreateExact(ServiceDescriptor descriptor, Type serviceType, CallSiteChain callSiteChain)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.TryCreateExact(Type serviceType, CallSiteChain callSiteChain)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateCallSite(Type serviceType, CallSiteChain callSiteChain)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.CreateServiceAccessor(Type serviceType)
at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.GetService(Type serviceType)
at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(Type serviceType)
at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider)
at Microsoft.AspNetCore.Hosting.Internal.WebHost.<StartAsync>d__26.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Hosting.WebHostExtensions.<RunAsync>d__5.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Hosting.WebHostExtensions.<RunAsync>d__4.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Hosting.WebHostExtensions.Run(IWebHost host)
at charismata.io.directory.api.v1.Program.Main(String[] args) in C:\proj\charismata_directory_api\Program.cs:line 17
services.AddHttpClient( c => { ... })
If you're doing this then you should be resolving PCSyncService
from DI.
I think AddHostedService adds the service as a transient dependency. Without the AddHttpClient extension call my service receives the Ilogger through DI
If anyone has a similar issue in the future, I figured out how to solve the issue, but I do not know why.
I could not find the appropriate pattern for passing the HttpClient directly into an IHostedService. You must create another service interface, and pass that into the IHostedService. You must define this new Interface service first, then the HttpClient definition, then the HostedService binding.
public void ConfigureServices(IServiceCollection services)
{
services.AddTransient<IPeopleService, PeopleService>();
services.AddHttpClient<IPeopleService,PeopleService>( c => {
// configuration removed
});
services.AddHostedService<PCSyncService>();
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}