2
votes

My class library project (which is developed 8 years back) needed Assembly A. Though Assembly A is strong named, developers then kept them in local folder and referenced from there so that assembly is always there in the application's bin folder. I guess, this was done to get rid of some deployment issues.

My class library project is consumed by one of our clients.

Newer version of Assembly A has been released and our client's application wants to use that version. They are not referencing new version from GAC; they have their own copy! Now when they use latest version, they get an error because my class library project assembly which they have referenced needs older version of the Assembly A.

  1. How to solve this particular problem?
  2. Would client face the same issue if I change my project to start referencing Assembly A from GAC (when they still use their local copy) ?
  3. Newer version of Assembly A has some breaking changes. If client and I, both, start using required versions of the assembly from GAC, will our problem be solved?
  4. If there comes newer version of the Assembly A and if that goes to GAC, will .NET load the one from GAC regardless of the version we are referencing in both the projects?
2

2 Answers

2
votes

The GAC is a deployment detail and is not involved when you build your project. Whenever the CLR needs to load an assembly, and it has a strong name, then it looks in the GAC first. The app's probing path next. When it is stored in the GAC then the CLR can match the required version. When it is not then the CLR stops searching the directories in the probing path as soon as it finds a match with the assembly name. Kaboom if the assembly if finds is not the correct version.

Since your client prefers storing the new version in the probing path, they can never get the old version loaded. They must therefore put the old version of the assembly in the GAC. It is not the only thing that can go wrong, they cannot properly call your code if you expose any of the types from the assembly in your library's public methods.

Clearly you'll give them less of a headache by updating your library to use the new version as well.

0
votes
  1. How to solve this particular problem?

Give a new strong name to the newer version of Assembly A. (Project Properties - Signing - Choose a strong name key file)

 2. Would client face the same issue if I change my project to start referencing Assembly A from GAC (when they still use their local copy) ? 

If both assemblies have their own strong name and you build your assembly with Specific version "true" it will work... That's what I've done in my test below

 3. Newer version of `Assembly A` has some breaking changes. If client and I, both, start using required versions of the assembly from GAC, will our problem be solved? 

Yes, two different strong name are required tho.

 4. If there comes newer version of the `Assembly A` and if that goes to GAC, will .NET load the one from GAC regardless of the version we are referencing in both the projects?

Yes it will load the one in the GAC if it's strong name is the same. However you can put as many versions you want in the GAC but each need it's strong name.

Here is what i've done: ClassLibrary was compile with a strong key and put into the GAC. LibraryThatUseAGacVersionOfClassLibrary referenced it and was compile with it.
enter image description here

I've then changed ClassLibrary and give it a NEW strong Name. After a solution rebuild/refresh here is what I have: enter image description here

ClassLibrary assembly

namespace ClassLibrary
{
    public class Class1
    {
        public string TwoTwo { get; set; }//Was Toto in the old version
        public Class1()
        {
            TwoTwo = "TwoTwo from new Class1";
        }
    }
}

LibraryThatUseAGacVersionOfClassLibrary assembly

namespace LibraryThatUseAGacVersionOfClassLibrary
{
    public class UseGACAssembly
    {
        ClassLibrary.Class1 aaaa = new ClassLibrary.Class1();
        public UseGACAssembly()
        {
            aaaa.Toto = "Toto is in the GAC";//Is Toto in the GAC version
        }
        public string TotoFromSubClass { get { return aaaa.Toto; }  }
    }
}

Project that use both

   public partial class Form1 : Form
    {
        public Form1()
        {
            LibraryThatUseAGacVersionOfClassLibrary.UseGACAssembly oldObject = new UseGACAssembly();
            ClassLibrary.Class1 newObject = new ClassLibrary.Class1();
            InitializeComponent();
            Console.WriteLine(oldObject.TotoFromSubClass);
            Console.WriteLine(newObject.TwoTwo);
        }
    }

Sorry for my AWESOME naming convention. ;)

And Hans is right: if you can... update both libraries to use the newer reference.