dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
15.47k stars 4.77k forks source link

[dotnet-sdk-9.0.100-preview.7.24366.3] Fail to launch grandnode with error "Some services are not able to be constructed" #105134

Closed Junjun-zhao closed 4 months ago

Junjun-zhao commented 4 months ago

Description

When run the 3rd party application grandnode with the latest .NET 9 build, it failed to launch that browser displays "can't reach this page". During the debugging, we found it failed with message "Some services are not able to be constructed" and stacktrace shows at Microsoft.Extensions.DependencyInjection.ServiceProvider..ctor. Because this app is very complex, and we don't identify a code snippet to reproduce the issue. So, we provided a repro machine for team to investigate. Please refer to the details from "Internal bug"

Reproduction Steps

Repro Steps for Debug Source on repro machine: (Please refer to the repro machine from Internal bug ) The machine has dotnet-sdk-9.0.100-preview.7.24366.3 sdk and mongodb installed.

  1. Set VSDebugger_ValidateDotnetDebugLibSignatures=0 in Environment Variables.
  2. Open C:\Users\test01\Desktop\Source\GrandNode\GrandNode.sln by VS 2022 preview.
  3. Build Grand.Web.
  4. Update Grand.Web.runtimeconfig to run against with dotnet-sdk-9.0.100-preview.7.24366.3:
    "frameworks": [
      {
        "name": "Microsoft.AspNetCore.App",
        "version": "9.0.0-preview.7.24365.9"
      }
    ]
  5. Add breakpoint in Program.cs line 15.
  6. Run Grand.Web in debug mode.
  7. Press F10.

Expected behavior

Loading page successfully. image

Actual behavior

Can't reach this page . image error details:

System.AggregateException
  HResult=0x80131500
  Message=Some services are not able to be constructed (Error while validating the service descriptor 'ServiceType: FluentValidation.IValidator`1[Grand.Web.Models.Install.InstallModel] Lifetime: Transient ImplementationType: Grand.Web.Validators.Install.InstallValidator': Unable to resolve service for type 'Grand.Services.Installation.IInstallationLocalizationService' while attempting to activate 'Grand.Web.Validators.Install.InstallValidator'.) (Error while validating the service descriptor 'ServiceType: Grand.Web.Validators.Install.InstallValidator Lifetime: Transient ImplementationType: Grand.Web.Validators.Install.InstallValidator': Unable to resolve service for type 'Grand.Services.Installation.IInstallationLocalizationService' while attempting to activate 'Grand.Web.Validators.Install.InstallValidator'.) (Error while validating the service descriptor 'ServiceType: WebEssentials.AspNetCore.Pwa.PwaController Lifetime: Transient ImplementationType: WebEssentials.AspNetCore.Pwa.PwaController': Unable to resolve service for type 'WebEssentials.AspNetCore.Pwa.PwaOptions' while attempting to activate 'WebEssentials.AspNetCore.Pwa.PwaController'.) (Error while validating the service descriptor 'ServiceType: Microsoft.AspNetCore.Mvc.Infrastructure.IActionResultExecutor`1[Microsoft.AspNetCore.Mvc.RedirectResult] Lifetime: Singleton ImplementationType: Grand.Framework.Mvc.Routing.GrandRedirectResultExecutor': Cannot consume scoped service 'Grand.Domain.Security.SecuritySettings' from singleton 'Microsoft.AspNetCore.Mvc.Infrastructure.IActionResultExecutor`1[Microsoft.AspNetCore.Mvc.RedirectResult]'.) (Error while validating the service descriptor 'ServiceType: Grand.Web.Validators.Install.InstallValidator Lifetime: Transient ImplementationType: Grand.Web.Validators.Install.InstallValidator': Unable to resolve service for type 'Grand.Services.Installation.IInstallationLocalizationService' while attempting to activate 'Grand.Web.Validators.Install.InstallValidator'.)
  Source=Microsoft.Extensions.DependencyInjection
  StackTrace:
   at Microsoft.Extensions.DependencyInjection.ServiceProvider..ctor(ICollection`1 serviceDescriptors, ServiceProviderOptions options)
   at Microsoft.Extensions.DependencyInjection.ServiceCollectionContainerBuilderExtensions.BuildServiceProvider(IServiceCollection services, ServiceProviderOptions options)
   at Microsoft.Extensions.Hosting.HostBuilder.InitializeServiceProvider()
   at Microsoft.Extensions.Hosting.HostBuilder.Build()
   at Grand.Web.Program.Main(String[] args) in D:\grandnode\Grand.Web\Program.cs:line 15

  This exception was originally thrown at this call stack:
    [External Code]

Inner Exception 1:
InvalidOperationException: Error while validating the service descriptor 'ServiceType: FluentValidation.IValidator`1[Grand.Web.Models.Install.InstallModel] Lifetime: Transient ImplementationType: Grand.Web.Validators.Install.InstallValidator': Unable to resolve service for type 'Grand.Services.Installation.IInstallationLocalizationService' while attempting to activate 'Grand.Web.Validators.Install.InstallValidator'.

Inner Exception 2:
InvalidOperationException: Unable to resolve service for type 'Grand.Services.Installation.IInstallationLocalizationService' while attempting to activate 'Grand.Web.Validators.Install.InstallValidator'.

Regression?

Yes

Verify Scenarios: 1). Windows 10 22H2 AMD64 + dotnet-sdk-3.1.426: Pass 2). Windows 10 22H2 AMD64 + dotnet-sdk-9.0.100-preview.7.24359.5: Pass 3). Windows 10 22H2 AMD64 + dotnet-sdk-9.0.100-preview.7.24366.3: Fail

