Search code examples
c#nugetlazy-loadingmef

NuGet dependencies in MEF loaded assemblies


I am trying to code an application in C#.NET Core that can be extended using MEF. Currently, I am able to do that without any issues with libraries, that have no dependencies or have the same dependencies as the host app (so dependencies are already loaded). But, if I want to use a library with a NuGet reference, that is not used by the main app, the loading of this library fails on that reference.

How can I force the main app to load the missing NuGet dependency, if it tries to load an assembly with such reference? It seems to me as a pretty common use case, but I am lost here and cannot find a way out. Thanks.

For reference, I am posting the portion of the code.

[ImportMany]
private IEnumerable<Lazy<IService, IServiceMetadata>> _asrServices;

...

var catalog = new AggregateCatalog();
catalog.Catalogs.Add(new DirectoryCatalog(Path.Combine(Directory.GetCurrentDirectory(), "Services")));          
CompositionContainer _container = new CompositionContainer(catalog);

...

foreach (Lazy<IService, IServiceMetadata> _service in _asrServices)
{
   var _serviceInstance = _service.Value // here the loading fails
}

Jiri


Solution

  • .NET currently has two build "systems". One is the original project files, that import Microsoft.Common.props and Microsoft.CSharp.targets (assuming it's a c# project) and lots of XML in between, that has been around ever since .NET was first released, apparently in 2002. Since .NET Core was made generally available in 2016 there has been a new project system generally called SDK projects because the way a *proj file references the build system is though an Sdk element or attribute in the msbuild xml. Although it's off-topic, because there's a common bad assumption, I want to point out that although SDK projects were created for .NET Core, you can target the .NET Framework from SDK projects.

    With the original project files, when you build, all the projects references get copied to the output directory. However, with SDK projects, only the project's assembly is copied to output (I'm not sure, but I think even content set to copy to output doesn't actually get copied on build). In order to get everything in a single directory, you should use the dotnet cli's publish command.

    So, if you have a build script that builds your project and copies all the plugins somewhere, you should add a dotnet publish step to the script for each plugin using the SDK style project file.