aspnetcore icon indicating copy to clipboard operation
aspnetcore copied to clipboard

[9.0.100-rc.1.24406.1] EasyCMS app launch failed with 'Multiple constructors accepting all given argument types have been found in type 'Microsoft.AspNetCore.CookiePolicy.CookiePolicyMiddleware' exception

Open Junjun-zhao opened this issue 1 year ago • 13 comments

Is there an existing issue for this?

  • [X] I have searched the existing issues

Describe the bug

When running the 3rd party application with the latest .NET 9.0 build (9.0.100-rc.1.24406.1), it failed launch with below exception message: System.InvalidOperationException: 'Multiple constructors accepting all given argument types have been found in type 'Microsoft.AspNetCore.CookiePolicy.CookiePolicyMiddleware'. There should only be one applicable constructor.'

Findings: We found this issue is caused by Autofac.Extensions.DependencyInjection version 7.1.0 nuget package. If we upgrade the package to latest version 9.0.0, the issue will gone. But the Autofac.Extensions.DependencyInjection version 7.1.0 package works when running against with build dotnet-sdk-9.0.100-preview.7.24402.8, it starts failing on build dotnet-sdk-9.0.100-rc.1.24406.1.

Application Name: EasyCMS OS: Windows 10 21H2 CPU: X64 .NET Build Number: dotnet-sdk-9.0.100-rc.1.24406.1 App Source or App Location checking at: https://devdiv.visualstudio.com/DevDiv/_workitems/edit/2198684 Github Link: https://github.com/yushuo1990/EasyCMS

Verify Scenarios: 1). Windows 10 21H2 AMD64 + dotnet-sdk-8.0.303: Pass 2). Windows 10 21H2 AMD64 + dotnet-sdk-9.0.100-preview.7.24402.8: Pass 3). Windows 10 21H2 AMD64 + dotnet-sdk-9.0.100-rc.1.24406.1: Fail

Expected Behavior

App launch successfully.

Steps To Reproduce

App Repro steps on repro machine:(Please refer to the Repro Machine information from** Internal bug) 1.Open "C:\EasyCMS\App\EasyCMS\App\Atlass.Framework.Web.runtimeconfig.json" file . 2. Change the "Atlass.Framework.Web.runtimeconfig.json" file to let the app run against with dotnet-sdk-9.0.100-rc.1.24406.1

"framework": {
      "name": "Microsoft.AspNetCore.App",
      "version": "9.0.0-rc.1.24405.8"
    },
  1. Launch C:\EasyCMS\App\EasyCMS\App\Atlass.Framework.Web.exe.

Expected Result: Launch successfully.

Actual Result: Launch failed with below error in Command prompt window:

