title: How to dynamically load assemblies in dotnet core
body: <p>I'm building a web application, where I would like separate concerns, i.e. having abstractions and implementations in different projects.</p>
  
  <p>To achieve this, I've tried to implement a composition root concept, where all implementation must have an instance of <code>ICompositionRootComposer</code> to register services, types etc.</p>
  
  <pre><code>public interface ICompositionRootComposer
  {
      void Compose(ICompositionConfigurator configurator);
  }
  </code></pre>
  
  <p>In projects that are referred directly in the build hierarchy, implementations of <code>ICompositionRootComposer</code> are called, and services are registered correct in the underlying IoC container.</p>
  
  <p>The problem arises when I'm trying to register services in a project, where I've set up a post build task that copies the built dll to the web project's debug folder: </p>
  
  <pre><code>cp -R $(TargetDir)"assembly and symbol name"* $(SolutionDir)src/"webproject path"/bin/Debug/netcoreapp1.1
  </code></pre>
  
  <p>I'm loading the assembly with: (Inspiration: <a href="https://stackoverflow.com/questions/37895278/how-to-load-assemblies-located-in-a-folder-in-net-core-console-app">How to load assemblies located in a folder in .net core console app</a>)</p>
  
  <pre><code>internal class AssemblyLoader : AssemblyLoadContext
  {
      private string folderPath;
  
      internal AssemblyLoader(string folderPath)
      {
          this.folderPath = Path.GetDirectoryName(folderPath);
      }
  
      internal Assembly Load(string filePath)
      {
          FileInfo fileInfo = new FileInfo(filePath);
          AssemblyName assemblyName = new AssemblyName(fileInfo.Name.Replace(fileInfo.Extension, string.Empty));
  
          return this.Load(assemblyName);
      }
  
      protected override Assembly Load(AssemblyName assemblyName)
      {
          var dependencyContext = DependencyContext.Default;
          var ressource = dependencyContext.CompileLibraries.FirstOrDefault(r =&gt; r.Name.Contains(assemblyName.Name));
  
          if(ressource != null)
          {
              return Assembly.Load(new AssemblyName(ressource.Name));
          }
  
          var fileInfo = this.LoadFileInfo(assemblyName.Name);
          if(File.Exists(fileInfo.FullName))
          {
              Assembly assembly = null;
              if(this.TryGetAssemblyFromAssemblyName(assemblyName, out assembly))
              {
                  return assembly;
              }
              return this.LoadFromAssemblyPath(fileInfo.FullName);
          }
  
          return Assembly.Load(assemblyName);
      }
  
      private FileInfo LoadFileInfo(string assemblyName)
      {
          string fullPath = Path.Combine(this.folderPath, $"{assemblyName}.dll");
  
          return new FileInfo(fullPath);
      }
  
      private bool TryGetAssemblyFromAssemblyName(AssemblyName assemblyName, out Assembly assembly)
      {
          try
          {
              assembly = Default.LoadFromAssemblyName(assemblyName);
              return true;
          }
          catch
          {
              assembly = null;
              return false;
          }
      }
  }
  </code></pre>
  
  <p>With this I'm able to load the assembly and call the projects <code>ICompositionRootComposer</code> implementation.</p>
  
  <p>But the problem is that it doesn't seem to recognize any of my types.</p>
  
  <p>When calling my configurator with</p>
  
  <pre><code>configurator.RegisterTransiantService&lt;IFoo, Foo&gt;();
  </code></pre>
  
  <p>it should register IFoo and Foo in the IoC.<br>
  But when debugging I'm not able to get info of the types, i.e via typeof(Foo) in the debug console in Visual Studio Code.</p>