title: Custom AssemblyLoadContext failing to load Microsoft.AspNetCore.Components
body: <p><strong>Edit:  I have uploaded the source code for the issue to GitHub if you would like to download:  <a href="https://github.com/bryanenroute/assemblyloadcontext-issue" rel="nofollow noreferrer">https://github.com/bryanenroute/assemblyloadcontext-issue</a></strong></p>
  
  <p>I have a .NET Core 3.0 console application that references a .NET Standard 2.0 class library with a single interface (IModule).  I also have a ASP.NET Core 3.0 application that references the same .NET Standard 2.0 class library and implements the interface (Module : IModule).</p>
  
  <p>I am trying to load the ASP.NET Core assembly from the .NET Core console application using a custom AssemblyLoadContext and a common class library interface (IModule)... a simple plugin system.</p>
  
  <p>Unfortunately, the ASP.NET Core module/plugin fails in the ALC override function for Load(AssemblyName) with the following exception:</p>
  
  <p><strong>Could not load file or assembly 'Microsoft.AspNetCore.Components, Version=3.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'. The system cannot find the file specified.</strong></p>
  
  <p>When I try with a different project type (e.g. .NET Core Console Application or .NET Standard 2.0 Class Library), the module/plugin loads as intended.</p>
  
  <p>Here's the Console app code:</p>
  
  <pre><code>
  using NetStandardCommon;
  using System;
  using System.IO;
  
  namespace NetCoreConsoleApp
  {
      class Program
      {
          static void Main(string[] args)
          {
              LoadNetCoreModule();
              LoadAspNetCoreModule();
          }
  
          static void LoadNetCoreModule()
          {
              //Works!
              FileInfo asm = new FileInfo(@"..\..\..\..\NetCoreModule\bin\debug\netcoreapp3.0\NetCoreModule.dll");
              var moduleDirectory = asm.DirectoryName;
  
              ModuleAssemblyLoadContext context = new ModuleAssemblyLoadContext(asm.Name, moduleDirectory, typeof(IModule));
              context.Scan();
  
              foreach (var module in context.GetImplementations&lt;IModule&gt;())
              {
                  module.Start();
              }
          }
  
          static void LoadAspNetCoreModule()
          {
              //Fails!
              FileInfo asm = new FileInfo(@"..\..\..\..\AspNetCoreApp\bin\debug\netcoreapp3.0\AspNetCoreApp.dll");
              var moduleDirectory = asm.DirectoryName;
  
              ModuleAssemblyLoadContext context = new ModuleAssemblyLoadContext(asm.Name, moduleDirectory, typeof(IModule));
              context.Scan();
  
              foreach (var module in context.GetImplementations&lt;IModule&gt;())
              {
                  module.Start();
              }
          }
      }
  }
  
  
  </code></pre>
  
  <p>Here's the ModuleAssemblyLoadContext code:</p>
  
  <pre><code>using System;
  using System.Collections.Generic;
  using System.IO;
  using System.Reflection;
  using System.Runtime.Loader;
  using System.Linq;
  
  namespace NetCoreConsoleApp
  {
      public class ModuleAssemblyLoadContext : AssemblyLoadContext
      {
          private List&lt;Assembly&gt; _loaded;
          private Dictionary&lt;string, Assembly&gt; _shared;
  
          private string _path;
  
          private AssemblyDependencyResolver _resolver;
  
          public ModuleAssemblyLoadContext(string name, string path, params Type[] sharedTypes) : base(name)
          {
              _path = path;
              _resolver = new AssemblyDependencyResolver(_path);
  
              _loaded = new List&lt;Assembly&gt;();
              _shared = new Dictionary&lt;string, Assembly&gt;();
  
              if (sharedTypes != null)
              {
                  foreach (Type sharedType in sharedTypes)
                  {
                      _shared[Path.GetFileName(sharedType.Assembly.Location)] = sharedType.Assembly;
                  }
              }
          }
  
          public void Scan()
          {
              foreach (string dll in Directory.EnumerateFiles(_path, "*.dll"))
              {
                  var file = Path.GetFileName(dll);
  
                  if (_shared.ContainsKey(file))
                  {
                      continue;
                  }
  
                  var asm = this.LoadFromAssemblyPath(dll);
  
                  _loaded.Add(asm);
              }
          }
  
          public IEnumerable&lt;T&gt; GetImplementations&lt;T&gt;()
          {
              return _loaded
                  .SelectMany(a =&gt; a.GetTypes())
                  .Where(t =&gt; typeof(T).IsAssignableFrom(t))
                  .Select(t =&gt; Activator.CreateInstance(t))
                  .Cast&lt;T&gt;();
          }
  
          protected override Assembly Load(AssemblyName assemblyName)
          {
              string filename = $"{assemblyName.Name}.dll";
              if (_shared.ContainsKey(filename))
              {
                  return _shared[filename];
              }
  
              string assemblyPath = _resolver.ResolveAssemblyToPath(assemblyName);
              if (assemblyPath != null)
              {
                  return LoadFromAssemblyPath(assemblyPath);
              }
  
              return null;
          }
  
          protected override IntPtr LoadUnmanagedDll(string unmanagedDllName)
          {
              string libraryPath = _resolver.ResolveUnmanagedDllToPath(unmanagedDllName);
              if (libraryPath != null)
              {
                  return LoadUnmanagedDllFromPath(libraryPath);
              }
  
              return IntPtr.Zero;
          }
      }
  }
  
  
  </code></pre>
  
  <p>I tried modifying the ALC Load function to load the assemblies directly from the shared folder (C:\Program Files (x86)\dotnet\shared\Microsoft.AspNetCore.App\3.0.0) which lets the execution continue a bit farther, but it ultimately fails with the following exception:</p>
  
  <p><strong>An attempt was made to load a program with an incorrect format. (0x8007000B)</strong></p>
  
  <p>Here's the revised Load function:</p>
  
  <pre><code>        protected override Assembly Load(AssemblyName assemblyName)
          {
              string filename = $"{assemblyName.Name}.dll";
              if (_shared.ContainsKey(filename))
              {
                  return _shared[filename];
              }
  
              try
              {
                  if (File.Exists(@"C:\Program Files (x86)\dotnet\shared\Microsoft.AspNetCore.App\3.0.0\" + filename))
                  {
                      return Assembly.LoadFrom(@"C:\Program Files (x86)\dotnet\shared\Microsoft.AspNetCore.App\3.0.0\" + filename);
                  }
              }
              catch (Exception ex)
              {
                  //Message displayed is 'An attempt was made to load a program with an incorrect format. (0x8007000B)'
                  Console.WriteLine(ex.Message);
              }
  
              return Assembly.Load(assemblyName);
          }
  </code></pre>
  
  <p>I'm excited about the possibilities of loading/unloading assemblies for a .net Core plugin system, but I'm struggling to get over this hurdle.  What am I missing?</p>