jak obejść log4net, ciągle zmieniając publickeytoken

99

Mamy projekt asp.net 4.0, który używa kilku struktur, który jest zależny od log4net w wersji 1.2.10.0. Dzisiaj próbowałem dołączyć nowy framework, który jest zależny od log4net w wersji 1.2.11.0, utknąłem od tego czasu:

log4net 1.2.10.0 ma publickeytoken = 1b44e1d426115821

log4net 1.2.11.0 ma publickeytoken = 669e0ddf0bb1aa2a

Ponieważ są one różne, nie mogę używać ani przekierowań do zestawu (aby wszystkie frameworki korzystały z tej samej wersji log4net), ani bazy kodu (aby mieć tylko nową wersję frameworka w wersji 1.2.11.0) za pośrednictwem elementu wykonawczego w pliku web.config.

Jakie mam opcje tutaj?

(i dlaczego sygnał dźwiękowy log4net ciągle zmienia publickeytokens między wersjami, jak rozumiem, zgubiony klucz był przyczyną przełączenia między wersjami 1.2.9.0 i 1.2.10.0, czy znowu zgubili klucz? Zgłoszę moją skrzynkę referencyjną aby był bezpieczny, gdyby tego potrzebowali ...)

Edycja: Ok, więc faceci z log4net najwyraźniej wpadli na pomysł, że wydanie z dwoma kluczami było dobrym pomysłem, ale oznacza to, że każdy framework, którego używasz, musi uzgodnić, który z dwóch preferuje, lub te ramy nie mogą działać po stronie obok siebie w tej samej domenie aplikacji. Czy tylko ja uważam, że to okropny pomysł? gdyby wszyscy to zrobili, wszystko by się zepsuło, prawda?

Edit2: Jak powiedziałem, nie używam log4net w moim kodzie biznesowym, ale używam kilku frameworków, które zależą od 1.2.10.0, a problem pojawił się, gdy próbowałem użyć nowego frameworka, który zależał od 1.2.11.0 (nowy klucz ), więc odpowiedź Stefansa nie ma zastosowania, ponieważ nowy framework będzie oczekiwał nowego klucza, a nie starego

AndreasKnudsen
źródło
1
IMHO, pierwszym błędem ze strony Apache jest dostarczenie plików binarnych podpisanych nowym kluczem: nowy klucz jest przeznaczony dla poprawionej / ulepszonej wersji open source i nie powinien być używany tak, jak jest. Drugim błędem jest to, że framework, o którym mówisz, został wydany tylko z nowym podpisem log4net: wersja ze starym podpisem powinna istnieć.
JoeBilly
6
Właściwie patrzysz na trzeci smak: ten, który geniusze SAP przekompilowali pod własną silną nazwą, jako część pakietu Crystal Reports for Visual Studio, a co gorsza, umieścili go w GAC, co sprawi, że Twoje zależności między maszynami koszmarem.
Jeremy Holovacs

Odpowiedzi:

65

W ten sposób wszystko działa z wersją 1.2.11.0.

  1. Klątwa apache za zmianę klucza w pierwszej kolejności :)
  2. Pobierz wersję 1.2.11.0 podpisaną starym kluczem.
  3. Uporządkuj swój własny kod, usuwając wszelkie bezpośrednie odwołania do log4net (nowy klucz) i zamień na odwołanie do zestawu podpisanego starym kluczem.
  4. Uporządkuj wszystkie zależne zestawy, które możesz mieć, dołączając ten segment do pliku 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>
David Christiansen
źródło
9
Pobranie wersji podpisanej starym kluczem publicznym jest konieczne, ponieważ niestety nie jest możliwe wykonanie przekierowania powiązania do zestawu z innym kluczem publicznym.
David Christiansen
2
Wydaje się, że kończy się to niepowodzeniem z powodu przełomowej zmiany w wersji 1.2.11.0: netpl.blogspot.com/2012/03/…
sydneyos
Czy ktoś znalazł rozwiązanie problemów opisanych pod linkiem wspomnianym przez @sydneyos, co powoduje następujący wyjątek:Method not found: 'Void log4net.Config.BasicConfigurator.Configure()'
Neo
Niestety nie ma innego rozwiązania niż obniżenie wersji do 1.2.10. (lub ponowne kompilowanie każdego używanego zestawu zależnego).
bk0
1
Umieść zestaw 1.2.10 w innym katalogu i użyj tej konfiguracji: „<dependentAssembly> <assemblyIdentity name =" log4net "publicKeyToken =" 1b44e1d426115821 "culture =" neutral "/> <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

