gpt4 book ai didi

c# - 需要在运行时使用 Azure Function 中的 ServiceProvider 创建服务

转载 作者:行者123 更新时间:2023-12-02 23:35:11 26 4
gpt4 key购买 nike

我有一个棘手的要求,我需要创建通过 Azure 函数中的构造函数 DI 创建的服务的副本

public MyFunction(IMyService myService,
IServiceProvider serviceProvider,
ServiceCollectionContainer serviceCollectionContainer)
{
_myService = tmToolsService;
_serviceProvider = serviceProvider;
_serviceCollectionContainer = serviceCollectionContainer;
}

[FunctionName("diagnostic-orchestration")]
public async Task DiagnosticOrchestrationAsync(
[OrchestrationTrigger] IDurableOrchestrationContext context)
{

}

这个服务有很多依赖项,所以我真的不想走手动 Activator.CreateInstance 路线

我尝试了两种不同的方法

方法 1

我有 ServiceCollectionContainer。这是在启动的配置中填写的,只是保存服务

public override void Configure(IFunctionsHostBuilder builder)
{
base.Configure(builder);

var services = builder.Services;
services.AddSingleton(s => new ServiceCollectionContainer(services));
}

在我的函数中我调用

var provider = _serviceCollectionContainer.ServiceCollection.BuildServiceProvider();
if (provider.GetService<IMyService>() is IMyService myService)
{
await myService.MyMathodAsync();
}

这会引发错误

System.InvalidOperationException: 'Unable to resolve service for type 
'Microsoft.Azure.WebJobs.Script.IEnvironment' while attempting to activate
'Microsoft.Azure.WebJobs.Script.Configuration.ScriptJobHostOptionsSetup'.'

我相信这可能是因为虽然服务集合看起来不错(276 个注册服务),但我在网上看到引用资料说配置可能不可靠

方法 2

第二种方法是更传统的方法,我只是尝试使用注入(inject)的服务提供者而不做任何更改

if (_serviceProvider.GetService<IMyService>() is IMyService myService)
{
await myService.MyMathodAsync();
}

但是如果我使用这种方法,我会收到错误

“范围已处置{no name}已处置,作用域实例已处置且不再可用

我该如何解决这个问题?

我正在处理大日期范围的数据。我需要分割日期范围并使用我的服务来处理每个日期范围。我的服务有存储库。每个存储库都有一个 DbContext。让每个日期段在其自己的服务上下文中运行允许我并行运行处理,而无需并行运行 DbContext 查询,这会导致 Ef Core 出现问题

此处理在持久函数内运行

最佳答案

我不知道这对于 Azure Functions 是否适用,而且我对持久功能没有经验,尽管主要目标似乎是通过 IMyService 通过 ef core 运行并行查询,然后您可以在构造函数中:

public MyFunction(IServiceScopeFactory serviceScopeFactory) 
{
_serviceScopeFactory = serviceScopeFactory;
}

然后在函数调用中,假设您有一个 IEnumerable“yourSegments”,其中包含要并行处理的内容:

var tasks = yourSegments.Select(async segment =>
{
using (var scope = _serviceScopeFactory.CreateScope())
{
var IMyService = scope.ServiceProvider.GetRequiredService<IMyService>();
await IMyService.MyMathodAsync(segment);


}
});

await Task.WhenAll(tasks);

我从一篇很好的博客文章中得到了这个,它解释了“Since we project our parameters to multiple tasks, each will have it's own scope which can resolve it's own DbContext instance.

关于c# - 需要在运行时使用 Azure Function 中的 ServiceProvider 创建服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74509986/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com