Чи можливі конфлікти двох DLL-файлів, не дозволяючи створювати рішення


9

Хоча я маю конкретний випадок, але мені було цікаво про загальну ситуацію.

Чи можуть дві DLL-файли, додані як Посилання на проект Visual C #, стикаються між собою, щоб запобігти створенню рішення? Якщо це так, то які можливі способи пом'якшити це.

Відповіді:


13

Це дуже можливо.

Якщо ви визначили однакове простір імен та ім'я типу на різних збірках (або у вашому проекті та доданій збірці), ви отримаєте конфлікт із будь-яким кодом, який намагається використовувати той чи інший із цих типів.

Якщо ви переконаєтесь, що у вас є унікальні простори імен, як і у ваших посиланнях, у вас не виникне цієї проблеми.

Інша можливість пов'язана з різними версіями залежності - якщо ваш проект використовує (наприклад) бібліотеку журналу у версії 1.2, але додана збірка має залежність від тієї ж збірки, але іншої версії (скажімо 1.3) та будь-якого вашого проекту або додана збірка була налаштована / побудована для використання конкретної версії, ви отримаєте конфлікт, і збірка не вдасться.

Обидва ці проблеми можна вирішити за допомогою псевдонімів збірки, як описано тут .


Я не зовсім впевнений, що це правда. Якщо ви подивитеся на CIL, CLR посилається на символи, які явно знаходяться в межах певних збірок, із позначенням [Assembly] перед кожним символом. Можливо, компілятор C # виконує цю проблему, але я не думаю, що це обмеження для платформи.
Ям Маркович

@Yam Marcovic, як би хтось зрозумів, який простір імен ви намагаєтеся використовувати в конкретному класі? Повністю кваліфіковані конфлікти імен класу, безумовно, запобігають збірці.
Джеремі

Компілятор C # надає вам можливість складання псевдонімів при роботі з збірками з однойменною назвою (і, можливо, мають однакові символи, визначені в них). Дивіться stackoverflow.com/questions/517058/…
Ям Маркович

@Yam - Однак правда, вам потрібно знати про цей прапор і використовувати його. Просто додавання збірки порушить збірку.
Одід

1
Очевидно. Ось чому він приходить сюди на допомогу, правда, правда? Він хоче знати про цей прапор і використовувати його, оскільки він дасть йому більш чітке рішення, не впливаючи на його проект чи сторонні комунальні послуги.
Ям Маркович

4

Бачачи, як ніхто інший не згадував про це, ви запитали:

які можливі способи пом'якшити це

Існує чисте рішення саме для цього випадку, без обмежень і без дратівливих обхідних шляхів. Ви можете визначити аліменти для складання, щоб компілятор знав, на які слід звернутися в потрібному місці.

Погляньте на http://blogs.msdn.com/b/ansonh/archive/2006/09/27/774692.aspx


3

Так, це дуже можливо.
Скажімо, ви додали посилання на деяку DLL, яка використовує стару версію Lucene.Net, і ви хочете включити останню версію.
Ви можете вирішити цю проблему, використовуючи зовнішні псевдоніми: http://msdn.microsoft.com/en-us/library/ms173212.aspx


+1, здається, це правильна відповідь, а як щодо "зовнішнього" псевдоніма.
Джалайн

1

Ви можете розмістити стільки різних версій збірки, скільки потрібно в кеш глобальної асамблеї, за умови, що вони мають чітку назву. Це може допомогти вам, якщо ви хочете, щоб різні програми використовували різні версії збірки, машинно. Однак використання різних версій збірки в програмі ONE все одно спричинить вам проблеми.

Яка причина, що вам потрібні обидві версії одночасно?


1
Ну я явно не додаю різні версії. В основному у мене є додаток WPF. Тепер, щоб додати функцію сторонніх розробників, я додав кілька DLL-файлів, і саме ці DLL-файли, можливо, конфліктують.
Шамім Хафіз

1
Гаразд, тоді ви можете, можливо, додати ці DLL-файли, пов’язані із сторонніми розробниками, до GAC? З давніх пір я читав про ці речі, але підозрюю, що це може вирішити вашу проблему.
Джалайн

Що мається на увазі під GAC?
Шамім Хафіз

1
Кеш глобальної асамблеї, див. Msdn.microsoft.com/en-us/library/yf1d93sz%28v=vs.71%29.aspx
Jalayn

0

Напевно. Ви можете отримати помилку компілятора "Неоднозначна довідка", коли два об'єкти неможливо розрізнити. Як правило, ви можете вказати повний шлях у коді, і це не спричинить проблеми, але якби dlls були повністю ідентичними, ви не змогли б розрізнити два об'єкти жодним чином. У нас є два будинки:

System.IO, який містить клас File

і

MyProject.IO, який містить клас File

Якби у вас було щось подібне ...

using System.IO;
using MyProject.IO;

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

... ви б мали неоднозначну посилання, оскільки немає способу сказати, про який файл ви говорите. Це виправить це:

using System.IO;
using MyProject.IO;

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

Єдиний спосіб було б важко виправити, якби шлях "File" був однаковим в обох складах, але це вимагало б малоймовірної ситуації, коли два dll мали однакову структуру простору імен. Наприклад, моя ситуація вище ніколи не відбудеться, оскільки ніхто не збирається назвати там проект "Система" (за винятком фактичних розробників рамки .Net).


Насправді це буває багато, якщо будувати рішення на основі популярних сторонніх бібліотек. Наприклад, бібліотеки щебетання можуть залежати від старішої версії вашого json lib
Hoàng Long
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.