Finbuckle.MultiTenant icon indicating copy to clipboard operation
Finbuckle.MultiTenant copied to clipboard

[Question] MultiTenantContext now readonly

Open malisancube opened this issue 1 year ago • 8 comments

The change in v7.0.0 makes MultiTenantContext to be readonly preventing changing of currect tenant info.

image

More details https://github.com/fullstackhero/dotnet-webapi-starter-kit/issues/925

Is there another way this can be done?

malisancube avatar Apr 26 '24 16:04 malisancube

Hi yes. It’s an implementation detail but you can inject IMultiTenantContextSetter. Look at the source in the middlewarere or TrySetTenantInfo and you’ll see how it can be used. I can’t recall right now but if it is only internal then I will make it public.

AndrewTriesToCode avatar Apr 26 '24 16:04 AndrewTriesToCode

Impressive!

malisancube avatar Apr 26 '24 19:04 malisancube

I just ran into this same issue. I see IMultiTenantContextSetter is documented as an "implementation detail". Is there any plan to expose this functionality for general use? We are using the library in scenarios where the "entry point" is not an HTTP request.

douggish avatar May 02 '24 22:05 douggish

Yes it is available to inject as an interface currently. For your use case it is the right approach (or you could mutate the tenant info on the context but I don’t recommend that).

AndrewTriesToCode avatar May 02 '24 22:05 AndrewTriesToCode

@AndrewTriesToCode Sorta related to this, when having a design time factory, how are we now supposed to inject the IMultiTenantContextAccessor? Earlier it was just a matter of creating a ITenantInfo and injecting, but since IMultiTenantContextAccessor only has internal implementations I can't really wrap my head around a solution - and the docs doesn't seem to have been updated to reflect this change

fbjerggaard avatar May 08 '24 09:05 fbjerggaard

Hi Andrew,

Prior to the upgrade, I handled non http requests with something like this

 using var scope = _serviceProvider.CreateScope();

 var accessor = scope.ServiceProvider.GetRequiredService<IMultiTenantContextAccessor<AppTenantInfo>>();

 var multiTenantContext = new MultiTenantContext<AppTenantInfo>
 {
     TenantInfo = new AppTenantInfo()
     {
         Id = context.Message.TenantId.ToString(),
         Identifier = context.Message.Identifier.ToString(),
     }
 };

 acccessor.MultiTenantContext = multiTenantContext;

using the new interface, I will handle non http request as below?

 using var scope = _serviceProvider.CreateScope();

 var accessor = scope.ServiceProvider.GetRequiredService<IMultiTenantContextAccessor<AppTenantInfo>>();
 var setter = scope.ServiceProvider.GetRequiredService<IMultiTenantContextSetter>();

 var multiTenantContext = new MultiTenantContext<AppTenantInfo>
 {
     TenantInfo = new AppTenantInfo()
     {
         Id = context.Message.TenantId.ToString(),
         Identifier = context.Message.Identifier.ToString(),
     }
 };

 setter.MultiTenantContext = multiTenantContext;

goforebroke avatar May 14 '24 22:05 goforebroke

Hi @fbjerggaard and @goforebroke

Check out the Identity sample where I have the db design time factory in the data folder and and per-tenant scope for migration in program.cs.

I kept the old constructor signature for the mult-tenant db contexts specifically for these use cases despite the change in dependency injection. I should maybe update the docs on this topic.

AndrewTriesToCode avatar May 15 '24 13:05 AndrewTriesToCode