Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exception after ASP.NET Core app migration from .net7 -> .net8 #786

Open
AlexanderKot opened this issue Feb 2, 2024 · 11 comments
Open

Exception after ASP.NET Core app migration from .net7 -> .net8 #786

AlexanderKot opened this issue Feb 2, 2024 · 11 comments

Comments

@AlexanderKot
Copy link

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
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?

@AndrewTriesToCode
Copy link
Sponsor Contributor

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?

@AlexanderKot
Copy link
Author

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.

@asamoylik
Copy link

Hi. I've reproduced it in the attached small project. It appears when using Castle.Windsor as default service provider.
WebApplication1.zip

@mlessard-appcom
Copy link

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.

@mlessard-appcom
Copy link

Looks like this is due to a breaking change in .NET 8 that Finbuckle did not account for?
See:

dotnet/runtime#94736
https://learn.microsoft.com/en-us/dotnet/core/compatibility/extensions/8.0/activatorutilities-createinstance-behavior

@AndrewTriesToCode
Copy link
Sponsor Contributor

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.

@mlessard-appcom
Copy link

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 :)

@AndrewTriesToCode
Copy link
Sponsor Contributor

Good to know, thanks @mlessard-appcom

@AlexanderKot
Copy link
Author

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.

@mlessard-appcom
Copy link

@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.

@AndrewTriesToCode
Copy link
Sponsor Contributor

AndrewTriesToCode commented Feb 28, 2024

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

No branches or pull requests

4 participants