Finbuckle / Finbuckle.MultiTenant

Finbuckle.MultiTenant is an open-source multitenancy middleware library for .NET. It enables tenant resolution, per-tenant app behavior, and per-tenant data isolation.
https://www.finbuckle.com/multitenant
Apache License 2.0
1.26k stars 261 forks source link

using TrySetTenantInfo : exception : No service for type IMultiTenantContextAccessor #607

Open pyramidsbuilder opened 1 year ago

pyramidsbuilder commented 1 year ago

I am trying to set the tenant for the request manually, I tried to use the function in documentation to set

if(HttpContext.TrySetTenantInfo(newTenantInfo, resetServiceProvider: true)) { var tenant = HttpContext.GetMultiTenantContext().TenantInfo; var optionsProvider = HttpContext.RequestServices.GetService<IOptions<MyScopedOptions>>(); }

I get the following error: : No service for type 'Finbuckle.MultiTenant.IMultiTenantContextAccessor`1[Finbuckle.MultiTenant.TenantInfo]' has been registered.'

How do I set the current tenant manually? I want to do this for a test project.

AndrewTriesToCode commented 1 year ago

Hi, I don't see anything right off the bat that indicates why that is happening. Can you post a link to a repo that shows the problem in action?

pyramidsbuilder commented 1 year ago

Yes this exception was because of my code (The MultiTenantContext was initialized using derived class from TenantInfo, once used this derived class in setting httpcontext the error has gone)

But .. I still cannot figure out how to use Finbuckle in integration tests, I tried to create httpcontext and then set the TenantInfo using this method, but I get error Value cannot be null. (Parameter 'provider')

` _httpContextAccessor =_servicesProvider.GetRequiredService();

_httpContextAccessor.HttpContext = new DefaultHttpContext();

if (_httpContextAccessor.HttpContext.TrySetTenantInfo(tenantInfo, true)); ` Anybody has idea on how to use it in integration test project, or in other words how do I set the current tenant info manually not through mediator, http header .. etc?

AndrewTriesToCode commented 1 year ago

@leaditnet I'm not sure if this helps but this is how I mock HttpContext in many of my unit tests.

var mock = new Mock<HttpContext>();
mock.SetupProperty(c => c.RequestServices);
var testHttpContext = mock.Object;

var services = new ServiceCollection();
services.AddOptions().AddMultiTenant<TenantInfo>().WithBasePathStrategy().WithInMemoryStore(options =>
            {
                options.Tenants.Add(new TenantInfo
                {
                    Id = "base123",
                    Identifier = "base",
                    Name = "base tenant"
                });
            });

testHttpContext.RequestServices = services;

...

For integration testing I've had success using the TestServer.

lorenzogiudici5 commented 1 year ago

For integration testing I've had success using the TestServer.

@AndrewTriesToCode could you please provide us a configuration sample of Multitenant using TestServer.?