Est-il possible que deux DLL entrent en conflit, empêchant la création de la solution

9

Bien que j'aie un cas spécifique, mais je me posais des questions sur la situation générale.

Deux DLL, lorsqu'elles sont ajoutées en tant que référence à un projet Visual C #, peuvent-elles entrer en collision pour empêcher la création de la solution? Si tel est le cas, quelles sont les façons possibles d'atténuer cela.

Shamim Hafiz
la source

Réponses:

13

C'est très possible.

Si vous avez défini un espace de noms et un nom identiques sur différents assemblys (ou dans votre projet et l'assembly ajouté), vous obtiendrez un conflit avec tout code qui essaie d'utiliser l'un ou l'autre de ces types.

Si vous vous assurez d'avoir des espaces de noms uniques, tout comme vos références, vous n'auriez pas ce problème.

Une autre possibilité concerne les différentes versions d'une dépendance - si votre projet utilise (par exemple) une bibliothèque de journalisation à la version 1.2, mais l'assembly ajouté a une dépendance sur le même assembly mais une version différente (disons 1.3) et soit votre projet ou l'assembly ajouté a été configuré / construit pour utiliser une version spécifique, vous obtiendrez un conflit et la génération échouera.

Ces deux problèmes peuvent être résolus à l'aide d'alias d'assembly, comme décrit ici .

Oded
la source
Je ne suis pas tout à fait sûr que ce soit vrai. Si vous regardez le CIL, le CLR se réfère explicitement aux symboles dans certains assemblages avec la notation [assembly] avant chaque symbole. Il est possible que le compilateur C # applique ce problème, mais je ne pense pas que ce soit une contrainte de plate-forme.
Yam Marcovic
@Yam Marcovic comment le complice pourrait-il déterminer quel espace de noms vous essayez d'utiliser dans une classe particulière? Les conflits de nom de classe pleinement qualifiés vont certainement empêcher une construction.
Jeremy
Le compilateur C # vous offre une option pour les alias d'assembly, lorsqu'il s'agit d'assemblys du même nom (et éventuellement ayant les mêmes symboles définis). Voir stackoverflow.com/questions/517058/…
Yam Marcovic
@Yam - Certes, cependant, vous devez connaître ce drapeau et l'utiliser. Le simple fait d'ajouter l'assemblage romprait la construction.
Odé
1
Évidemment. C'est pourquoi il vient ici pour de l'aide, non? Il veut connaître ce drapeau et l'utiliser, car il lui donnera une solution plus propre, sans affecter son projet ou les utilitaires tiers.
Yam Marcovic
4

Voyant que personne d'autre ne l'a mentionné, vous avez demandé:

quelles sont les façons possibles d'atténuer ce

Il existe une solution propre juste pour ce cas, sans contraintes et sans solutions de contournement ennuyeuses. Vous pouvez définir des alises d'assemblage pour que le compilateur sache celles auxquelles se référer au bon endroit.

Jetez un œil à http://blogs.msdn.com/b/ansonh/archive/2006/09/27/774692.aspx

Yam Marcovic
la source
3

Oui, c'est très possible.
Supposons que vous ayez ajouté une référence à une DLL qui utilise l'ancienne version de Lucene.Net et que vous souhaitez inclure la dernière version.
Vous pouvez résoudre ce problème en utilisant des alias externes: http://msdn.microsoft.com/en-us/library/ms173212.aspx

šljaker
la source
+1, cela semble être la bonne réponse, mais pas l'alias "extern".
Jalayn
1

Vous pouvez placer autant de versions différentes d'un assembly que vous le souhaitez dans le Global Assembly Cache à condition qu'elles portent un nom fort. Cela peut vous aider si vous souhaitez que différentes applications utilisent différentes versions d'un assemblage, en termes de machine. Cependant, l'utilisation de différentes versions d'un assemblage dans UNE application vous posera toujours des problèmes.

Quelle est la raison pour laquelle vous avez besoin des deux versions en même temps?

Jalayn
la source
1
Eh bien, je n'ajoute pas explicitement de versions différentes. Fondamentalement, j'ai une application WPF. Maintenant, afin d'ajouter une fonctionnalité tierce, j'ai ajouté quelques DLL et ce sont ces DLL qui sont peut-être en conflit.
Shamim Hafiz
1
OK, alors vous pouvez peut-être ajouter ces DLL liées à des tiers au GAC? Cela fait longtemps que je n'ai pas lu ces choses, mais je pense que cela pourrait résoudre votre problème.
Jalayn
Qu'entend-on par GAC ici?
Shamim Hafiz
0

Pour sûr. Vous pouvez obtenir l'erreur du compilateur «Référence ambiguë» lorsque deux objets ne peuvent pas être distingués. En règle générale, vous pouvez spécifier le chemin d'accès complet dans le code et cela ne causera pas de problème, mais si les DLL étaient entièrement identiques, vous ne pourrez en aucune façon distinguer entre deux objets. Sya nous avons deux DLL:

System.IO qui contient la classe File

et

MyProject.IO qui contient une classe File

Si vous deviez avoir quelque chose comme ça ...

using System.IO;
using MyProject.IO;

...
private void foo()
{
    File f = new File();
}

... vous auriez une référence ambiguë, car il n'y a aucun moyen de savoir de quel fichier vous parlez. Cela le corrigerait:

using System.IO;
using MyProject.IO;

...
private void foo()
{
    MyProject.IO.File f = new MyProject.IO.File();
}

La seule façon qu'il serait difficile de résoudre serait si le chemin d'accès de "File" était identique dans les deux assemblages, mais cela nécessiterait la situation peu probable où deux DLL ont une structure d'espace de noms identique. Par exemple, ma situation ci-dessus ne se produirait jamais, car personne ne va y nommer le projet "System" (à l'exception des développeurs réels du framework .Net).

Morgan Herlocker
la source
En fait, cela arrive souvent si vous créez des solutions basées sur des bibliothèques tierces populaires. Par exemple, une bibliothèque twitter peut dépendre d'une version plus ancienne de votre lib json
Hoàng Long