как мне обойти log4net, продолжая изменять publickeytoken

99

У нас есть проект asp.net 4.0, который использует пару фреймворков, зависящих от log4net версии 1.2.10.0. Сегодня я попытался включить новую структуру, которая зависит от log4net версии 1.2.11.0, с тех пор я застрял:

log4net 1.2.10.0 имеет publickeytoken = 1b44e1d426115821

log4net 1.2.11.0 имеет publickeytoken = 669e0ddf0bb1aa2a

Поскольку они разные, я не могу использовать ни перенаправления сборки (чтобы все фреймворки использовали одну и ту же версию log4net), ни кодовую базу (чтобы только новая структура использовала версию 1.2.11.0) через элемент времени выполнения в web.config.

Какие у меня здесь варианты?

(и почему log4net продолжает менять publickeytokens между версиями, насколько я понимаю, причиной переключения между версией 1.2.9.0 и 1.2.10.0 был потерянный ключ, они снова потеряли ключ? Я добровольно отправлю свой Dropbox чтобы сохранить его, если он им понадобится ...)

Изменить: Хорошо, поэтому у ребят из log4net, по-видимому, была идея, что выпуск с двумя ключами был хорошей идеей, но это означает, что каждая используемая вами структура должна согласовывать, какой из двух вариантов они предпочитают, или эти структуры не могут работать. рядом в том же домене приложения. Неужели только я считаю, что это ужасная идея? если бы все так поступили, все бы сломалось, верно?

Edit2: Как я уже сказал, я не использую log4net в своем бизнес-коде, но я использую несколько фреймворков, которые зависят от 1.2.10.0, и проблема возникла, когда я попытался использовать новую структуру, которая зависела от 1.2.11.0 (новый ключ ), поэтому ответ Стефанса неприменим, потому что новая структура будет ожидать новый ключ, а не старый

Андреас Кнудсен
источник
1
IMHO, первая ошибка apache здесь - предоставить двоичные файлы, подписанные новым ключом: новый ключ предназначен для исправленной / расширенной версии с открытым исходным кодом и не должен использоваться как есть. Вторая ошибка заключается в том, что фреймворк, о котором вы говорите, был выпущен только с новой подписью log4net: должна существовать версия со старой подписью.
JoeBilly
6
На самом деле, вы смотрите на третий вариант: тот, который гении SAP перекомпилировали со своим собственным сильным именем в составе пакета Crystal Reports для Visual Studio, и, что еще хуже, они засунули его в GAC, что сделает ваши зависимости между машинами - это кошмар.
Джереми Головач

Ответы:

65

Вот так у меня все заработало с версией 1.2.11.0.

  1. Прокляните apache за смену ключа в первую очередь :)
  2. Скачайте версию 1.2.11.0, подписанную старым ключом.
  3. Отсортируйте собственный код, удалив любые прямые ссылки на log4net (новый ключ) и заменив их ссылкой на сборку, подписанную старым ключом.
  4. Отсортируйте любые зависимые сборки, которые у вас могут быть, включив этот сегмент в свой файл web / app.config.
   <runtime>
        <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
            <dependentAssembly>
                <assemblyIdentity name="log4net" publicKeyToken="1b44e1d426115821" culture="neutral" />
                <bindingRedirect oldVersion="0.0.0.0-1.2.10.0"
                                 newVersion="1.2.11.0"/>
            </dependentAssembly>
        </assemblyBinding>
    </runtime>
Дэвид Кристиансен
источник
9
Необходимо загрузить версию, подписанную старым открытым ключом, поскольку, к сожалению, невозможно выполнить перенаправление привязки к сборке с другим открытым ключом.
Дэвид Кристиансен
2
Кажется, это не удается из-за критического изменения в 1.2.11.0: netpl.blogspot.com/2012/03/…
Sydneyos 05
Кто-нибудь нашел решение проблем, описанных в ссылке, упомянутой @sydneyos, которая вызывает следующее исключение:Method not found: 'Void log4net.Config.BasicConfigurator.Configure()'
Neo
К сожалению, нет другого решения, кроме перехода на 1.2.10. (или перекомпиляция каждой используемой зависимой сборки).
bk0 05
1
Поместите сборку 1.2.10 в другой каталог и используйте эту конфигурацию: '<dependentAssembly> <assemblyIdentity name = "log4net" publicKeyToken = "1b44e1d426115821" culture = "нейтральный" /> <bindingRedirect oldVersion = "0.0.0.0-1.2.9.0 "newVersion =" 1.2.10.0 "/> <codeBase version =" 1.2.10.0 "href =" Resources \ log4net-oldkey \ log4net.dll "/> </dependentAssembly> '
Agile Jedi
27

