dotnet / aspnetcore

ASP.NET Core is a cross-platform .NET framework for building modern cloud-based web applications on Windows, Mac, or Linux.
https://asp.net
MIT License
35.21k stars 9.95k forks source link

Minimal code pattern doesn't work with OrchardCore in net6.0 #34210

Closed eerhardt closed 3 years ago

eerhardt commented 3 years ago

Describe the bug

When trying to use the new minimal Main method pattern in ASP.NET 6 and loading OrchardCore, I'm getting an exception that the IHostEnvironment service is not available.

To Reproduce

  1. Build and run the following application
    <Project Sdk="Microsoft.NET.Sdk.Web">
    <PropertyGroup>
    <TargetFramework>net6.0</TargetFramework>
    </PropertyGroup>
    <ItemGroup>
    <PackageReference Include="OrchardCore.Application.Cms.Targets" Version="1.0.0-rc2-13450" />
    </ItemGroup>
    </Project>
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddOrchardCms();
var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.UseDeveloperExceptionPage();
}

app.UseRouting();

app.UseStaticFiles();

app.UseOrchardCore();

app.Run();
  1. Navigate to https://localhost:5001/

image

Notes

Note that if I write the Main method using the configure lambda pattern in https://github.com/dotnet/aspnetcore/issues/34208, that this exception doesn't occur.

Exceptions (if any)

fail: Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[1]
      An unhandled exception has occurred while executing the request.
      System.InvalidOperationException: No service for type 'Microsoft.Extensions.Hosting.IHostEnvironment' has been registered.
         at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType) in Microsoft.Extensions.DependencyInjection.Abstractions.dll:token 0x6000095+0x4f
         at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider) in Microsoft.Extensions.DependencyInjection.Abstractions.dll:token 0x6000096+0x0
         at OrchardCore.Mvc.ShellViewFeatureProvider..ctor(IServiceProvider services) in C:\projects\orchardcore\src\OrchardCore\OrchardCore.Mvc.Core\ShellViewFeatureProvider.cs:line 25
         at OrchardCore.Mvc.Startup.AddModularFrameworkParts(IServiceProvider services, ApplicationPartManager manager) in C:\projects\orchardcore\src\OrchardCore\OrchardCore.Mvc.Core\Startup.cs:line 134
         at OrchardCore.Mvc.Startup.ConfigureServices(IServiceCollection services) in C:\projects\orchardcore\src\OrchardCore\OrchardCore.Mvc.Core\Startup.cs:line 95
         at OrchardCore.Environment.Shell.Builders.ShellContainerFactory.CreateContainer(ShellSettings settings, ShellBlueprint blueprint) in C:\projects\orchardcore\src\OrchardCore\OrchardCore\Shell\Builders\ShellContainerFactory.cs:line 155
         at OrchardCore.Environment.Shell.Builders.ShellContextFactory.CreateDescribedContextAsync(ShellSettings settings, ShellDescriptor shellDescriptor) in C:\projects\orchardcore\src\OrchardCore\OrchardCore\Shell\Builders\ShellContextFactory.cs:line 76
         at OrchardCore.Environment.Shell.Builders.ShellContextFactory.OrchardCore.Environment.Shell.Builders.IShellContextFactory.CreateSetupContextAsync(ShellSettings settings) in C:\projects\orchardcore\src\OrchardCore\OrchardCore\Shell\Builders\ShellContextFactory.cs:line 63
         at OrchardCore.Environment.Shell.ShellHost.PreCreateAndRegisterShellsAsync() in C:\projects\orchardcore\src\OrchardCore\OrchardCore\Shell\ShellHost.cs:line 279
         at OrchardCore.Environment.Shell.ShellHost.InitializeAsync() in C:\projects\orchardcore\src\OrchardCore\OrchardCore\Shell\ShellHost.cs:line 60
         at OrchardCore.Modules.ModularTenantContainerMiddleware.Invoke(HttpContext httpContext) in C:\projects\orchardcore\src\OrchardCore\OrchardCore\Modules\ModularTenantContainerMiddleware.cs:line 31
         at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context) in Microsoft.AspNetCore.Diagnostics.dll:token 0x60000aa+0x82

Further technical details

Runtime Environment: OS Name: Windows OS Version: 10.0.19043 OS Platform: Windows RID: win10-x64 Base Path: C:\dotnet\sdk\6.0.100-preview.7.21357.29\

Host (useful for support): Version: 6.0.0-preview.7.21356.2 Commit: 566b53a66b

.NET SDKs installed: 6.0.100-preview.7.21357.29 [C:\dotnet\sdk]

.NET runtimes installed: Microsoft.AspNetCore.App 6.0.0-preview.7.21355.4 [C:\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.NETCore.App 6.0.0-preview.7.21356.2 [C:\dotnet\shared\Microsoft.NETCore.App] Microsoft.WindowsDesktop.App 6.0.0-preview.7.21352.1 [C:\dotnet\shared\Microsoft.WindowsDesktop.App]

To install additional .NET runtimes or SDKs: https://aka.ms/dotnet-download


- The IDE (VS / VS Code/ VS4Mac) you're running on, and its version: n/a

cc @davidfowl 
davidfowl commented 3 years ago

Here's the issue without orchard:

using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

var builder = WebApplication.CreateBuilder(args);

// Add the service collection to the service collection 
builder.Services.AddSingleton(builder.Services);

var app = builder.Build();

// This works fine
var env = app.Services.GetRequiredService<IHostEnvironment>();

// This will go boom because the IHostEnvironment wasn't in the IServiceCollection
env = app.Services.GetRequiredService<IServiceCollection>().BuildServiceProvider().GetRequiredService<IHostEnvironment>();

Typically the IHostEnvironment is added by the HostBuilder this happens when you build. Using the callback model we get access to all of the services because we run user code after adding these defaults but we don't get access to them with the minimal host.

@halter73 this is the same problem you brought up earlier, looks like orchard hits that edge case and its no longer an edge case 😄

Looking at the slew of services here it seems the ones you'd want to access in this edgecasey way is IHostEnviroment and IHostApplicationLifetime