Search code examples
c#asp.net.net.net-assemblymef

How can MEF AssemblyCatalogs be used with custom AssemblyLoadContexts


I am working on an ASP.NET Core API that is extensible with Plug-Ins. Because the Plug-In Assemblies need to be unloadable, I've started loading them into separate, collectible, AssemblyLoadContexts.

The Implementation basically looks like this:

// Creating a new Context for the Plugin.
AssemblyLoadContext context = new AssemblyLoadContext(directoryInfo.FullName, true);
...

// Loading every Assembly the Plugin uses into the Context.
Assembly assembly = context.LoadFromAssemblyPath(fileInfo.FullName);
...

// Creating AssemblyCatalogs with the Assemblies.
AssemblyCatalog assemblyCatalog = new AssemblyCatalog(assembly);

This works and I can use the Assemblies normally. However, the AssemblyCatalogs all have unpopulated Parts Properties and thus will not compose.

Now, if I load the Assemblies into the Default Context (AssemblyLoadContext.Default), everything works as expected, except the unloading of course.

What am I missing? Thanks for pointing me in the right direction :)


Solution

  • Okay, turns out I've made a mistake. My Plug-In Project had CopyLocalLockFileAssemblies set to true and because of this, copied the NuGet dependencies to the output directory. Since I would then just copy the output to the directory the API loads its Plug-Ins from, the API tried to load these referenced libraries as well. Now, both the API and Plug-In Project reference System.ComponentModel.Composition and - long story short - the DLL was loaded twice, in different versions. The API was using 6.0.0 and the Plug-In was using 4.0.0.

    Because of this, the attribute comparison (MEF finds its exports by looking for the ExportAttribute) would later fail which is why the AssemblyCatalog was not able to find the Exports.

    enter image description here