使用 IHttpClientFactory 的问题依赖注入 net core 8

问题描述 投票:0回答:1

我目前正在将项目从 Net Core 7 和 Azure Function Runtime 3 迁移到 Net Core 8 和 Azure Function Runtime 4。

在此迁移中,我在使用 IHttpClientFactory 实现服务时遇到了麻烦。

我有这个界面:

    public interface IGenericSender<in TData>
    {
        Task SendAsync(TData data, string resource = null, IDictionary<string, string> parameters = null, string model = "Data", ILogger logger = null);
    }

我在此界面中使用的:

   public interface IGenericCollectionSender<in TData> : IGenericSender<IEnumerable<TData>>
   {
   }

通过此实施:

    public class GenericCollectionSender<TData> : GenericSender<IEnumerable<TData>>, IGenericCollectionSender<TData>
    {
        public GenericCollectionSender(IHttpClientFactory httpClientFactory, HttpMethod method = null,
            AuthorizationServices authorizationServices = null, string resource = null,
            IDictionary<string, string> parameters = null) :
            base(httpClientFactory, method, authorizationServices, resource, parameters)
        {
        }
    }

这是 GenericSender 类:

    public class GenericSender<TData> : IGenericSender<TData>
    {
        private readonly HttpClient _httpClient;
        private readonly AuthorizationServices _authorizationServices;
        private readonly HttpMethod _httpMethod;
        private readonly IDictionary<string, string> _parameters;
        private readonly string _resource;

        public GenericSender(IHttpClientFactory httpClientFactory, HttpMethod method = null,
            AuthorizationServices authorizationServices = null, string resource = null,
            IDictionary<string, string> parameters = null)
        {
            if (method == null)
            {
                _httpMethod = HttpMethod.Post;
            }

            _httpClient = httpClientFactory.CreateClient();
            _authorizationServices = authorizationServices;
            _resource = resource;
            _parameters = parameters;

            if (parameters != null && parameters.Any())
            {
                _resource = ReplaceWithParameters(_resource, parameters);
            }
        }

        public virtual async Task SendAsync(TData data, string resource = null, IDictionary<string, string> parameters = null, string model = "Data", ILogger logger = null)
        {
            //Some code
        }

        public static string ReplaceWithParameters(string resource, IDictionary<string, string> parameters)
        {
            //Some code
        }
    }

这是我的职能工作者:


    public class OrderReaderWorker
    {

        //some other variables
        private readonly IGenericCollectionSender<int> _errorSender;

        public OrderReaderWorker(IOrderFileCreator orderFileCreator,
            OrderFileSender orderFileSender, OrderFileJsonSender orderFileJsonSender, IEmailSender emailSender, IGenericCollectionSender<int> errorSender)
        {
            _orderFileCreator = orderFileCreator;
            _orderFileSender = orderFileSender;
            _orderJsonFileSender = orderFileJsonSender;
            _emailSender = emailSender;
            _errorSender = errorSender;
        }

        [Function("OrdersSenderWorker")]
        public async Task RunAsync([QueueTrigger("orders", Connection = "AzureWebJobsStorage")]
            string data,  ILogger log, int dequeueCount)
        {
            //some code
        }

        private async Task ManageErrors(Guid identifier, string data, DateTimeOffset currentDate, Exception ex, ILogger log, string fileTxt, int dequeueCount)
        {
            //some code where I use the _errorSender

        }

    }

最后,我在 Program.cs 中注册该服务,如下所示:


var host = new HostBuilder()
    .ConfigureFunctionsWebApplication()
    .ConfigureServices((context, services) =>
    {
        var configuration = context.Configuration;

        // Some code and other services

        services.AddOptions<SacApiSettings>().Configure<IConfiguration>((settings, configuration) => configuration.GetSection("SacApiSettings").Bind(settings));

        services.AddOptions<AuthConfig>().Configure<IConfiguration>((settings, configuration) => configuration.GetSection("IdentityServer").Bind(settings));

        services.AddHttpClient<IGenericCollectionSender<int>, GenericCollectionSender<int>>((provider, client) =>
        {
            client.BaseAddress = new Uri(provider.GetRequiredService<SacApiSettings>().BaseUrl);
        }).AddPolicyHandler(GetRetryPolicy());

        services.AddHttpClient<AuthorizationServices>().AddPolicyHandler(GetRetryPolicy());
    })
    .Build();

host.Run();

问题是,当我触发函数时,出现以下异常:

