More and more .NET Core libraries is bound to IServiceCollection
. In example, I want to use HttpClientFactory
described here in my NET Framework 4.7.1. desktop application. My application is using Unity IoC. I referenced Microsoft.Extensions.Http
as NuGet.
But there is a problem: new ASP.Net Core components are bound to Microsoft DI framework for .NetCore - IServiceCollection
. In example, registration of HttpClientFactory
is here:
public void ConfigureServices(IServiceCollection services)
{
services.AddHttpClient();
}
I was going deeper into MS code and wanted to manually register corresponding interfaces and classes to Unity. This is how services are registered by IServiceCollection:
services.TryAddTransient<HttpMessageHandlerBuilder, DefaultHttpMessageHandlerBuilder>();
services.TryAddSingleton<IHttpClientFactory, DefaultHttpClientFactory>();
This would be no problem to move this to Unity IoC, but I am stucked when I want to register DefaultHttpMessageHandlerBuilder
and DefaultHttpClientFactory
which have internal visibility. So they are not available for registration outside of MS code.
Do I have any chance how to resolve this situation?
Based on @davidfowl answer, I have used his second solution and completed code:
These packages need to be referenced from my project (snippet from .csproj):
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Http">
<Version>2.1.1</Version>
</PackageReference>
<PackageReference Include="Unity.Microsoft.DependencyInjection">
<Version>2.0.10</Version>
</PackageReference>
</ItemGroup>
And here is the test that services from ServiceCollection can be resolved from Unity container:
using System;
using System.Linq;
using System.Net.Http;
using Microsoft.Extensions.DependencyInjection;
using Unity;
using Unity.Microsoft.DependencyInjection;
using Xunit;
namespace FunctionalTests
{
public class UnityWithHttpClientFactoryTest
{
/// <summary>
/// Integration of Unity container with MS ServiceCollection test
/// </summary>
[Fact]
public void HttpClientCanBeCreatedByUnity()
{
UnityContainer unityContainer = new UnityContainer();
ServiceCollection serviceCollection = new ServiceCollection();
serviceCollection.AddHttpClient("Google", (c) =>
{
c.BaseAddress = new Uri("https://google.com/");
});
serviceCollection.BuildServiceProvider(unityContainer);
Assert.True(unityContainer.IsRegistered<IHttpClientFactory>());
IHttpClientFactory clientFactory = unityContainer.Resolve<IHttpClientFactory>();
HttpClient httpClient = clientFactory.CreateClient("Google");
Assert.NotNull(httpClient);
Assert.Equal("https://google.com/", httpClient.BaseAddress.ToString());
}
}
}
You have 2 options:
Create a ServiceCollection, add the factory and then call BuildServiceProvider and resolve the IHttpClientFactory. There's an uber sample here https://github.com/aspnet/HttpClientFactory/blob/64ed5889635b07b61923ed5fd9c8b69c997deac0/samples/HttpClientFactorySample/Program.cs#L21.
Use the unity adapter for IServiceCollection
https://www.nuget.org/packages/Unity.Microsoft.DependencyInjection/.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With