4

The Background:

  1. Consuming application is a website built using .NET Core 3.1.
  2. Consuming application references a NuGet package built using .NET Standard 2.0.
  3. The consuming application has a reference to the latest version of the NuGet package and builds without any errors or warnings.
  4. The DLL from the NuGet package is visible in the bin\debug\netcoreapp31\ and bin\release\netcoreapp31\ folders.
  5. In the IDE, full IntelliSense for the types in the NuGet package is available, including the XML Documentation comments for types, methods, and parameters.
  6. At runtime, at the first reference to any type in the NuGet package, a FileNotFound exception is thrown, reporting that the DLL from the NuGet package file cannot be found.

What I have tried:

  1. Verifying that the PackageReference entries in the .csproj file is correct. Since it's a .NET Core application, there are no hint paths or assembly binding redirects that are interfering with assembly binding.
  2. Clearing the NuGet cache.
  3. Removing and re-adding the NuGet package.
  4. Forcing NuGet to reinstall the package through the Package Manager Console.
  5. Cleaning and rebuilding the solution.
  6. Enabling Fusion Log Viewer and combing through the logs. This is where things get interesting. There are no entries in the logs indicating any attempts to resolve or load the assembly, or any entries indicating that the assembly bind failed.

Exception Message

Could not load file or assembly 'OneCall.FeatureFlags, Version=1.0.0.0, Culture=en-US, PublicKeyToken=null'. The system cannot find the file specified.
   at PTWebAPI.Startup.ConfigureServices(IServiceCollection services) in C:\Dev\PTWebAPI\PTWebAPI\Startup.cs:line 65
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor, Boolean wrapExceptions)
   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.<>c__DisplayClass9_0.<Invoke>g__Startup|0(IServiceCollection serviceCollection)
   at Microsoft.AspNetCore.Hosting.StartupLoader.ConfigureServicesDelegateBuilder`1.<>c__DisplayClass15_0.<BuildStartupServicesFilterPipeline>g__RunPipeline|0(IServiceCollection services)
   at Microsoft.AspNetCore.Hosting.ConfigureServicesBuilder.Invoke(Object instance, IServiceCollection services)
   at Microsoft.AspNetCore.Hosting.ConfigureServicesBuilder.<>c__DisplayClass8_0.<Build>b__0(IServiceCollection services)
   at Microsoft.AspNetCore.Hosting.StartupLoader.ConfigureServicesDelegateBuilder`1.<>c__DisplayClass14_0.<ConfigureServices>g__ConfigureServicesWithContainerConfiguration|0(IServiceCollection services)
   at Microsoft.AspNetCore.Hosting.ConventionBasedStartup.ConfigureServices(IServiceCollection services)
   at Microsoft.AspNetCore.Hosting.WebHost.EnsureApplicationServices()
   at Microsoft.AspNetCore.Hosting.WebHost.Initialize()
   at Microsoft.AspNetCore.Hosting.WebHostBuilder.Build()
   at PTWebAPI.Program.Main(String[] args) in C:\Dev\PTWebAPI\PTWebAPI\Program.cs:line 15

Point of Failure

public static void Main(string[] args)
{
   CreateWebHostBuilder(args).Build().Run(); // <-- Right here
}

The Question

What causes this particular exception when loading an assembly in a .NET Core application, and how do you resolve it?

