Finbuckle.MultiTenant
Finbuckle.MultiTenant copied to clipboard
Exception after ASP.NET Core app migration from .net7 -> .net8
Hello all
Trying migrate our app to .net8 cause exception: System.InvalidOperationException: 'Multiple constructors accepting all given argument types have been found in type 'Finbuckle.MultiTenant.AspNetCore.MultiTenantAuthenticationSchemeProvider'. There should only be one applicable constructor.'
MultiTenantAuthenticationSchemeProvider really has 2 similar constructors.
At the same time all works fine on .net7. (only changes in code are target + nuget libs refs and recompile) We are using FB 6.13.1 Strange for me, that nobody yet detected same situation.
FB initialization from our problem solution:
services
.AddMultiTenant<CustomTenantInfo>()
.WithInMemoryStore(options => options.Tenants = GetTenantsList())
.WithStrategy<CustomMultiTenantStrategy>(ServiceLifetime.Singleton, CustomEndpointRoutingUrlHelper.PART_TENANT)
.WithPerTenantAuthentication();
Have tried add [ActivatorUtilitiesConstructor] to 3-parameters constructor of MultiTenantAuthenticationSchemeProvider It stops break with Multiple constructors exception and start breaks with new one in FinbuckleServiceCollectionExtensions.AddMultiTenant when adding IMultiTenantContext<T> Castle.MicroKernel.CircularDependencyException: 'Dependency cycle has been detected when trying to resolve component 'Finbuckle.MultiTenant.Internal.AsyncLocalMultiTenantContextAccessor`1[[NN.Core.Web.Modularity.CustomTenantInfo, Core.Web, Version=8.3.8.1, Culture=neutral, PublicKeyToken=null]]@b9c0ecc3-62a9-4afd-b68d-734195721d7e'. The resolution tree that resulted in the cycle is the following ......
What else can be tried?
hi, I did a quick check of the unit tests and there is one that uses the test host and is able to resolve this via DI with no problem. Do you think you could create a small project that recreates the problem?
Not managed to do this quickly. Next week will ask colleagues in project try to help extracting initialization logic for reproducing. But i succeeded to run app somehow applying [ActivatorUtilitiesConstructor] attribute on 2 params constructor. It srtarts, but again with raising and suppressing somewhere additional exceptions related to FB and DI container.
Hi. I've reproduced it in the attached small project. It appears when using Castle.Windsor as default service provider. WebApplication1.zip
I use Autofac as the default service provider, not Windsor, and I have the same problem (resolving a different type though):
Multiple constructors accepting all given argument types have been found in type 'Finbuckle.MultiTenant.Stores.ConfigurationStore`1[MyTenantInfo]'. There should only be one applicable constructor.
Looks like this is due to a breaking change in .NET 8 that Finbuckle did not account for? See:
https://github.com/dotnet/runtime/issues/94736 https://learn.microsoft.com/en-us/dotnet/core/compatibility/extensions/8.0/activatorutilities-createinstance-behavior
Yes. Unfortunately I only test with the default DI provider so didn’t catch this. Hard to say what other things might be impacted by this change. I appreciate you all reporting your findings.
Hello, My problem was fixed by simply updating to a more recent version of Autofac (more specifically Autofac.Extensions.DependencyInjection).
Third-party service providers need to implement the new interface IServiceProviderIsService, otherwise having multiple constructors will break starting in .NET 8. So this might not be a problem with Finbuckle, but I think having multiple constructors on injectables should still be avoided as it is an anti-pattern.
See https://learn.microsoft.com/en-us/dotnet/core/compatibility/extensions/8.0/activatorutilities-createinstance-behavior
Thanks :)
Good to know, thanks @mlessard-appcom
Unfortunately for us problem is not solved :( It must be noted somewhere that it is not possible to use Finbackle with .net8 + Castle.Windsor as DI for current version of both.
@AlexanderKot I don't use Windsor and I'm just guessing here, but you should be able to make this work like before by simply creating your own implementation of IServiceProviderIsService and registering it in the container.
I get your situation but I believe the best path forward is for Castle Windsor to update to conform to .NET expectations. I explicitly try to stay clear of DI in this library as much as possible and only rely on the basic behavior as described by MS.
I’m happy to keep this open but I don’t plan to take any action at this time. I do appreciate your taking the time to investigate and report your findings.