.Net5 version-tolerant assembly loading

200 views Asked by At

I have the following situation in .Net5/C# that I'm struggling to resolve. We have Application (let's call it Platform) U that is able to load plugins, e.g. Plugin P, referencing Utilities U which is part of the Platform and shares its version. Our idea is, that anything within minor version should be compatible, i.e. A with version 3.1.x.y should be able to load any P with version 3.1.x.y.

Now, the Platform was deployed with version 3.1.1.10 and Plugin P we want to load was built targeting Application A with version 3.1.1.15.

This means, Platform is now running with Utilities U which has the same version, 3.1.1.10. When packaging our plugins, we do not include anything that is already available in the Platform, in this case Utilities U.

When loading the plugin, we call:

Assembly.LoadFrom(pathToPluginDll);

Not surprisingly, when loading the plugin, it also tries to load its dependency Utilities U with version 3.1.1.15 (which we do not provide at this place).

Was I want now is to simply load Utilities 3.1.1.10 that is already provided by the Platform. How can I achieve that?

I did quite some research but could not find anything to work. BindingRedirect seems to be an easy way to resolve this for .NET Framework, but not for .NET5 anymore. I also experimented with EnableDynamicLoading / RollForward, and the deps.json file, but without success.

Thanks for any hints/help in advance. I feel like I'm missing something simple.

1

There are 1 answers

0
Ildrial On BEST ANSWER

I was able to find a solution with AssemblyResolve:

internal PluginLoader() {
    AppDomain.CurrentDomain.AssemblyResolve += AssemblyResolver;
}

...

private static Assembly AssemblyResolver(object source, ResolveEventArgs e) {
    var expectedAssembly = new AssemblyName(e.Name);
    var assembly = AppDomain.CurrentDomain.GetAssemblies()
        .SingleOrDefault(a => a.GetName().Name.Equals(expectedAssembly.Name));
    return VersionMatches(assembly.GetName().Version, expectedAssembly.Version) ? assembly : null;
}

I was hoping to find a solution on some config level (as with binding redirect), but this looks easy enough. Still, let me know if any better solutions exist.