10

We have a plug in folder from which we load assemblies. Mostly this is fine. However, we have 1 3rd party plugin that uses System.Core Version 2.0.5.0.

We use .Net 4 so we have System.Core 4.0.0.0 loaded on on the PCs.

When loading the plug-in we get an error as System.Core Version 2.0.5.0. cannot be resolved.

I thought this would help:

<dependentAssembly>
    <assemblyIdentity name="System.Core"
                      publicKeyToken="7cec85d7bea7798e"
                      culture="neutral" />
    <bindingRedirect oldVersion="2.0.5.0"
                     newVersion="4.0.0.0"/>
  </dependentAssembly>

But it didn't.

How can I force a referencing .dll to use the version of System.Core I have?

And is that the right way to do this?

==================================

This is the code we use to register the plug-ins:

internal class TestCode
{
    FileInfo[] assemblies;

    public void GoFish()
    {
        AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;

        foreach (string directory in Directory.GetDirectories(@"E:\Plugins"))
        {
            assemblies = new DirectoryInfo(directory).GetFiles("*.dll");
            foreach (string assemblyFile in Directory.GetFiles(directory, "*.dll"))
            {
                try
                {
                    FileInfo fi = new FileInfo(assemblyFile);
                    var assembly = Assembly.LoadFile(fi.FullName);
                    IntegrationAssemblyAttribute integrationAssemblyAttribute = (IntegrationAssemblyAttribute)assembly.GetCustomAttribute(typeof(IntegrationAssemblyAttribute));
                }
                catch (Exception ex)
                {
                    //Exception handling
                    Console.WriteLine("An error has occured while loading plugin from loacation:{0}\n{1}", assemblyFile, ex);
                }
            }
        }
    }

    Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
    {
        var reference = assemblies.FirstOrDefault(file => file.Name == args.Name.Split(',').ToList()[0] + ".dll");
        if (null == reference)
        {
            return null;
        }
        return Assembly.LoadFile(reference.FullName);

    }
}

public sealed class IntegrationAssemblyAttribute : Attribute
{
    public Guid Guid { get; set; }
    public IntegrationAssemblyAttribute(string assemblyGuid)
    {
        Guid = Guid.Parse(assemblyGuid);
    }
}
Richard210363
  • 8,342
  • 6
  • 37
  • 63

2 Answers2

1

As far as I know, assembly redirection is only working from the end application's point of view. Hence, you have to add the redirection to the application's app.config/web.config. This is quite annoying, because it still creates a modern version of the earlier days' 'DLL hell'.

DotBert
  • 1,262
  • 2
  • 16
  • 29
1

The above statement is totally correct--to do a traditional assembly binding redirect, you have to add the redirection to the application's app.config/web.config file (adding the redirection to the actual PC's machine.config file would also work).

I ran into the same problem while developing a plugin for SDL Trados Studio 2017. I didn't want to have to make the user edit their machine.config or SdlTradosStudio.exe.config file, so what to do?

In the end, I added an event handler which changes the version information of the requested assembly as it's being loaded. The complete answer is here:

https://stackoverflow.com/a/59657378/11245901

todbott
  • 481
  • 5
  • 9