【问题标题】:Using Unity instead of ASP.Net Core DI IServiceCollection使用 Unity 而不是 ASP.Net Core DI IServiceCollection
【发布时间】:2018-06-05 17:28:53
【问题描述】:

越来越多的 .NET Core 库绑定到 IServiceCollection。例如,我想在我的 NET Framework 4.7.1 中使用HttpClientFactory 描述的here。桌面应用程序。我的应用程序正在使用 Unity IoC。我将Microsoft.Extensions.Http 引用为 NuGet。

但是有一个问题:新的 ASP.Net Core 组件绑定到 .NetCore 的 Microsoft DI 框架 - IServiceCollection。比如HttpClientFactory的注册地址在这里:

public void ConfigureServices(IServiceCollection services)
{
    services.AddHttpClient();
}

我正在深入研究MS code,并想手动将相应的接口和类注册到 Unity。这就是 IServiceCollection 注册服务的方式:

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

将其移至 Unity IoC 没有问题,但是当我想注册具有 internal 可见性的 DefaultHttpMessageHandlerBuilderDefaultHttpClientFactory 时,我被卡住了。所以它们不能在 MS 代码之外注册。

我有机会如何解决这种情况吗?

【问题讨论】:

  • 好吧,正如您所说,您要使用的两个具体类型是internal,就是这样,您不能直接使用它们。只是想补充一个想法:您能否设置您的 Unity IOC,使其通过从 ASP.NET IServiceCollection 依次解析 IHttpClientFactory 来解析 IHttpClientFactory
  • 我通过为 IServiceCollection 使用统一适配器解决了这个问题:stackoverflow.com/a/51036884/245460

标签: c# asp.net-core dependency-injection unity-container


【解决方案1】:

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

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

这里是来自 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());

        }

    }
}

【讨论】:

  • 注意:如果.csproj 非常小,则可能缺少完整的DependencyInjection 依赖项。我必须用&lt;PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="2.2.0" /&gt; 添加它。
  • 这对我不起作用。 ServiceCollection 似乎来自 Microsoft.Extensions.DependencyInjection,但我在您的示例中没有看到 using。在 Unity 的包中找不到它。也没有AddHttpClient() 方法,所以我不确定它来自哪里。
  • @void.pointer 你所缺少的一切都在 usings 指令中。检查您是否有合适的 NuGet 包(它们的版本现在会更高)。
【解决方案2】:

你有两个选择:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-08-21
    • 2018-08-16
    • 1970-01-01
    • 2020-06-09
    • 2019-04-27
    • 1970-01-01
    • 2018-09-07
    • 2017-12-27
    相关资源
    最近更新 更多