Посилання на 2 різні версії log4net в одному і тому ж рішенні


80

Я використовую NHibernate 2.1.2.400, який посилається на log4net 1.2.10.0. У тому ж проекті я також використовую просто обліковий SDK, на жаль, він все ще використовує log4net 1.2.9.0.

Тож я можу змусити NHibernate працювати, якщо я посилаюся на log4net 1.2.10.0, але simpleSDK не працює. І навпаки...

Я здогадуюсь, що більшість проблем пов'язані з тим, що log4net змінив ключ складання. Я спробував скористатися переспрямуванням прив'язки без успіху: 2 бібліотеки DLL не мають однакового ключа.

Я розглядаю можливість повторної компіляції NHibernate для використання log4net 1.2.9.0, але, здається, це неправильно робити, і я відчуваю, що Simply Accounting найближчим часом не буде оновлювати свій SDK для використання log4net 1.2.10.0.

Який найкращий спосіб вирішити це? Чи можна взагалі вирішити проблему?


2
У мене є дуже подібне запитання на stackoverflow.com/questions/1744543/… Я вдався до перекомпіляції. Думаю, це поява dll-hell v2.0.
Sandor Drieënhuizen

1
під час перевірки вашого запитання я виявив stackoverflow.com/questions/2460542/2461746#2461746, який вирішив мою проблему.
Джоель Говро

Чудово! Я дивувався про те, щоб зробити CLR виглядати в різних місцях, і hrefатрибут, здається, робить трюк. Дякуємо, що вказали на це!
Sandor Drieënhuizen

Відповіді:


149

Я знайшов рішення, використовуючи цю відповідь на подібне запитання

Ви створюєте 2 папки у своєму проекті, по одній для кожної версії log4net. Помістіть кожну log4net.dll у відповідну папку, додавши файл до рішення (не з посиланням на додавання). Ви можете встановити копію для властивості вихідного каталогу для копіювання завжди, щоб вона автоматично копіювалась у вихідну папку під час побудови.

Потім ви модифікуєте файл app.config, додавши щось подібне:

<configuration>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="log4net" publicKeyToken="681549d62126b7b8" />
        <codeBase version="1.2.9.0" href="log4netv1.2.9.0\log4net.dll" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="log4net" publicKeyToken="1b44e1d426115821" />
        <codeBase version="1.2.10.0" href="log4netv1.2.10.0\log4net.dll" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="log4net" publicKeyToken="669e0ddf0bb1aa2a" />
        <codeBase version="1.2.11.0" href="log4net.dll" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
</configuration>

Ви можете отримати маркер відкритого ключа збірки за допомогою sn -T [AssemblyName]


2
Здається, це працює і для мене. Я вилучив log4net зі списку посилань для проекту, де виникав конфлікт. Крім того, оскільки log4net.dll відсутній у моїх папках для сміття, мої шляхи href виглядали більше як ".. \ .. \ .. \ .. \ Lib \ NHibernate-2.0.1.GA \ log4net.dll" - просто відносний шлях до місця знаходження log4net на машині кожного розробника з нашою системою складання.
jyoungdev

12
Я не впевнений, що розумію це: як ви не отримуєте помилок компіляції, якщо на log4net немає посилань?
путівник

2
Це приголомшливо, це виправило б інші випадки, коли просте перенаправлення на прив'язку порушило б ситуацію через зміни API також!
Rhys Bevilaqua

5
@guidupy ви можете посилатися на log4net, який використовує ваш код, але вимкнути copyLocal у властивостях.
Джефф Мартін,

4
для майбутніх читачів (підказка, яку я знайшов з іншої відповіді, але розумно розміщувати тут) ... для веб-додатків (asp.net) посилання має твік: <codeBase version = "1.0.0.0" href = "bin \ folder \ namedll.dll "/>
granadaCoder

7

Ви можете додати виключення до реєстру. Просто додайте ці ключі:

HKEY_LOCAL_MACHINE\Software\Microsoft\StrongName\Verification\log4net,681549d62126b7b8
HKEY_LOCAL_MACHINE\Software\Microsoft\StrongName\Verification\log4net,1b44e1d426115821
HKEY_LOCAL_MACHINE\Software\Microsoft\StrongName\Verification\log4net,669e0ddf0bb1aa2a

Це змусить час виконання .net пропустити перевірку для перелічених збірок. Теоретично це проблема безпеки, але оскільки приватний ключ все одно відкритий, це навряд чи може мати якийсь вплив.


Як ви вже сказали, це проблема безпеки. Крім того, це означатиме, що ви повинні внести ці зміни на кожній робочій станції, на якій запущено програмне забезпечення. У складній корпоративній мережі такі речі створюють величезний хаос. Я волів би уникати цього якомога більше. Інші рішення є автономними та портативними.
Джоель Говро

Як я вже говорив, оскільки приватні ключі так чи інакше є загальнодоступними, реальних проблем безпеки взагалі немає. Особливо в корпоративній мережі було б простіше налаштувати один об’єкт групової політики, ніж налаштувати це для кожного використовуваного додатка LOB. Ви можете налаштувати його один раз на рівні домену і ніколи більше не думати про це.
Joep Beusenberg

3

Якщо перенаправлення на прив’язку не працює, а SDK для простого обліку є закритим, можливим рішенням є перекомпіляція NHibernate для використання log4net 1.2.9.0.


3
Це могло б спрацювати, але для того, щоб створити спеціальну версію nhibernate, важче було б підтримувати це рішення ... дякую.
Joel Gauvreau
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.