Yes, indeed. If you are writing a plugin, an app.config file is useless for redirecting assemblies. The plugin will look 1st to the machine.config file on the user's computer, then look to the *.config file of the main program.
Here is the two-step process I used for carrying out assembly-binding redirecting in a plugin scenario when writing a plugin for SDL Trados 2017--
Step One: Use a try-catch statement in the plugin itself to discover the information about the assembly which is failing to load.
In my case, I suspected one of the handful of assemblies required to create a Google Cloud AutoML client was to blame, so I put a try-catch statement around the point where the plugin first tries to create a Google Cloud AutoML client:
try
{
client = AutoMlClient.Create();
}
catch (Exception err)
{
using (System.IO.StreamWriter file = new System.IO.StreamWriter("C:/Desktop/log.txt", true))
{
file.WriteLine(err.ToString());
}
}
When I checked the "log.txt" file created during the error, I found the following information:
System.IO.FileNotFoundException: Could not load file or assembly 'Google.Apis.Auth, Version=1.41.1.0, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab' or one of its dependencies. The system cannot find the file specified.
So! It was clear that, in the process of creating an AutoML client, the plugin was trying to find.Google.Apis.Auth version 1.41.1.0. However, in order to get my plugin to compile correctly, I had to install Google.Apis.Auth version 1.42.0.0 with NuGet. Hence the need for the assembly binding redirect.
Step Two: Add an event handler related to that particular assembly which will change it's version / public key token information before loading it.
At the very beginning of the program--where the main form window of the plugin is initialized, I added this code:
public Main_form()
{
InitializeComponent();
Version V14200 = new Version("1.42.0.0");
RedirectAssembly("Google.Apis.Auth", V14200, "4b01fa6e34db77ab");
}
public static void RedirectAssembly(string assembly_name, Version targetVersion, string publicKeyToken)
{
ResolveEventHandler handler = null;
handler = (sender, args) => {
//gets the name of the assembly being requested by the plugin
var requestedAssembly = new AssemblyName(args.Name);
//if it is not the assembly we are trying to redirect, return null
if (requestedAssembly.Name != assembly_name)
return null;
//if it IS the assembly we are trying to redirect, change it's version and public key token information
requestedAssembly.Version = targetVersion;
requestedAssembly.SetPublicKeyToken(new AssemblyName("x, PublicKeyToken=" + publicKeyToken).GetPublicKeyToken());
requestedAssembly.CultureInfo = CultureInfo.InvariantCulture;
//finally, load the assembly
return Assembly.Load(requestedAssembly);
};
AppDomain.CurrentDomain.AssemblyResolve += handler;
}
So basically, you have to get information from the plugin (using a try-catch statement) about which assembly is failing to load. Then, you have to add an event handler, which will go into effect when the assembly in question begins to load.
In my case, I knew that Google.Apis.Auth was the problem--the plugin wanted to load version 1.41.1.0, but my plugin contained version 1.42.0.0. When the plugin begins looking for Google.Apis.Auth (1.41.1.0), the event handler steps in and changes the version number, so the plugin loads version 1.42.0.0.
Having never had any formal training in computer science or programming, I don't know how robust/recommendable this solution is, but it worked for me.
shared dependency
, where can D be found? – Blat