I am working on AzureFunction ServiceBus v3 which handle multi-tenant message. In message I will have TenantId and I will need to register DependencyInjection per message base on this TenantId. What I tried so far:
At StartUp, I stored the IServiceCollection as static variable
Retrieve the TenantId from the serialized message in Function'd Run method
Update IServiceCollection based on above TenantId and retrieve the Service
_serviceCollection.AddTransient<ITenantIdResolver>(ctx => { return new CompanyResolver{TenantId=tenantId}; }); var service = _serviceCollection.BuildServiceProvider().GetService<T>();
But it throw exception: Unable to resolve service for type 'Microsoft.Azure.WebJobs.Script.IEnvironment' while attempting to activate 'Microsoft.Azure.WebJobs.Script.Configuration.ScriptHostOptionsSetup'
I do some research and look like it was because I used IHttpClientFactory.
How can I fix this?
Or even better if there is a way to retrieve the message in StartUp, so I can inject the tenantId properly? Like
serviceCollection.AddTransient<ITenantIdResolver>(ctx => { var tenantId = GetServicebusMessage().TenantId; return new CompanyResolver { TenantId=tenantId }; }
I think that would be the wrong order of things. Dependency injection should be setup before the message is being processed.
A resolver could be a solution. Register the resolver with the dependency injection container, and let the function be dependent on the resolver. Based on the message you get the right instance from the resolver. In this article it is explained better under "IoC Container Registration #3 – Resolver + Factory Method Pattern": https://techcommunity.microsoft.com/t5/apps-on-azure/dependency-injection-on-azure-functions-5-ways-selecting/ba-p/1502394