[2024-05-06T20:31:36.469Z] Trigger Details: MessageId: blablablabla, DequeueCount: 1, InsertedOn: 2024-05-06T20:31:34.000+00:00
[2024-05-06T20:31:36.691Z] Function 'OrdersSenderWorker', Invocation id '0d3e79b9-44fd-4bfa-a386-089a01d7e7f8': An exception was thrown by the invocation.
[2024-05-06T20:31:36.692Z] Result: Function 'OrdersSenderWorker', Invocation id '0d3e79b9-44fd-4bfa-a386-089a01d7e7f8': An exception was thrown by the invocation.
Exception: System.InvalidOperationException: A suitable constructor for type 'Terumo.SAC.Master.Proxy.Services.GenericCollectionSender`1[System.Int32]' could not be located. Ensure the type is concrete and all parameters of a public constructor are either registered as services or passed as arguments. Also ensure no extraneous arguments are provided.
[2024-05-06T20:31:36.692Z]    at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.FindApplicableConstructor(Type instanceType, Type[] argumentTypes, ConstructorInfo& matchingConstructor, Nullable`1[]& matchingParameterMap)
[2024-05-06T20:31:36.693Z]    at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.CreateFactoryInternal(Type instanceType, Type[] argumentTypes, ParameterExpression& provider, ParameterExpression& argumentArray, Expression& factoryExpressionBody)
[2024-05-06T20:31:36.693Z]    at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.CreateFactory(Type instanceType, Type[] argumentTypes)
[2024-05-06T20:31:36.694Z]    at System.Threading.LazyInitializer.EnsureInitializedCore[T](T& target, Boolean& initialized, Object& syncLock, Func`1 valueFactory)
[2024-05-06T20:31:36.694Z]    at Microsoft.Extensions.Http.DefaultTypedHttpClientFactory`1.Cache.get_Activator()
[2024-05-06T20:31:36.695Z]    at Microsoft.Extensions.Http.DefaultTypedHttpClientFactory`1.CreateClient(HttpClient httpClient)
[2024-05-06T20:31:36.695Z]    at Microsoft.Extensions.DependencyInjection.HttpClientBuilderExtensions.AddTransientHelper[TClient,TImplementation](IServiceProvider s, IHttpClientBuilder builder)
[2024-05-06T20:31:36.696Z]    at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
[2024-05-06T20:31:36.696Z]    at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitDisposeCache(ServiceCallSite transientCallSite, RuntimeResolverContext context)
[2024-05-06T20:31:36.697Z]    at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
[2024-05-06T20:31:36.697Z]    at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(ServiceCallSite callSite, ServiceProviderEngineScope scope)
[2024-05-06T20:31:36.698Z]    at Microsoft.Extensions.DependencyInjection.ServiceLookup.DynamicServiceProviderEngine.<>c__DisplayClass2_0.<RealizeService>b__0(ServiceProviderEngineScope scope)
[2024-05-06T20:31:36.698Z]    at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(ServiceIdentifier serviceIdentifier, ServiceProviderEngineScope serviceProviderEngineScope)
[2024-05-06T20:31:36.698Z]    at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(Type serviceType)
[2024-05-06T20:31:36.699Z]    at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.ConstructorMatcher.CreateInstance(IServiceProvider provider)
[2024-05-06T20:31:36.699Z]    at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.CreateInstance(IServiceProvider provider, Type instanceType, Object[] parameters)
[2024-05-06T20:31:36.700Z]    at Microsoft.Azure.Functions.Worker.DefaultFunctionActivator.CreateInstance(Type instanceType, FunctionContext context) in D:\a\_work\1\s\src\DotNetWorker.Core\Invocation\DefaultFunctionActivator.cs:line 23
[2024-05-06T20:31:36.700Z]    at Terumo.SAC.Master.Worker.DirectFunctionExecutor.ExecuteAsync(FunctionContext context) in E:\Downloads\Trabajos\Dynamic\Clientes\terumo\dev\terumo-sac-master-worker\src\Terumo.SAC.Master.Worker\Microsoft.Azure.Functions.Worker.Sdk.Generators\Microsoft.Azure.Functions.Worker.Sdk.Generators.FunctionExecutorGenerator\GeneratedFunctionExecutor.g.cs:line 37
[2024-05-06T20:31:36.701Z]    at Microsoft.Azure.Functions.Worker.OutputBindings.OutputBindingsMiddleware.Invoke(FunctionContext context, FunctionExecutionDelegate next) in D:\a\_work\1\s\src\DotNetWorker.Core\OutputBindings\OutputBindingsMiddleware.cs:line 13
[2024-05-06T20:31:36.701Z]    at Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore.FunctionsHttpProxyingMiddleware.Invoke(FunctionContext context, FunctionExecutionDelegate next) in D:\a\_work\1\s\extensions\Worker.Extensions.Http.AspNetCore\src\FunctionsMiddleware\FunctionsHttpProxyingMiddleware.cs:line 34
[2024-05-06T20:31:36.702Z]    at Microsoft.Azure.Functions.Worker.FunctionsApplication.InvokeFunctionAsync(FunctionContext context) in D:\a\_work\1\s\src\DotNetWorker.Core\FunctionsApplication.cs:line 89

简历:

Exception: System.InvalidOperationException: A suitable constructor for type 'Terumo.SAC.Master.Proxy.Services.GenericCollectionSender`1[System.Int32]' could not be located

我不确定我错过了什么,我问了 gpt 但什么也没有。需要一些认真的帮助。

我尝试创建一个构造函数来接收 int,但异常仍然存在。

我期待服务能够顺利注入。

azure-functions asp.net-core-8 ihttpclientfactory
1个回答
0
投票

我解决了这个问题。我只需要在我的实现中使用 HttpClient 而不是 IHttpClientFactory,就解决了问题。

© www.soinside.com 2019 - 2024. All rights reserved.