使用Unity替代ASP.Net Core DI IServiceCollection

8
越来越多的.NET Core库绑定到IServiceCollection。例如,我想在我的.NET Framework 4.7.1桌面应用程序中使用这里描述的HttpClientFactory。我的应用程序正在使用Unity IoC。我将Microsoft.Extensions.Http作为NuGet引用。
但是有一个问题:新的ASP.Net Core组件绑定到针对.NetCore的Microsoft DI框架-IServiceCollection。例如,在这里注册HttpClientFactory
public void ConfigureServices(IServiceCollection services)
{
    services.AddHttpClient();
}

我正在深入研究MS代码,想要手动将对应的接口和类注册到Unity。以下是IServiceCollection注册服务的方式:

services.TryAddTransient<HttpMessageHandlerBuilder, DefaultHttpMessageHandlerBuilder>();
services.TryAddSingleton<IHttpClientFactory, DefaultHttpClientFactory>();

将这部分内容移动到Unity IoC应该不是问题,但当我想要注册具有内部可见性的DefaultHttpMessageHandlerBuilderDefaultHttpClientFactory时,我被卡住了。因此,它们在MS代码之外无法进行注册。

我有什么机会解决这个问题吗?


好的,正如你所说,你要使用的这两种具体类型是“internal”,因此你不能直接使用它们。只是想补充一下:你能否设置Unity IOC,以便它通过从ASP.NET的“IServiceCollection”中解析“IHttpClientFactory”来解析“IHttpClientFactory”? - p e p
我通过使用IServiceCollection的Unity适配器解决了这个问题:https://dev59.com/Yavka4cB1Zd3GeqP0_C0#51036884 - Karel Kral
2个回答

15

2022年7月12日更新:Unity已被弃用,因此不要在新项目中使用它。我用Autofac替换了它。

根据@davidfowl的回答,我使用了他的第二个解决方案并完成了代码:

这些包需要从我的项目中引用(来自.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>

这里是测试,验证ServiceCollection中的服务可以从Unity容器中解析:

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());

        }

    }
}

1
请注意:如果.csproj 非常简单,则可能缺少完整的 DependencyInjection 依赖项。我必须通过 <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="2.2.0" /> 来添加它。 - skolima
这对我不起作用。ServiceCollection 似乎来自于 Microsoft.Extensions.DependencyInjection,但是在你的示例中我没有看到 using。它在 Unity 的包中也找不到。此外,也没有 AddHttpClient() 方法,所以我不确定它是从哪里来的。 - void.pointer
@void.pointer 你所缺少的一切都在 using 指令中。请检查是否有适当的 NuGet 包(它们的版本现在应该更高)。 - Karel Kral

7

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接