'c# use multiple versions of same library (nest)
I have situation something like this:
1 Solution that contains 3 projects:
- 1 console application which references these 2 other elastic related projects
- 1 elastic search v1 project, which contains Nest and ElasticSearch.Net v1 libraries to do searches to our old elastic 1.4 cluster
- 1 elastic search v5 project, which contains Nest and ElasticSearch.Net v5 libraries to do searches to our new elastic 5.4 cluster
Nest library is 1 Nuget package and you are supposed to use right version for your elastic cluster. It uses internally ElasticSearch.Net library. Also Newtonsoft.Json is conflicting between these library versions.
Most answers to similar questions are related assembly redirect but in this case it's not possible because versions are not compatible.
I tried to use Fody/Costura (https://github.com/Fody/Costura) to embed elastic related dlls into my elastic v1 and v5 libraries to avoid conflicts. Embedding itself works fine meaning that those dlls are not copied to bin-folder.
I didn't try ILMerge yet but my understanding is that it's similar to Costura.
public void Test1()
{
var es1Helper = new MyElasticSearchV1RelatedProject.SearchHelper();
es1Helper.TestSearch();
var es5Helper = new MyElasticSearchV5RelatedProject.SearchHelper();
es5Helper.TestSearch();
}
public void Test2()
{
var es5Helper = new MyElasticSearchV5RelatedProject.SearchHelper();
es5Helper.TestSearch();
var es1Helper = new MyElasticSearchV1RelatedProject.SearchHelper();
es1Helper.TestSearch();
}
But Test1 fails
System.TypeLoadException: 'Could not load type 'Nest.Indices' from assembly 'Nest, Version=1.0.0.0, Culture=neutral, PublicKeyToken=96c599bbe3e70f5d'.'
And Test2 fails
System.TypeLoadException: 'Could not load type 'Elasticsearch.Net.ConnectionPool.IConnectionPool' from assembly 'Elasticsearch.Net, Version=5.0.0.0, Culture=neutral, PublicKeyToken=96c599bbe3e70f5d'.'
It looks like that depending on the order, other dll versions are loaded and the other library project tries to use them as well.
Is there any way to use both versions on the same project?
Solution 1:[1]
You might have better luck using a little known C# feature called extern alias
https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/extern-alias
This would allow you to reference two DLL's with the same fully qualified type names by creating additional root level namespaces so you can reference the types e.g: nestv1::ConnectionSettings and nestv2::ConnectionSettings. Much like you can reference normal types through the global:: namespace alias.
NuGet does not expose this so you will need to create the reference manually.
Solution 2:[2]
I tried the solution from https://www.elastic.co/blog/nest-and-elasticsearch-net-upgrading-your-codebase. It worked in a proof of concept project: a console app that references 2 libraries which in turn reference Nest 5.6.4 and Nest.v6 (all .NET Framework 4.6.1).
So I'm going to try this approach in real project where we have similar situation as in the question: 2 elasticsearch clusters both 5.6 at the time of writing. They are going to upgrade to 6.8 one by one (not simultaneously). During the upgrade period, which can take several weeks to migrate all indices, we will have to read from and write to both versions of elasticsearch. The solution from the article looks easy to implement and it doesn't require some manipulations with extern alias or binding redirects or whatever else "magic". You just reference two different major versions of Nest (one is main package from nuget.org, another is a package from Elastic CI packages feed) and they work together in one application side by side.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Martijn Laarman |
| Solution 2 | Andrey Zakharov |