Unhandled exception. System.InvalidOperationException: Multiple constructors accepting all given argument types have been found in type 'Microsoft.AspNetCore.CookiePolicy.CookiePolicyMiddleware'. There should only be one applicable constructor.
   at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.TryFindMatchingConstructor(Type instanceType, Type[] argumentTypes, ConstructorInfo& matchingConstructor, Nullable`1[]& parameterMap)
   at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.FindApplicableConstructor(Type instanceType, Type[] argumentTypes, ConstructorInfoEx[] constructors, ConstructorInfo& matchingConstructor, Nullable`1[]& matchingParameterMap)
   at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.CreateInstance(IServiceProvider provider, Type instanceType, Object[] parameters)
   at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.ReflectionMiddlewareBinder.CreateMiddleware(RequestDelegate next)
   at Microsoft.AspNetCore.Builder.ApplicationBuilder.Build()
   at Microsoft.AspNetCore.Hosting.GenericWebHostService.StartAsync(CancellationToken cancellationToken)
   at Microsoft.Extensions.Hosting.Internal.Host.<StartAsync>b__14_1(IHostedService service, CancellationToken token)
   at Microsoft.Extensions.Hosting.Internal.Host.ForeachService[T](IEnumerable`1 services, CancellationToken token, Boolean concurrent, Boolean abortOnFirstException, List`1 exceptions, Func`3 operation)
   at Microsoft.Extensions.Hosting.Internal.Host.StartAsync(CancellationToken cancellationToken)
   at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.RunAsync(IHost host, CancellationToken token)
   at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.RunAsync(IHost host, CancellationToken token)
   at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.Run(IHost host)
   at Atlass.Framework.Web.Program.Main(String[] args) in C:\Users\Appcompat\Desktop\EasyCms\Atlass.Framework.Web\Program.cs:line 31

Minimal Repro steps (attached WebApplication1.zip): The minimal repro project under C:\WebApplication1 on repro machine (Please refer to the Repro Machine information from Internal bug) 1.Create a .NET 5.0 ASP.NET Core MVC project. (We select .NET 5 because it has the same target framework and same project structure with testing app) 2. Install Autofac.Extensions.DependencyInjection version 7.1.0 nuget package. 3. Add following code in Program.cs file:

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
    .UseServiceProviderFactory(new AutofacServiceProviderFactory())
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup<Startup>();
        });
  1. Add following code in Startup.cs file:
app.UseCookiePolicy();
app.UseHttpsRedirection();
  1. Build the project.
  2. Update "bin\Debug\net5.0\WebApplication1.runtimeconfig.json" to run against with dotnet-sdk-9.0.100-rc.1.24406.1:
"framework": {
      "name": "Microsoft.AspNetCore.App",
      "version": "9.0.0-rc.1.24405.8"
    },
  1. Press F5 to start the app.

Exceptions (if any)

App launch failed with below exception:

System.InvalidOperationException: 'Multiple constructors accepting all given argument types have been found in type 'Microsoft.AspNetCore.CookiePolicy.CookiePolicyMiddleware'. There should only be one applicable constructor.'

Stack Trace:
   at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.TryFindMatchingConstructor(Type instanceType, Type[] argumentTypes, ConstructorInfo& matchingConstructor, Nullable`1[]& parameterMap)
   at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.FindApplicableConstructor(Type instanceType, Type[] argumentTypes, ConstructorInfoEx[] constructors, ConstructorInfo& matchingConstructor, Nullable`1[]& matchingParameterMap)
   at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.CreateInstance(IServiceProvider provider, Type instanceType, Object[] parameters)
   at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.ReflectionMiddlewareBinder.CreateMiddleware(RequestDelegate next)
   at Microsoft.AspNetCore.Builder.ApplicationBuilder.Build()
   at Microsoft.AspNetCore.Hosting.GenericWebHostService.<StartAsync>d__40.MoveNext()
   at Microsoft.Extensions.Hosting.Internal.Host.<<StartAsync>b__14_1>d.MoveNext()
   at Microsoft.Extensions.Hosting.Internal.Host.<ForeachService>d__17`1.MoveNext()
   at Microsoft.Extensions.Hosting.Internal.Host.<StartAsync>d__14.MoveNext()
   at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.<RunAsync>d__4.MoveNext()
   at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.<RunAsync>d__4.MoveNext()
   at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.Run(IHost host)
   at WebApplication1.Program.Main(String[] args) in E:\Demos\WebApplication1\WebApplication1\Program.cs:line 17

.NET Version

9.0.100-rc.1.24406.1

Anything else?

Dotnet Info:

.NET SDK:
 Version:           9.0.100-rc.1.24406.1
 Commit:            b149a156f2
 Workload version:  9.0.100-manifests.c127569d
 MSBuild version:   17.12.0-preview-24405-01+85d805a5a

Runtime Environment:
 OS Name:     Windows
 OS Version:  10.0.19045
 OS Platform: Windows
 RID:         win-x64
 Base Path:   C:\Program Files\dotnet\sdk\9.0.100-rc.1.24406.1\

.NET workloads installed:
Configured to use loose manifests when installing new manifests.
There are no installed workloads to display.

Host:
  Version:      9.0.0-rc.1.24403.1
  Architecture: x64
  Commit:       static

.NET SDKs installed:
  9.0.100-rc.1.24406.1 [C:\Program Files\dotnet\sdk]

.NET runtimes installed:
  Microsoft.AspNetCore.App 9.0.0-rc.1.24405.8 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 9.0.0-rc.1.24403.1 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.WindowsDesktop.App 9.0.0-rc.1.24404.1 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]

@dotnet-actwx-bot @dotnet/compat

