我使用的是Azure函数v3和DI。我有一个服务,我在我的StartUp.cs中设置了一个短暂的生命周期(使用:builder.Services.AddTransient<ICoreApiClient>(s => coreApiService);),然后我注入到我的Azure函数类中。Azure函数是一个存储队列触发器函数。
我希望每个队列消息都有一个单独的"coreApiService“实例,但当多个消息同时放入队列时,我似乎是在共享一个实例。
我期望为每个调用获得一个单独的实例,或者“运行”是不正确的吗?我遇到的问题是,"_coreApiClient“似乎在多次调用Run方法之间共享,因此当我在其中设置属性时(如"Customer ID”或"API“等)。当它开始处理下一条消息时,i对一条消息有效并且应该保持对该消息的处理是改变的。
是我做错了,还是我没有正确地理解生命?
下面是我的启动代码:
public class Startup: FunctionsStartup
{
public override void Configure(IFunctionsHostBuilder builder)
{
builder.Services.AddLogging();
var loggingService = new HttpLoggingService(Environment.GetEnvironmentVariable("LoggingURL"), 0, "ABC.Integrations");
builder.Services.AddTransient<ILoggingService>(s => loggingService);
int CoreApiTimeout = 60; //Environment.GetEnvironmentVariable("CoreApiTimeout")
var coreApiService = new CoreApiClient(Environment.GetEnvironmentVariable("CoreApiKey"),string.Empty, CoreApiTimeout,Environment.GetEnvironmentVariable("CoreApiBaseUrl"));
builder.Services.AddTransient<ICoreApiClient>(s => coreApiService);
}
}和我的Azure函数类:
public class TaskRouter
{
private readonly ICoreApiClient _coreApiClient;
private readonly ILoggingService _upgLogger;
private readonly ILogger<TaskRouter> _log;
public TaskRouter(ICoreApiClient coreApiClient, ILoggingService upgLogger, ILogger<TaskRouter> log)
{
_coreApiClient = coreApiClient;
_upgLogger = upgLogger;
_log = log;
}
[FunctionName("RouteTask")]
[ExponentialBackoffRetry(5, "00:00:04", "00:03:00")]
public async Task Run([QueueTrigger("task-scheduler", Connection = "")]
string queueItem)
{
//Call Appropriate Function to start task
var taskMsg = JsonConvert.DeserializeObject<TaskMessage>(queueItem);
_coreApiClient.SetId(taskMsg.TaskNumber);
//DO SOME WORK HERE
Console.Log(_coreApiClient.GetId); //Will be different b/c this was set by the next message
}
}发布于 2021-03-01 04:16:49
尽管客户端在容器中注册为瞬态,但它实际上是一个单例,因为在启动中创建的实例是每次调用注入ICoreApiClient时都会返回的唯一实例。
将实例创建移到工厂委托中,使其成为实际的临时注册,以便每次必须从服务提供者解析ICoreApiClient时都会初始化一个新实例。
//...
builder.Services.AddTransient<ICoreApiClient>(s =>
new CoreApiClient(Environment.GetEnvironmentVariable("CoreApiKey"), string.Empty, CoreApiTimeout, Environment.GetEnvironmentVariable("CoreApiBaseUrl"))
);
//...https://stackoverflow.com/questions/66412416
复制相似问题