É possível que duas DLLs entrem em conflito, impedindo a criação da solução

9

Embora eu tenha um caso específico, mas estava pensando sobre a situação geral.

Duas DLLs, quando adicionadas como referência a um projeto do Visual C #, podem colidir entre si para impedir a criação da solução? Se for esse o caso, quais são as formas possíveis de atenuar isso.

Shamim Hafiz
fonte

Respostas:

13

Isto é muito possível.

Se você definiu um namespace idêntico e digite o nome em diferentes assemblies (ou no seu projeto e no assembly adicionado), você entrará em conflito com qualquer código que tente usar um ou outro desses tipos.

Se você garantir que possui namespaces exclusivos, assim como suas referências, não terá esse problema.

Outra possibilidade tem a ver com versões diferentes de uma dependência - se o seu projeto usar (por exemplo) uma biblioteca de log na versão 1.2, mas o assembly adicionado tiver uma dependência do mesmo assembly, mas uma versão diferente (por exemplo, 1.3) e seu projeto ou o conjunto adicionado foi configurado / construído para usar uma versão específica, você terá um conflito e a construção falhará.

Esses dois problemas podem ser resolvidos usando aliases de montagem, conforme descrito aqui .

Oded
fonte
Não tenho certeza absoluta de que isso seja verdade. Se você olhar para o CIL, o CLR se refere a símbolos explicitamente dentro de certas montagens com a notação [assembly] antes de cada símbolo. É possível que o compilador C # imponha esse problema, mas não acho que seja uma restrição de plataforma.
Yam Marcovic
@Yam Marcovic, como o complier descobriria o namespace que você está tentando usar em uma classe específica? Os conflitos de nome de classe totalmente qualificados definitivamente impedirão uma compilação.
Jeremy
O compilador C # fornece uma opção para aliases de montagem, ao lidar com montagens com o mesmo nome (e possivelmente com os mesmos símbolos definidos). Veja stackoverflow.com/questions/517058/…
Yam Marcovic 5/11
@Yam - É verdade, no entanto, você precisa saber sobre essa bandeira e usá-la. Simplesmente adicionar a montagem quebraria a compilação.
Oded
11
Obviamente. É por isso que ele vem aqui para ajudar, certo? Ele quer saber sobre esse sinalizador e usá-lo, porque ele fornecerá uma solução mais limpa, sem afetar seu projeto ou utilitários de terceiros.
Yam Marcovic
4

Como ninguém mais mencionou isso, você perguntou:

quais são as possíveis maneiras de mitigar isso

Existe uma solução limpa apenas para este caso, sem restrições e sem soluções irritantes. Você pode definir alises de montagem para que o compilador saiba a quem se referir no lugar certo.

Dê uma olhada em http://blogs.msdn.com/b/ansonh/archive/2006/09/27/774692.aspx

Yam Marcovic
fonte
3

Sim, isso é muito possível.
Digamos que você adicionou uma referência a alguma DLL que usa a versão antiga do Lucene.Net e deseja incluir a versão mais recente.
Você pode resolver esse problema usando aliases externos: http://msdn.microsoft.com/en-us/library/ms173212.aspx

šljaker
fonte
+1, esta parece ser a resposta certa, não é o alias "externo"?
Jalayn
1

Você pode colocar quantas versões diferentes de uma montagem quiser no Cache de Montagem Global, desde que elas tenham nome forte. Isso pode ajudá-lo se você quiser que aplicativos diferentes usem versões diferentes de uma montagem, em termos de máquina. No entanto, o uso de versões diferentes de uma montagem em UM aplicativo ainda causará problemas.

Por que você precisa das duas versões ao mesmo tempo?

Jalayn
fonte
11
Bem, eu não estou adicionando explicitamente versões diferentes. Basicamente, eu tenho um aplicativo WPF. Agora, para adicionar um recurso de terceiros, adicionei algumas DLLs e são essas DLLs que podem estar em conflito.
Shamim Hafiz
11
OK, talvez você possa adicionar essas DLLs relacionadas a terceiros ao GAC? Já faz muito tempo que eu li sobre essas coisas, mas suspeito que isso possa resolver seu problema.
Jalayn
O que significa o GAC aqui?
Shamim Hafiz
11
Cache de montagem global, consulte msdn.microsoft.com/en-us/library/yf1d93sz%28v=vs.71%29.aspx
Jalayn 5/11
0

Com certeza. Você pode obter o erro do compilador "Referência ambígua" quando dois objetos não podem ser distinguidos. Normalmente, você pode especificar o caminho completo no código e isso não causará um problema, mas se as dlls forem totalmente idênticas, não será possível distinguir de maneira alguma dois objetos. Sya, temos duas DLLs:

System.IO que contém a classe File

e

MyProject.IO que contém uma classe File

Se você tivesse algo assim ...

using System.IO;
using MyProject.IO;

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

... você teria uma referência ambígua, pois não há como saber de qual arquivo você está falando. Isso o corrigia:

using System.IO;
using MyProject.IO;

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

A única maneira de corrigir isso seria se o caminho do "Arquivo" fosse idêntico nos dois assemblies, mas isso exigiria a situação improvável em que duas DLLs tinham uma estrutura de namespace idêntica. Por exemplo, minha situação acima nunca aconteceria, pois ninguém nomeará o projeto "Sistema" (com exceção dos desenvolvedores reais da estrutura .Net).

Morgan Herlocker
fonte
Na verdade, isso acontece muito, se você criar soluções baseadas em bibliotecas populares de terceiros. Por exemplo, as bibliotecas de um twitter podem depender de uma versão mais antiga do seu json lib
Hoàng Long