Junjun-zhao avatar Aug 08 '24 08:08 Junjun-zhao

Hi @javiercn Could you please help look at this issue which was found during our runtime compat testing? Thanks.

Junjun-zhao avatar Aug 13 '24 08:08 Junjun-zhao

Both ctors of CookiePolicyMiddleware are really old, but @halter73 might have some idea how this could break a DI consumer.

amcasey avatar Aug 20 '24 23:08 amcasey

Thanks @amcasey @halter73 for looking this issue. Any new update about it? We are in RC1 validation window, could you also please confirm if this is a blocker for RC1?

Junjun-zhao avatar Aug 23 '24 02:08 Junjun-zhao

This isn't my area, but my immediate reaction is that a 5.0 project (out-of-support) using Autofac 7.1 (from 2020, but not officially deprecated) is probably not a top priority. If a 6.0 project using a more recent version of Autofac doesn't work, that would be more interesting, though 6.0 is also going out of support shortly.

amcasey avatar Aug 23 '24 18:08 amcasey

I did my best to follow the minimal repro steps (except that I'm on win11 and 9.0.0-preview.7.24406.2) and I didn't see the exception.

amcasey avatar Aug 23 '24 18:08 amcasey

I made a devbox to play around. The exception appears to be new between 9.0.0-preview.7.24406.2 and 9.0.0-rc.1.24416.6.

amcasey avatar Aug 23 '24 19:08 amcasey

From the stack, it appears that TryFindPreferredConstructor failed so it's using TryFindMatchingConstructor. There are two constructors and the single argument type is Microsoft.AspNetCore.Http.RequestDelegate.

amcasey avatar Aug 23 '24 20:08 amcasey

Inspecting the signatures, it looks like there should also be an IOptions<CookiePolicyOptions>.

Edit: this appears to be the same in P7, so it's probably a red herring.

amcasey avatar Aug 23 '24 20:08 amcasey

@steveharter Could this be related to recent DI changes in RC1?

adityamandaleeka avatar Aug 23 '24 21:08 adityamandaleeka

This difference seems interesting to me (I picked a different middleware type that isn't broken):

RC1
>	Microsoft.AspNetCore.HttpsPolicy.dll!Microsoft.AspNetCore.HttpsPolicy.HttpsRedirectionMiddleware.HttpsRedirectionMiddleware(Microsoft.AspNetCore.Http.RequestDelegate next, Microsoft.Extensions.Options.IOptions<Microsoft.AspNetCore.HttpsPolicy.HttpsRedirectionOptions> options, Microsoft.Extensions.Configuration.IConfiguration config, Microsoft.Extensions.Logging.ILoggerFactory loggerFactory) Line 36	C#
 	[Lightweight Function]	
 	System.Private.CoreLib.dll!System.Reflection.ConstructorInvoker.InvokeWithManyArgs(System.Span<object> arguments) Line 334	C#
 	System.Private.CoreLib.dll!System.Reflection.ConstructorInvoker.Invoke(System.Span<object> arguments) Line 237	C#
 	Microsoft.Extensions.DependencyInjection.Abstractions.dll!Microsoft.Extensions.DependencyInjection.ActivatorUtilities.ConstructorMatcher.CreateInstance(System.IServiceProvider provider) Line 888	C#
 	Microsoft.Extensions.DependencyInjection.Abstractions.dll!Microsoft.Extensions.DependencyInjection.ActivatorUtilities.CreateInstance(System.IServiceProvider provider, System.Type instanceType, object[] parameters) Line 192	C#
 	Microsoft.AspNetCore.Http.Abstractions.dll!Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.ReflectionMiddlewareBinder.CreateMiddleware(Microsoft.AspNetCore.Http.RequestDelegate next) Line 131	C#
 	Microsoft.AspNetCore.Http.dll!Microsoft.AspNetCore.Builder.ApplicationBuilder.Build() Line 197	C#
Preview 7
>	Microsoft.AspNetCore.HttpsPolicy.dll!Microsoft.AspNetCore.HttpsPolicy.HttpsRedirectionMiddleware.HttpsRedirectionMiddleware(Microsoft.AspNetCore.Http.RequestDelegate next, Microsoft.Extensions.Options.IOptions<Microsoft.AspNetCore.HttpsPolicy.HttpsRedirectionOptions> options, Microsoft.Extensions.Configuration.IConfiguration config, Microsoft.Extensions.Logging.ILoggerFactory loggerFactory, Microsoft.AspNetCore.Hosting.Server.Features.IServerAddressesFeature serverAddressesFeature) Line 68	C#
 	[Lightweight Function]	
 	System.Private.CoreLib.dll!System.Reflection.MethodBaseInvoker.InvokeWithManyArgs(object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, object[] parameters, System.Globalization.CultureInfo culture) Line 217	C#
 	Microsoft.AspNetCore.Http.Abstractions.dll!Microsoft.Extensions.Internal.ActivatorUtilities.ConstructorMatcher.CreateInstance(System.IServiceProvider provider) Line 169	C#
 	Microsoft.AspNetCore.Http.Abstractions.dll!Microsoft.Extensions.Internal.ActivatorUtilities.CreateInstance(System.IServiceProvider provider, System.Type instanceType, object[] parameters) Line 54	C#
 	Microsoft.AspNetCore.Http.Abstractions.dll!Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.ReflectionMiddlewareBinder.CreateMiddleware(Microsoft.AspNetCore.Http.RequestDelegate next) Line 130	C#
 	Microsoft.AspNetCore.Http.dll!Microsoft.AspNetCore.Builder.ApplicationBuilder.Build() Line 197	C#

amcasey avatar Aug 23 '24 21:08 amcasey

Hmm https://github.com/dotnet/aspnetcore/pull/55722

amcasey avatar Aug 23 '24 21:08 amcasey

I updated to autofac 8 and I no longer see the exception. Can you please confirm, @Junjun-zhao?

Edit: 7.2 seems to work as well. Confirmed that downgrading to 7.1 brings back the exception. Edit 2: It was pointed out to me that the description already mentions the issue is specific to 7.1.

amcasey avatar Aug 23 '24 22:08 amcasey

Hi @amcasey , yes, it does not reproduce this issue with autofac 8.0.0. It reproduces with autofac 7.1.0 and 7.2.0.

There is a repro machine prepared (We set it to autofac 7.2.0 currently, you can change it to other version freely), please get the information from devdiv bug if needed. And please note that after the project is built, please follow the reproduce steps to update Atlass.Framework.Web.runtimeconfig.json file to run the project against RC1.

"framework": {
      "name": "Microsoft.AspNetCore.App",
      "version": "9.0.0-rc.1.24405.8"
    },

Junjun-zhao avatar Aug 26 '24 02:08 Junjun-zhao

The internal ActivatorUtilities used match length as a tie-breaker, whereas the "official" one does not.

amcasey avatar Sep 06 '24 22:09 amcasey

The "official" ActivatorUtilities does use match length as a tie-breaker if the container supports IServiceProviderIsService, which Autofac.Extensions.DependencyInjection does as of version 7.2.

amcasey avatar Sep 06 '24 22:09 amcasey

Thanks @amcasey for looking into this issue and finding the difference.
Could you please share the plan about it, and will it be fixed in RC2?

Junjun-zhao avatar Sep 09 '24 02:09 Junjun-zhao

No, we're not planning to address it in RC2. We'll revisit in 10.0.

amcasey avatar Sep 09 '24 17:09 amcasey

It appears everything is OK with Autofac-related stuff as long as folks are on fairly recent versions. Tag me or file an issue with Autofac.Extensions.DependencyInjection if that's not the case so we can look into it. ;)

tillig avatar Oct 21 '24 19:10 tillig

That's my understanding as well. Thanks for checking in, @tillig!

amcasey avatar Oct 21 '24 19:10 amcasey

Does this affect nomarl service contructors or it only happend on middleware ? Does the default MS DI container be affected ? this announcement#514 is not very clear to me.

John0King avatar Oct 22 '24 00:10 John0King

@John0King This announcement only covers middleware constructors.

amcasey avatar Oct 22 '24 16:10 amcasey

Closing this issue as the breaking change issue https://github.com/aspnet/Announcements/issues/514 filed. Thanks.

Junjun-zhao avatar Oct 25 '24 05:10 Junjun-zhao