How to set binding redirects?

843
3
Jump to solution
09-16-2021 08:18 AM
mcamp1
by
New Contributor II

I am using npgsql with my add-in, but I ran into a bug that is preventing me from upgrading past version 4.0.11 (the latest npgsql version is 5.0.10). The suggested workaround is to use assembly binding redirects in the app.config, but the ArcGIS add-in does not seem to use app.config file.


Is there a way to configure the add-in to use the app.config file?
If not, is there another way to set binding redirects?

Thanks!

0 Kudos
1 Solution

Accepted Solutions
ThomasRea
New Contributor II

So I encountered the same issue, and according to this post, the redirects in the addin's app.config are not respected:

getting a run-time error when binding a transitive... - Esri Community

 

My workaround is to add the following code to my Module's constructor. It is only instantiated once, so you can safely put initialization logic here:


var binDlls = Directory.EnumerateFiles(Path.GetDirectoryName(typeof(Module1).Assembly.Location), "*.dll")
.Select(d =>
{
var n = AssemblyName.GetAssemblyName(d);
n.Version = null;
return n;
})
.ToArray();

 

AppDomain.CurrentDomain.AssemblyResolve += (object sender, ResolveEventArgs args) =>
{
var assemblyName = new AssemblyName(args.Name)
{
Version = null
};

foreach (var dll in binDlls)
if (dll.FullName.Equals(assemblyName.FullName, StringComparison.Ordinal))
return Assembly.LoadFrom(dll.CodeBase);

return null;
};

 

this isn't a perfect solution, but what it does is search the addin's execution folder for a DLL that has a matching name, public key, and culture. If one is found, it just loads it. This may be problematic since this would do this for EVERY dll that couldn't be found, possibly leading to an invalid DLL being loaded. But for my purposes, this isn't a concern. I suppose you could also parse the App.Config with XML to get the exact Dlls and version that should be redirected, but that wasn't necessary for me

View solution in original post

3 Replies
mcamp1
by
New Contributor II

I wrote out some steps to reproduce the problem. Any help would be appreciated!
1. Open Visual Studio and create a new ArcGIS Pro Module Add-in
2. Run ‘Install-Package Npgsql’ in the Package Manager Console.
3. Run ‘Update-Package’ in the Package Manager Console.
4. Initialize a new NpgsqlConnection:

var conn = new NpgsqlConnection("Server=127.0.0.1;Port=5432;Database=myDataBase;User Id=myUsername;Password=myPassword;");

 

Error:

System.IO.FileNotFoundException: 'Could not load file or assembly 'System.Threading.Channels, Version=4.0.2.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51' or one of its dependencies. The system cannot find the file specified.'

0 Kudos
Vidar
by
Occasional Contributor II

Hi,

 

I have had the same problem - when I get to the code that starts to try  to connect to my DB, I get thrown the error: Exception thrown: 'System.IO.FileNotFoundException' in Npgsql.dll.

 

When I install an old version of npgsql - then it works. Esri need to fix this to work with the latest versions of npgsql.

0 Kudos
ThomasRea
New Contributor II

So I encountered the same issue, and according to this post, the redirects in the addin's app.config are not respected:

getting a run-time error when binding a transitive... - Esri Community

 

My workaround is to add the following code to my Module's constructor. It is only instantiated once, so you can safely put initialization logic here:


var binDlls = Directory.EnumerateFiles(Path.GetDirectoryName(typeof(Module1).Assembly.Location), "*.dll")
.Select(d =>
{
var n = AssemblyName.GetAssemblyName(d);
n.Version = null;
return n;
})
.ToArray();

 

AppDomain.CurrentDomain.AssemblyResolve += (object sender, ResolveEventArgs args) =>
{
var assemblyName = new AssemblyName(args.Name)
{
Version = null
};

foreach (var dll in binDlls)
if (dll.FullName.Equals(assemblyName.FullName, StringComparison.Ordinal))
return Assembly.LoadFrom(dll.CodeBase);

return null;
};

 

this isn't a perfect solution, but what it does is search the addin's execution folder for a DLL that has a matching name, public key, and culture. If one is found, it just loads it. This may be problematic since this would do this for EVERY dll that couldn't be found, possibly leading to an invalid DLL being loaded. But for my purposes, this isn't a concern. I suppose you could also parse the App.Config with XML to get the exact Dlls and version that should be redirected, but that wasn't necessary for me