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.43k stars 10.02k forks source link

Application DLL cannot be loaded once hosting model is switched OutOfProcess #57949

Open EllaCorvinMRI opened 1 month ago

EllaCorvinMRI commented 1 month ago

I have a .Net 8 web app deployed to an Azure app service. There are 2 components, and because one of them is deployed as a virtual application / sub-app, I had to switch to both components using the OutOfProcess hosting model (this is because both, mixed models and two InProcess models, errored out in Azure as not allowed). When I was only deploying the main app and it was using the InProcess model, it ran in Azure fine. As soon as I switched to OutOfProcess, they both error out on startup, with the error stack below in the logs.

What additional setup or configuration do I need in order to avoid this error and load all of the DLLs successfully when deploying OutOfProcess?

Error Stack:

Microsoft.AspNetCore.Hosting.Diagnostics: Application startup exception System.IO.FileNotFoundException: Could not load file or assembly 'DVS.ServiceContract, Culture=neutral, PublicKeyToken=null'. The system cannot find the file specified. File name: 'DVS.ServiceContract, Culture=neutral, PublicKeyToken=null' at System.Reflection.RuntimeAssembly.InternalLoad(AssemblyName assemblyName, StackCrawlMark& stackMark, AssemblyLoadContext assemblyLoadContext, RuntimeAssembly requestingAssembly, Boolean throwOnFileNotFound) at System.Reflection.Assembly.Load(String assemblyString) at Microsoft.AspNetCore.Mvc.ApplicationParts.ApplicationPartManager.<>c.b8_0(ApplicationPartAttribute name) at System.Linq.Enumerable.SelectArrayIterator2.Fill(ReadOnlySpan1 source, Span1 destination, Func2 func) at System.Linq.Enumerable.SelectArrayIterator2.ToArray() at System.Linq.Buffer1..ctor(IEnumerable1 source) at System.Linq.OrderedEnumerable1.GetEnumerator()+MoveNext() at System.Linq.Enumerable.SelectManySingleSelectorIterator2.MoveNext() at System.Linq.Enumerable.ConcatIterator1.MoveNext() at Microsoft.AspNetCore.Mvc.ApplicationParts.ApplicationPartManager.PopulateDefaultParts(String entryAssemblyName) at Microsoft.Extensions.DependencyInjection.MvcCoreServiceCollectionExtensions.GetApplicationPartManager(IServiceCollection services, IWebHostEnvironment environment) at Microsoft.Extensions.DependencyInjection.MvcCoreServiceCollectionExtensions.AddMvcCore(IServiceCollection services) at Microsoft.Extensions.DependencyInjection.MvcServiceCollectionExtensions.AddControllersCore(IServiceCollection services) at Microsoft.Extensions.DependencyInjection.MvcServiceCollectionExtensions.AddControllersWithViewsCore(IServiceCollection services) at Microsoft.Extensions.DependencyInjection.MvcServiceCollectionExtensions.AddControllersWithViews(IServiceCollection services) at Microsoft.Extensions.DependencyInjection.MvcServiceCollectionExtensions.AddMvc(IServiceCollection services) at VsOnline.Reporting.Startup.ConfigureServices(IServiceCollection services) in D:\a\1\s\src\VsOnline.Reporting\Startup.cs:line 168 at System.RuntimeMethodHandle.InvokeMethod(Object target, Void* arguments, Signature sig, Boolean isConstructor) at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr args) at System.Reflection.MethodBaseInvoker.InvokeDirectByRefWithFewArgs(Object obj, Span`1 copyOfArgs, BindingFlags invokeAttr) at System.Reflection.MethodBaseInvoker.InvokeWithOneArg(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) at Microsoft.AspNetCore.Hosting.ConfigureServicesBuilder.InvokeCore(Object instance, IServiceCollection services) at Microsoft.AspNetCore.Hosting.ConfigureServicesBuilder.<>cDisplayClass9_0.gStartup|0(IServiceCollection serviceCollection) at Microsoft.AspNetCore.Hosting.ConfigureServicesBuilder.Invoke(Object instance, IServiceCollection services) at Microsoft.AspNetCore.Hosting.ConfigureServicesBuilder.<>cDisplayClass8_0.b0(IServiceCollection services) at Microsoft.AspNetCore.Hosting.GenericWebHostBuilder.UseStartup(Type startupType, HostBuilderContext context, IServiceCollection services, Object instance) --- End of stack trace from previous location --- at Microsoft.AspNetCore.Hosting.GenericWebHostBuilder.<>cDisplayClass9_0.b2(IApplicationBuilder app) at Microsoft.AspNetCore.Server.IISIntegration.IISSetupFilter.<>cDisplayClass4_0.b0(IApplicationBuilder app) at Microsoft.AspNetCore.HostFilteringStartupFilter.<>cDisplayClass0_0.b0(IApplicationBuilder app) at Microsoft.ApplicationInsights.AspNetCore.ApplicationInsightsStartupFilter.<>cDisplayClass2_0.b__0(IApplicationBuilder app) at Microsoft.AspNetCore.Hosting.GenericWebHostService.StartAsync(CancellationToken cancellationToken)

gfoidl commented 1 month ago

As the DVS.ServiceContract assembly is loaded via reflection (and most likely w/ relative path), I guess that the working directory isn't set to a place where that assembly can be found.

Please try to display Environment.CurrentDirectory and see what value it has.

If the cur-dir doesn't match, you can set it early at startup (Program.cs) to AppContext.BaseDirectory (or whatever path the assembly is resided).

EllaCorvinMRI commented 1 month ago

Thanks for your response. However, if this were a matter of the working directory not being set to a place where that assembly could be found, why would it load just fine with the InProcess hosting model? This DLL is actually part of a package from the vendor's package source which is part of the build. In Kudu, when I go to site/wwwroot, I can see this DLL in the directory, so it's definitely there, right along with all the other binaries. This ONLY doesn't work on the branch where I'm switching to the OutOfProcess hosting model.