Odwoływanie się do 2 różnych wersji log4net w tym samym rozwiązaniu


80

Używam NHibernate 2.1.2.400, który odwołuje się do log4net 1.2.10.0. W tym samym projekcie używam również prostego zestawu SDK do księgowania, niestety nadal używa on log4net 1.2.9.0.

Mogę więc uruchomić NHibernate, jeśli odwołam się do log4net 1.2.10.0, ale SimplySDK nie działa. I wzajemnie...

Domyślam się, że większość problemów wynika z faktu, że log4net zmienił swój klucz asemblera. Próbowałem użyć przekierowania powiązania bez powodzenia: 2 biblioteki DLL nie mają tego samego klucza.

Zastanawiam się nad przekompilowaniem NHibernate do korzystania z log4net 1.2.9.0, ale wydaje mi się, że to niewłaściwa rzecz i czuję, że Simply Accounting nie zaktualizuje swojego SDK do korzystania z log4net 1.2.10.0 w najbliższym czasie.

Jak najlepiej sobie z tym poradzić? Czy w ogóle można to rozwiązać?


2
Mam bardzo podobne pytanie pod adresem stackoverflow.com/questions/1744543/ ... Uciekłem się do ponownej kompilacji. Myślę, że to nadejście dll-hell v2.0.
Sandor Drieënhuizen

1
podczas sprawdzania twojego pytania znalazłem stackoverflow.com/questions/2460542/2461746#2461746, które rozwiązało mój problem.
Joel Gauvreau

Świetny! Zastanawiałem się nad tym, aby CLR wyglądał w różnych lokalizacjach i hrefwydaje się, że atrybut załatwia sprawę. Dziękuję za zwrócenie uwagi!
Sandor Drieënhuizen

Odpowiedzi:


149

Znalazłem rozwiązanie, używając tej odpowiedzi na podobne pytanie

Tworzysz 2 foldery w swoim projekcie, po jednym dla każdej wersji log4net. Umieść każdy plik log4net.dll w odpowiednim folderze, dodając plik do rozwiązania (nie z dodawaniem odwołania). Możesz ustawić właściwość copy to output directory na kopiowanie zawsze, tak aby była automatycznie kopiowana do folderu wyjściowego podczas kompilacji.

Następnie modyfikujesz plik app.config, dodając coś takiego:

<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>

możesz uzyskać token klucza publicznego zestawu za pomocą sn -T [nazwa_zestawu]


2
Wydaje się, że to działa również dla mnie. Usunąłem log4net z mojej listy referencji dla projektu, w którym występował konflikt. Ponadto, ponieważ plik log4net.dll nie znajduje się w moich folderach bin, moje ścieżki href wyglądały bardziej jak „.. \ .. \ .. \ .. \ Lib \ NHibernate-2.0.1.GA \ log4net.dll” - po prostu względna ścieżka do miejsca, w którym log4net będzie się znajdować na komputerze każdego dewelopera z naszym systemem kompilacji.
jyoungdev

12
Nie jestem pewien, czy dostaję to: jak można uniknąć błędów kompilacji, jeśli nie ma odwołania do log4net?
guidupuy

2
To jest niesamowite, naprawiłoby inne przypadki, w których proste przekierowanie wiązania mogłoby zepsuć wszystko z powodu zmian w API!
Rhys Bevilaqua

5
@guidupy możesz odwołać się do log4net, którego używa twój kod, ale wyłącz copyLocal we właściwościach.
Jeff Martin

4
dla przyszłych czytelników (wskazówka, którą znalazłem w innej odpowiedzi, ale rozsądnie zamieścić ją tutaj) ... w przypadku aplikacji internetowych (asp.net) odniesienie ma poprawkę: <codeBase version = "1.0.0.0" href = "bin \ folder \ namedll.dll "/>
granadaCoder,

7

Możesz dodać wykluczenie do rejestru. Po prostu dodaj te klucze:

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

Spowoduje to pominięcie sprawdzania poprawności przez środowisko uruchomieniowe .NET dla wymienionych zestawów. W teorii jest to kwestia bezpieczeństwa, ale ponieważ klucz prywatny i tak jest otwarty, nie ma prawie żadnego wpływu.


Jak powiedziałeś, jest to kwestia bezpieczeństwa. Ponadto oznacza to, że musisz wprowadzić te zmiany na każdej stacji roboczej, na której działa oprogramowanie. W złożonej sieci przedsiębiorstwa takie rzeczy sumują się, tworząc ogromny bałagan. Wolałbym tego unikać tak bardzo, jak to tylko możliwe. Pozostałe rozwiązania są samodzielne i przenośne.
Joel Gauvreau

Jak powiedziałem, ponieważ klucze prywatne i tak są publicznie dostępne, nie ma żadnego prawdziwego problemu z bezpieczeństwem. Zwłaszcza w sieci korporacyjnej łatwiej byłoby skonfigurować pojedynczy obiekt zasad grupy, niż skonfigurować go dla każdej używanej aplikacji LOB. Możesz to skonfigurować raz na poziomie domeny i nigdy więcej o tym nie myśleć.
Joep Beusenberg

3

Jeśli przekierowanie powiązań nie działa, a prosty księgowy SDK jest zamkniętym źródłem, możliwym rozwiązaniem jest ponowna kompilacja NHibernate, aby używał log4net 1.2.9.0.


3
To by działało, ale konieczność zbudowania specjalnej wersji nhibernate byłaby trudniejsza do utrzymania w przyszłości… dzięki.
Joel Gauvreau
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.