Używam najnowszej wersji log4net, którą pobrałem za pośrednictwem nuget. Jednak jedna z bibliotek, których używam, wymaga starej wersji. Moje kłopoty doprowadziły mnie do tego pytania.

Problem z innymi odpowiedziami polega na tym, że używają one tej samej wersji dll dla wszystkich powiązań. Chcę używać funkcji w nowej wersji do wszystkiego innego oprócz starszej zależności.

Aby to zrobić, musisz wykonać następujące czynności:

  1. Zacznij od pobrania starej wersji (wersja 1.2.11.0).
  2. Zmień nazwę pobranego pliku binarnego na log4net.1.2.10.dll. Uwzględnij go w swoim projekcie startowym z akcją Kompiluj ustawioną na Nonei „Kopiuj, jeśli nowsza” wprowadź opis obrazu tutaj
  3. Poinformuj .NET, gdzie może znaleźć starszą wersję:

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>

hrefAtrybuty identyfikuje gdzie stara wersja jest. Dlatego wszystkie inne żądania dotyczące log4net będą wskazywać na nową wersję.

jgauffin
źródło
4
Jest to świetne rozwiązanie, ponieważ pozwala zachować obie wersje dla bibliotek, które się do nich odwołują.
SouthShoreAK
2
DZIĘKUJĘ CI! To mnie uratowało. Musiałem zmienić „Kopiuj do katalogu wyjściowego” na „Nie kopiuj”, ale poza tym działało to jak urok!
Daniel Hedenström
3

Możesz pobrać wersję log4net 1.2.11.0, która jest podpisana starym kluczem. Powód, dla którego zmieniono klucz na nowy, wyjaśniono w ich FAQ:

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

(Zasadniczo nowy klucz jest publicznie dostępny iz jakiegoś powodu nie chcieli uwzględniać starego klucza w dystrybucji. Nie jest dla mnie jasne, dlaczego nie udostępnili starego klucza publicznie)

Stefan Egli
źródło
10
Ale kiedy używam biblioteki innej firmy, która jest powiązana z nowym kluczem, nadal utknąłem (prawda?). Nie moim wyborem jest używanie nowego log4net, to framework innej firmy. Nie widzę, jak te rzeczy nie
wybuchną
To jest niestety poprawne. Chyba trzeba brać pod uwagę nie posiadające wszystkie elementy wykorzystać tę samą wersję log4net ...
Stefan Egli
1
.... i jak bym to zrobił? Czy w .net istnieje mechanizm obsługi tego problemu?
AndreasKnudsen
1

Nie wiem, czy jest to odpowiednie dla twojego konkretnego przypadku, czy nie, ale możesz przekompilować jeden z frameworków, aby używał log4net z tym samym kluczem publicznym. W moim przypadku był to FluentNHibernate, który używa log4net 1.2.10 i Combres z log4net 1.2.11 z nowym kluczem. Ściągnąłem log4net 1.2.11 podpisany starym kluczem i ponownie skompilowałem z nim Combress. Następnie dodane powiązanie zestawu przekierowuje z 1.2.10 na 1.2.11 i zaczyna działać.

Alex
źródło
0

To niekoniecznie zadziała we wszystkich przypadkach, ale ponieważ projekt korzystający z log4net był OSS, pobrałem źródło, zastąpiłem sprzeczną wersję log4net wersją, z której korzystałem i przebudowałem projekt. W moim przypadku był to Topshelf, więc mam teraz wersję zespołu Topshelf, która została zbudowana z tą samą wersją log4net, której używam i teraz mogę odwoływać się do obu bez problemu.

Mark J. Miller
źródło
0

Próbowałem przejść do linków podanych powyżej, ale wygląda na to, że wszystkie linki w witrynie Apache nie działają. Oto, co zrobiłem, aby rozwiązać problem:

W programie Visual Studio użyj narzędzia Nuget, aby pobrać i zainstalować najnowszą wersję log4net (1.2.13.0). Menedżer pakietów NuGet automatycznie pobierze i zaktualizuje cały log4net (1.2.11.0) do najnowszej wersji.

George Huang
źródło