How to programmatically override assembly binding?

736 views Asked by At

I've got an AppDomain hosted plugin architecture. Each plugin is installed in their own folders together with whatever dependency assemblies they need. At runtime the plugins are instantiated into their own AppDomains together with the optional plugin.config file that they can use to specify assembly redirects, etc.

The interfaces for Host-Plugin communication are defined in My.API assembly. The host application has its own My.API assembly, but it is likely that the plugins will bundle the My.API assembly as their dependency as well.

As long as these two My.API assemblies are the same version there's no problem - however if the host application is updated with a newer version of My.API assembly, it would be best to use this backwards compatible My.API assembly for the plugin as well.

Is there a way to force the Host-installed My.API assembly to be loaded in the plugin app domain (and used for assembly binding) instead of the My.API assembly that is located in the plugin folder, which is defined as the ApplicationBase of the AppDomain?

The usual AssemblyResolve events won't work here as those are triggered only when the assembly bind fails - in this case the assembly bind succeeds, but it will bind to the possibly outdated assembly.

I can force the correct assembly to be loaded with LoadFrom, but this doesn't populate the assembly binding cache, which will still load the plugin assembly when assembly binding occurs.

One option I've came up with is to programmatically insert an assembly redirect into the plugin.config to force the My.API to be loaded as version 9999.0.0.0. I expect this would result in AssemblyResolve event that I could then resolve using the correct version of the assembly. However as far as I know, the only way to insert the redirection is to physically modify the plugin.config - something I would like to stay away from.

Are there any other approaches to force a specific assembly binary into the app domain?

I guess publisher policies might be able to solve this, but don't those need GAC deployment? Currently none of the assemblies are deployed into GAC. There might be various versions of the application installed and each of these should be using their specific versions of assemblies. GAC would end up forcing v1.0 of the application to end up with v2.0 assemblies - while only v1.0 plugin in v2.0 application should redirect to v2.0 assemblies.

(We're currently using static 1.0.0.0 assembly version so having different assembly identities shouldn't be a problem as long as we could redirect the physical path.)

0

There are 0 answers