Known Workarounds

No response

Configuration

Application Name: grandnode OS: Windows 10 22H2 CPU: X64 .NET Build Number: dotnet-sdk-9.0.100-preview.7.24366.3 App & Source , Repro machine checking at https://devdiv.visualstudio.com/DevDiv/_workitems/edit/2166741

Github Link: https://github.com/grandnode/grandnode

Dotnet Info:

.NET SDK:
 Version:           9.0.100-preview.7.24366.3
 Commit:            bcf65856f2
 Workload version:  9.0.100-manifests.c564055a
 MSBuild version:   17.12.0-preview-24365-02+977d5ccf6

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-preview.7.24366.3\

Host:
  Version:      9.0.0-preview.7.24365.1
  Architecture: x64
  Commit:       static

.NET SDKs installed:
  9.0.100-preview.7.24366.3 [C:\Program Files\dotnet\sdk]

.NET runtimes installed:
  Microsoft.AspNetCore.App 9.0.0-preview.7.24365.9 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 9.0.0-preview.7.24365.1 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.WindowsDesktop.App 9.0.0-preview.7.24365.3 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]

Other information

@dotnet-actwx-bot @dotnet/compat

dotnet-policy-service[bot] commented 4 months ago

Tagging subscribers to this area: @dotnet/area-extensions-dependencyinjection See info in area-owners.md if you want to be subscribed.

Junjun-zhao commented 4 months ago

Hi @ericstj, could you please help check and triage this issue? Please kindly help to move to correct team if this is not correct. Thanks very much.

ericstj commented 4 months ago

Having a look at the repro to see if I can help find regressing change. These are the runtime changes that would be in that difference of builds: https://github.com/dotnet/runtime/compare/4e278fe17f69ea31fbdcbab74ac47ec6fa84914b...b885a58062434707e7584d29910af429a1ee0107

dotnet-policy-service[bot] commented 4 months ago

Tagging subscribers to this area: @dotnet/area-extensions-hosting See info in area-owners.md if you want to be subscribed.

ericstj commented 4 months ago

This was regressed with https://github.com/dotnet/runtime/pull/99199 @wcsanders1 @steveharter

So this app only registers the IInstallationLocalizationService when databaseInstalled is not set. https://github.com/grandnode/grandnode/blob/c209758031e88d0279a023a7237b1f68ebd9f4dc/Grand.Services/Infrastructure/DependencyRegistrar.cs#L277-L282

However, it will always register validators, regardless of this: https://github.com/grandnode/grandnode/blob/c209758031e88d0279a023a7237b1f68ebd9f4dc/Grand.Framework/Infrastructure/DependencyRegistrar.cs#L116-L135

The InstallValidator will fail construction because it doesn't have the IInstallationLocalizationService https://github.com/grandnode/grandnode/blob/c209758031e88d0279a023a7237b1f68ebd9f4dc/Grand.Web/Validators/Install/InstallValidator.cs#L9-L23

I can fix this in the application by registering the IInstallationLocalizationService regardless of the databaseInstalled.

This got me past the first error, but then I hit:

Unable to resolve service for type 'WebEssentials.AspNetCore.Pwa.PwaOptions' while attempting to activate 'WebEssentials.AspNetCore.Pwa.PwaController'.

That's also related to conditional service registration: https://github.com/grandnode/grandnode/blob/c209758031e88d0279a023a7237b1f68ebd9f4dc/Grand.Framework/Infrastructure/Extensions/ServiceCollectionExtensions.cs#L444-L460

I couldn't see why it was trying to create a PwaController during validation (maybe assembly registration, or someone looking for all Controller instances???), but I was able to remove the conditions on adding the PwaOptions to get past that. Then I hit

'Cannot consume scoped service 'Grand.Domain.Security.SecuritySettings' from singleton 'Microsoft.AspNetCore.Mvc.Infrastructure.IActionResultExecutor`1[Microsoft.AspNetCore.Mvc.RedirectResult]'.'

At this point I stopped hacking. I worked around the change by setting ASPNETCORE_ENVIRONMENT=Staging.

Seems to me like this app even tried to disable validation, but we ignored that: https://github.com/grandnode/grandnode/blob/c209758031e88d0279a023a7237b1f68ebd9f4dc/Grand.Web/Program.cs#L38-L39 I think we should have cleared _defaultProviderFactoryUsed with the call to UseDefaultServiceProvider at least.

@wcsanders1 @steveharter @halter73 could you have a look here? Do you think others might face breaking changes like this with #99199 such that we should revert it, or is this a one off?

Junjun-zhao commented 4 months ago

Verified and this issue has been fixed on dotnet-sdk-9.0.100-preview.7.24379.15