Я использую последнюю версию log4net, которую я скачал через nuget. Однако для одной из используемых мной библиотек требуется старая версия. Мои проблемы привели меня к этому вопросу.

Проблема с другими ответами заключается в том, что они используют одну и ту же версию dll для всех привязок. Я хочу использовать функции новой версии для всего остального, кроме устаревшей зависимости.

Для этого вам необходимо сделать следующее:

  1. Для начала загрузите старую версию (версия 1.2.11.0).
  2. Переименуйте загруженный двоичный файл в log4net.1.2.10.dll. Включите его в свой проект запуска с Сложение действия набора в Noneи «Копировать если новее» введите описание изображения здесь
  3. Сообщите .NET, где можно найти старую версию:

App.config

<runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
        <dependentAssembly>
            <assemblyIdentity name="log4net" publicKeyToken="1b44e1d426115821" />
            <codeBase version="1.2.10.0" href="log4net.1.2.10.dll" />
        </dependentAssembly>
    </assemblyBinding>
</runtime>

hrefАтрибутов определяет , где старая версия. Следовательно, все остальные запросы для log4net будут указывать на новую версию.

Джгауффин
источник
4
Это отличное решение, потому что оно позволяет поддерживать обе версии для библиотек, которые также ссылаются.
SouthShoreAK
2
СПАСИБО! Это меня спасло. Мне пришлось изменить «Копировать в выходной каталог» на «Не копировать», но в остальном это работало как шарм!
Даниэль Хеденстрём
3

Вы можете скачать версию log4net 1.2.11.0, подписанную старым ключом. Причина, по которой ключ был изменен на новый, объясняется в их FAQ:

http://logging.apache.org/log4net/release/faq.html#two-snks

(В основном новый ключ общедоступен, и по какой-то причине они не хотели включать старый ключ в дистрибутив. Мне непонятно, почему они просто не сделали старый ключ общедоступным)

Стефан Эгли
источник
10
Но когда я использую стороннюю библиотеку, привязанную к новому ключу, я все равно застреваю (верно?). Это не мой выбор , чтобы использовать новый log4net, это основа третьей стороной. Я не понимаю, как этот материал не взорвется у всех, поскольку все больше и больше фреймворков начинают использовать log4net с новым ключом
Андреас Кнудсен
К сожалению, это правильно. Я думаю, вам нужно подумать о том, чтобы не все компоненты использовали одну и ту же версию log4net ...
Стефан Эгли,
1
.... и как мне это сделать? Есть ли какой-либо механизм в .net для решения этой проблемы?
AndreasKnudsen 06
1

Не знаю, подходит это для вашего конкретного случая или нет, но вы можете перекомпилировать одну из фреймворков, чтобы они использовали log4net с тем же открытым ключом. В моем случае это был FluentNHibernate, который использует log4net 1.2.10 и Combres с log4net 1.2.11 с новым ключом. Я скачал log4net 1.2.11, подписанный старым ключом, и перекомпилировал Combress с ним. После этого добавлено перенаправление привязки сборки с 1.2.10 на 1.2.11, и он начинает работать.

Алекс
источник
0

Это не обязательно сработает во всех случаях, но поскольку проект, который использовал log4net, был OSS, я загрузил исходный код, заменил конфликтующую версию log4net версией, которую использовал я, и перестроил проект. В моем случае это была Topshelf, так что теперь у меня есть версия сборки Topshelf, которая была построена с той же версией log4net, которую я использую, и теперь я могу ссылаться на обе без проблем.

Марк Дж. Миллер
источник
0

Я попытался перейти по ссылкам, указанным выше, но похоже, что все ссылки на сайте Apache не работают. Тогда вот что я сделал, чтобы решить проблему:

В Visual Studio используйте Nuget, чтобы загрузить и установить последнюю версию log4net (1.2.13.0). Диспетчер пакетов NuGet автоматически загрузит и обновит весь log4net (1.2.11.0) до последней версии.

Джордж Хуанг
источник