10

In my solution, I have several projects which use Log4Net (1.2 and 2.5).

Then I have a project where I do all the unit testing (of the other projects). So I'm in a situation where depending on what I test/mock I would need Log4Net 1.2 or 2.5.

I read you could support different version of a single assembly in an application (using codebase etc.) but is it even possible to support different version of a single assembly into a project? If so, how?

EDIt:

Here's a tiny (2 classes, 2 methods, 2 constructors) project showing my issue:

https://srv-file1.gofile.io/download/EQFdOs/212.76.254.142/Log4NetMulti.zip

(I hope the link work)

Serge Intern
  • 2,669
  • 3
  • 22
  • 39
  • What did you read when you *read you could support different version of a single assembly in an application (using codebase etc.)* ? – Nikhil Vartak May 19 '16 at 06:44
  • I doubt so as they'd define the same namespaces twice. – AUsr19532 May 19 '16 at 06:51
  • @AUsr19532 - and what problem do you see with that? It's perfectly normal for multiple assemblies to have types that exist in the same namespace. – Damien_The_Unbeliever May 19 '16 at 06:58
  • How would the compiler know wheter to use Samplenamespace.lib.somthing from one version or the other? – AUsr19532 May 19 '16 at 07:01
  • 1
    @AUsr19532 - you can use aliases, as Pikoh's answer indicates, if they have exactly the same *types*, but my point is, it's extremely common for assemblies to have (different) types in the same namespaces. See e.g. [System.Uri](https://msdn.microsoft.com/en-us/library/system.uri(v=vs.110).aspx) (from the System assembly) and [System.Attribute](https://msdn.microsoft.com/en-us/library/system.attribute(v=vs.110).aspx) (from the mscorlib assembly) – Damien_The_Unbeliever May 19 '16 at 07:17
  • I simply wasn't aware of the alias thing but yes this solves the problem. And since it's the same assembly just different versions collisions would be rather certain. For example using mscorlib version 1.0.0 and mscorlib 1.0.1 you'd define System.Attribute etc. twice. That's what I wanted to point out. I never questioned **different** assamblies using the same namespace. – AUsr19532 May 19 '16 at 07:34

2 Answers2

17

Thanks to Pikoh's advices I managed to make it work. But since it requires more than just using alias and rename dll, I'll write down the whole process.

  1. Remove the existing reference (ex: log4net.dll) from the project
  2. Add a folder to the project to store the several dll (ex: /Libs)
  3. Add the several dll in it and give them unique file names (like log4net.1.2.10.0.dll, log4net.1.2.15.0.dll)
  4. Go to property on those files and chose "Copy: Always" or "Copy: Copy if newer"
  5. Add references to those files
  6. Give those references unique aliases (ex: log4net_1_2_10_0, log4net_1_2_15_0)
  7. In you code, make use of the aliases, using "extern alias" keywords.

    extern alias log4net_1_2_10_0;
    
    using log4net_1_2_10_0.log4net;
    using System.Web;
    ...
    
  8. Add codebases into your config file. Those should refer to the dll you placed into your folder, with the proper version and token.

    <runtime> 
      <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
        <dependentAssembly>
          <assemblyIdentity name="log4net" publicKeyToken="669e0ddf0bb1aa2a" />
          <codeBase version="1.2.15.0" href="Libs/log4net.1.2.15.0.dll"/>
        </dependentAssembly>
        <dependentAssembly>
          <assemblyIdentity name="log4net" publicKeyToken="1b44e1d426115821" />
          <codeBase version="1.2.10.0" href="Libs/log4net.1.2.10.0.dll"/>
        </dependentAssembly>
      </assemblyBinding>
    </runtime>  
    
Athari
  • 33,702
  • 16
  • 105
  • 146
Serge Intern
  • 2,669
  • 3
  • 22
  • 39
5

You can reference diferent versions of the same dll using Alias, as is explained here MSDN:

Add the reference to both the dlls in your client application solution. Then in the Solution Explorer under the reference node select the first (old version) class library. In the property window change Aliases field from global to oldVer. Make similar change after selecting the newer class library as well. You are then good to go…

Pikoh
  • 7,582
  • 28
  • 53
  • VS won't even let me add the reference "A reference to ... could not be added. A reference to the component ... already exists in the project. – Serge Intern May 19 '16 at 11:08
  • Well..try to rename the dll's name, for example `log4netold.dll`and `log4netnew.dll` – Pikoh May 19 '16 at 12:11
  • It's better, I could add the two references. So I used an alias for one but the one which is on the global alias cannot be found when the unit test run (it compiles but then, the test involving "global log4net" crashe). – Serge Intern May 19 '16 at 13:12
  • I think you must add an alias for both. See the link in my answer – Pikoh May 19 '16 at 13:26
  • It's not working. Could it be related to XUnit? Resharper? Because I use those to define/run my tests. – Serge Intern May 19 '16 at 13:52
  • Maybe..i don't have experience with xunit. Does it not compile? Or the error is running tests? – Pikoh May 19 '16 at 13:54
  • It compiles the error only occur during the tests run. – Serge Intern May 19 '16 at 13:55
  • Then it's possible xunit does not support alias. Maybe you should look it up in their documentation... – Pikoh May 19 '16 at 13:57
  • i added a link to a very simple visual studio project to show my whole situation. – Serge Intern May 19 '16 at 14:14