如何使用autofac注册键入的httpClient服务? [英] How to register typed httpClient service with autofac?

查看:618
本文介绍了如何使用autofac注册键入的httpClient服务?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在创建MVC Web应用程序,该应用程序使用.net core 2.2使用单独的 HttpClient s调用api来调用每个控制器(相同的api)。

I'm creating MVC web application which calls an api using .net core 2.2 using separate HttpClients to call each controller (same api).

例如:


  • 对于用户控制器操作:UserService(httpclient)

  • 对于后控制器操作:PostService(httpclient)

startup.cs 我将DI用作:

In startup.cs I use DI as:

services.AddHttpClient<IUserService, UserService>();
services.AddHttpClient<IPostService, PostService>();

在我的处理程序中:

public class CommandHandler : IRequestHandler<Command, BaseResponse>
{
    private readonly IUserService _userService;

    public CommandHandler(IUserService userService)
    {
        _userService = userService;
    }

    public Task<BaseResponse> Handle(Command request, CancellationToken cancellationToken)
    {
        throw new System.NotImplementedException();
    }
}

但是调用命令处理程序时出现此错误:

But when invoking command handler I get this error:


找不到与
'Autofac.Core.Activators.Reflection.DefaultConstructorFinder'相同的构造函数,类型为
'xxx可以使用
调用可用的服务和参数来调用.Application.Services.Users.UserService:无法解析构造函数'Void
.ctor的参数
'System.Net.Http.HttpClient httpClient' (System.Net.Http.HttpClient,
xxx.Application.Configurations.IApplicationConfigurations,
Microsoft.Extensions.Logging.ILogger`1 [xxx.Application.Services.Users.UserService])。

None of the constructors found with 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type 'xxx.Application.Services.Users.UserService' can be invoked with the available services and parameters: Cannot resolve parameter 'System.Net.Http.HttpClient httpClient' of constructor 'Void .ctor(System.Net.Http.HttpClient, xxx.Application.Configurations.IApplicationConfigurations, Microsoft.Extensions.Logging.ILogger`1[xxx.Application.Services.Users.UserService])'.

但是我已经在autofac模块中注册了服务:

But I've registered services in autofac module:

public class ServiceModule : Module
{
    protected override void Load(ContainerBuilder builder)
    {
        builder.RegisterAssemblyTypes(typeof(ServiceModule).Assembly)
                .Where(t => t.Namespace.StartsWith("xxx.Application.Services"))
                .AsImplementedInterfaces().InstancePerLifetimeScope();
    }
}

这是我的 UserService 类构造函数:

public UserService (HttpClient httpClient, IApplicationConfigurations applicationConfig, ILogger<UserService> logger)
{
    _httpClient = httpClient;
    _applicationConfig = applicationConfig;
    _logger = logger;

    _remoteServiceBaseUrl = $"{_applicationConfig.WebApiBaseUrl}";
}

我有两个问题:


  1. 上述错误是什么意思?

  2. 在api中为不同的控制器使用单独的httpclient是好习惯吗?


推荐答案

通过

services.AddHttpClient<IUserService, UserService>();  

您将配置本机.net核心依赖项注入以注入 HttpClient IUserService 时,将code>转换为 UserService

You will configure the native .net core dependency injection to inject HttpClient to UserService when a IUserService is requested.

然后您完成

builder.RegisterAssemblyTypes(typeof(ServiceModule).Assembly)
       .Where(t => t.Namespace.StartsWith("xxx.Application.Services"))
       .AsImplementedInterfaces().InstancePerLifetimeScope();

这将删除 IUserService IUserService 现在已在 UserService 中注册,其中没有任何 HttpClient 心神。

which will erase the native dependency injection configuration for IUserService. The IUserService is now registered with UserService without any HttpClient in mind.

添加 HttpClient 的最简单方法是像这样注册它:

The simplest way to add HttpClient would be to register it like this :

builder.Register(c => new HttpClient())
       .As<HttpClient>();

services.AddHttpClient(); // register the .net core IHttpClientFactory 
builder.Register(c => c.Resolve<IHttpClientFactory>().CreateClient())
       .As<HttpClient>(); 

如果要为特定服务配置httpclient,可以创建一个autofac模块,该模块添加如下参数

If you want to configure your httpclient for a specific service you can create an autofac module which add parameters like this :

public class HttpClientModule<TService> : Module
{
    public HttpClientModule(Action<HttpClient> clientConfigurator)
    {
        this._clientConfigurator = clientConfigurator;
    }

    private readonly Action<HttpClient> _clientConfigurator;

    protected override void AttachToComponentRegistration(IComponentRegistry componentRegistry, IComponentRegistration registration)
    {
        base.AttachToComponentRegistration(componentRegistry, registration);

        if (registration.Activator.LimitType == typeof(TService))
        {
            registration.Preparing += (sender, e) =>
            {
                e.Parameters = e.Parameters.Union(
                  new[]
                  {
                    new ResolvedParameter(
                        (p, i) => p.ParameterType == typeof(HttpClient),
                        (p, i) => {
                            HttpClient client = i.Resolve<IHttpClientFactory>().CreateClient();
                            this._clientConfigurator(client);
                            return client;
                        }
                    )
                  });
            };
        }
    }
}

然后

builder.RegisterModule(new HttpClientModule<UserService>(client =>
{
    client.BaseAddress = new Uri("https://api.XXX.com/");
    client.DefaultRequestHeaders.Add("Accept", "application/vnd.XXX.v3+json");
    client.DefaultRequestHeaders.Add("User-Agent", "HttpClientFactory-XXX");
}));

这篇关于如何使用autofac注册键入的httpClient服务?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