Mike Hofer
  • 16,477
  • 11
  • 74
  • 110
  • Did you check the "TargetFramework", I've experienced some problems when they don't match. – Jeroen van Langen Nov 17 '21 at 22:46
  • Maybe.... its like something in the class/property in the package is missing due to a newer version and links, but fails at runtime due to a dynamic call...., is the package set to `[Get] the latest` and pulling in what you expect instead of the `least version`? See my answer here: [System.MissingMethodException: Method not found?](https://stackoverflow.com/a/36344325/285795) – ΩmegaMan Nov 17 '21 at 23:16
  • @JeroenvanLangen The `TargetFramework` shouldn't be an issue. However, the consuming application targets .NET Core 3.1, and the NuGet package targets .NET Standard 2.0. From what I understand, a .NET Core application should have no issues whatsoever consuming a .NET Standard 2.0 NuGet package. – Mike Hofer Nov 18 '21 at 11:17
  • @ΩmegaMan There aren't any dynamic calls involved at all. In fact, the call that fails is a call to a method on a static type in the NuGet package. Also, the same call succeeds when the NuGet package is consumed in a .NET Framework application. – Mike Hofer Nov 18 '21 at 11:19
  • 1
    Worth a shot, next step, is to create a minimally reproducible example ... maybe creating that will tip you off to what the real issue is. :-/ – ΩmegaMan Nov 18 '21 at 15:17
  • 1. What nuget package you are trying to use.? 2. What is the full exception? – Hamlet Hakobyan Nov 29 '21 at 13:56
  • @HamletHakobyan It's a custom NuGet package we've built internally, targeting .NET Standard 2.0. – Mike Hofer Nov 29 '21 at 13:57
  • does it refer any unmanaged dll? – Hamlet Hakobyan Nov 29 '21 at 13:58
  • @HamletHakobyan No. All it references are NuGet packages that also target .NET Standard. – Mike Hofer Nov 29 '21 at 13:58
  • What about full exception? do you load assembly dynamically? – Hamlet Hakobyan Nov 29 '21 at 14:00
  • @HamletHakobyan I'll add full exception detail to the body of the message, but we don't load it dynamically. It's part of the `CreateWebHostBuilder(args).Build().Run()` call in Main. – Mike Hofer Nov 29 '21 at 14:03
  • 1
    Are you sure that the culture of the assembly that you are trying to load is the same in the reference? I see you are trying to load assembly with culture en-us, maybe the assembly in the nuget package has different culture, says neutral. Also, if the referencing assembly is digitally signed, it cant load an unsigned assembly. – Hamlet Hakobyan Nov 29 '21 at 14:22
  • I know this kind of exception if a referenced nuget package has a reference to any other package or library which is not delivered with the nuget package itself. The build and everything else went well for me as well but then I got a runtime error. But not sure if this is your problem as well. – Sebastian S. Dec 01 '21 at 22:46
  • Any chance you have included a nugget package (some latest version) built for a newer version of the .NET Core? If so, build will execute just fine, but in runtime you'll get an error as described. Maybe ensure all included nugget packages target .net core 3.1. – Nesaje Dec 02 '21 at 09:58
  • What's the exact exception type? Any inner exception? Otherwise, use procmon from sysinternals: https://learn.microsoft.com/en-us/sysinternals/downloads/procmon filter by your .exe name, and observe file events, there should be request for this file in specific paths passing in there. – Simon Mourier Dec 02 '21 at 15:58
  • @HamletHakobyan It was the culture on the NuGet package, which was set to "en-US". The consuming assembly's culture was neutral. Everything worked fine when I set the culture of the NuGet package to neutral to match the consumer. If you'll post your suggestion as an answer, I'll award the bounty to you. – Mike Hofer Dec 02 '21 at 21:23
  • That is not necessary, just add a well formed consistent answer with troubleshooting steps and mark as accepted answer for future SO searchers. – Hamlet Hakobyan Dec 03 '21 at 09:29

1 Answers1

1

The issue turned out to be the culture on the NuGet package itself.

The culture on the NuGet package was set to "en-US", while the culture on the consuming assembly was set to neutral (""). This prevented the consuming assembly from being able to load the NuGet package's assembly at runtime.

The solution was to set the culture on the NuGet package to neutral (""), republish the package, and update the package reference in the consuming assembly.

(Thanks to Hamlet Hakobyan for pointing me in the right direction.)

Mike Hofer
  • 16,477
  • 11
  • 74
  • 110