Mam bardzo dziwny błąd na naszej maszynie testowej. Błąd jest następujący:
System.TypeLoadException: Method 'SetShort' in type 'DummyItem' from assembly 'ActiveViewers (...)' does not have an implementation.
Po prostu nie rozumiem dlaczego. SetShort
jest w DummyItem
klasie, a nawet skompilowałem wersję z zapisem do dziennika zdarzeń, aby upewnić się, że nie jest to problem z wdrażaniem / wersjonowaniem. Dziwne jest to, że kod wywołujący nawet nie wywołuje SetShort
metody.
c#
.net
fusion
typeloadexception
Benjol
źródło
źródło
Odpowiedzi:
UWAGA - Jeśli ta odpowiedź ci nie pomoże, poświęć czas na przewinięcie w dół innych odpowiedzi dodanych od tego czasu.
Krótka odpowiedź
Może się tak zdarzyć, jeśli dodasz metodę do interfejsu w jednym zestawie, a następnie do klasy implementującej w innym zestawie, ale przebudujesz zespół implementujący bez odwoływania się do nowej wersji zestawu interfejsu.
W tym przypadku DummyItem implementuje interfejs z innego zestawu. Metoda SetShort została niedawno dodana zarówno do interfejsu, jak i do DummyItem - ale zestaw zawierający DummyItem został przebudowany w odniesieniu do poprzedniej wersji zestawu interfejsu. Zatem metoda SetShort jest skuteczna, ale bez magicznego sosu łączącego ją z równoważną metodą w interfejsie.
Długa odpowiedź
Jeśli chcesz spróbować to odtworzyć, spróbuj wykonać następujące czynności:
Utwórz projekt biblioteki klas: InterfaceDef, dodaj tylko jedną klasę i skompiluj:
Utwórz projekt biblioteki drugiej klasy: Implementacja (z osobnym rozwiązaniem), skopiuj InterfaceDef.dll do katalogu projektu i dodaj jako odwołanie do pliku, dodaj tylko jedną klasę i skompiluj:
Utwórz trzeci, konsolowy projekt: ClientCode, skopiuj dwie biblioteki dll do katalogu projektu, dodaj odwołania do plików i dodaj następujący kod do metody Main:
Uruchom kod raz, konsola mówi „witaj świecie”
Odkomentuj kod w dwóch projektach dll i przebuduj - skopiuj dwa dll z powrotem do projektu ClientCode, przebuduj i spróbuj uruchomić ponownie. TypeLoadException występuje podczas próby utworzenia instancji klasy ImplementingClass.
źródło
Oprócz tego, co już odpowiedziała własna pytająca, warto zwrócić uwagę na następujące kwestie. Dzieje się tak dlatego, że klasa może mieć metodę z tym samym podpisem co metoda interfejsu bez implementacji tej metody. Poniższy kod ilustruje to:
źródło
Mam to, gdy moja aplikacja nie ma odwołania do innego zestawu definiującego klasę, której użyła metoda w komunikacie o błędzie. Uruchomienie PEVerify dało bardziej pomocny błąd: „System nie może znaleźć określonego pliku”.
źródło
Natknąłem się na tę samą wiadomość i oto, co znaleźliśmy: w naszym projekcie wykorzystujemy biblioteki DLL stron trzecich. Po wydaniu nowej wersji zmieniliśmy nasz projekt, aby wskazywał na nowy zestaw bibliotek DLL i pomyślnie skompilowaliśmy.
Wyjątek został zgłoszony, gdy próbowałem zainicjować jedną z klas interfejsu w czasie wykonywania. Zadbaliśmy o to, aby wszystkie pozostałe referencje były aktualne, ale nadal nie ma szczęścia. Potrzebowaliśmy trochę czasu, aby zauważyć (za pomocą Przeglądarki obiektów), że typ zwracany przez metodę w komunikacie o błędzie jest zupełnie nowym typem z nowego, niepowiązanego zestawu.
Dodaliśmy odniesienie do zestawu i błąd zniknął.
źródło
Ten błąd wystąpił w następującym scenariuszu.
var target = Assembly.GetAssembly(typeof(FertPin.Classes.Contact));
Dla mnie poprawką było uaktualnienie odwołania System.Web.Mvc w asemblerze B do 4.0.0.0. Teraz wydaje się oczywiste!
Dzięki oryginalnemu plakatowi!
źródło
Innym razem możesz otrzymać ten błąd, jeśli masz niepoprawną wersję podpisanego zestawu. To nie jest normalny objaw tej przyczyny, ale oto scenariusz, w którym ją dostałem
Projekt asp.net zawiera zestaw A i zestaw B, nazwa B jest silnie nazwana
zestaw A używa Activator.CreateInstance do załadowania zestawu C (tzn. nie ma odniesienia do C, które jest budowane osobno)
C został zbudowany w odniesieniu do starszej wersji zestawu B niż obecnie
mam nadzieję, że to komuś pomoże - zrozumienie tego zajęło mi wieki.
źródło
Miałem też ten błąd, był on spowodowany przez dowolną exe CPU odwołującą się do dowolnych zestawów CPU, które z kolei odnosiły się do zestawu x86.
Wyjątek narzekał na metodę klasy w MyApp.Implementations (Any CPU), która wyprowadziła MyApp.Interfaces (Any CPU), ale w fuslogvw.exe znalazłem ukrytą „próbę załadowania programu z wyjątkiem niepoprawnego formatu” z MyApp .CommonTypes (x86), który jest używany przez oba.
źródło
Wracam do tego ... Wiele odpowiedzi tutaj świetnie tłumaczy, na czym polega problem, ale nie jak go naprawić.
Rozwiązaniem tego jest ręczne usunięcie plików bin z katalogu opublikowanego projektu. Wyczyści wszystkie referencje i zmusi projekt do korzystania z najnowszych bibliotek DLL.
Nie sugeruję używania funkcji usuwania narzędzi do publikowania, ponieważ ma to tendencję do odrzucania IIS.
źródło
Mam jeszcze inne ezoteryczne rozwiązanie tego komunikatu o błędzie. Uaktualniłem docelową platformę z .Net 4.0 do 4.6, a mój projekt testu jednostkowego dawał mi błąd „System.TypeLoadException ... nie ma implementacji” podczas próby kompilacji. Dał także drugi komunikat o błędzie dotyczący tej samej rzekomo niezaimplementowanej metody, która mówiła: „Zadanie„ BuildShadowTask ”nieoczekiwanie zakończyło się niepowodzeniem”. Żadna z tych rad nie pomogła, więc szukałem „BuildShadowTask” i znalazłem post na MSDN, który skłonił mnie do skorzystania z edytora tekstu do usunięcia tych wierszy z pliku csproj projektu testowego.
Następnie oba błędy zniknęły i projekt został zbudowany.
źródło
Wystąpił ten błąd w kontekście, w którym korzystałem z funkcji Autofac i dużej ilości dynamicznego ładowania zespołu.
Podczas wykonywania operacji rozpoznawania Autofac środowisko wykonawcze nie może załadować jednego z zestawów. Komunikat o błędzie narzekał, że
Method 'MyMethod' in type 'MyType' from assembly 'ImplementationAssembly' does not have an implementation
. Symptomy występowały podczas działania na maszynie wirtualnej z systemem Windows Server 2012 R2, ale nie występowały na maszynach wirtualnych z systemem Windows 10 lub Windows Server 2016.ImplementationAssembly
odwoływał się doSystem.Collections.Immutable
1.1.37 i zawierał implementacjeIMyInterface<T1,T2>
interfejsu, który został zdefiniowany w osobnymDefinitionAssembly
.DefinitionAssembly
wymienionySystem.Collections.Immutable
1.1.36.Metody, z
IMyInterface<T1,T2>
których „nie zaimplementowano”, miały parametry typuIImmutableDictionary<TKey, TRow>
zdefiniowane wSystem.Collections.Immutable
.Rzeczywista kopia
System.Collections.Immutable
znaleziona w katalogu programu to wersja 1.1.37. Na mojej maszynie wirtualnej z systemem Windows Server 2012 R2 GAC zawierał kopięSystem.Collections.Immutable
1.1.36. W systemach Windows 10 i Windows Server 2016 GAC zawierał kopięSystem.Collections.Immutable
1.1.37. Błąd ładowania wystąpił tylko wtedy, gdy GAC zawierał starszą wersję biblioteki DLL.Tak więc główną przyczyną niepowodzenia ładowania zestawu były niedopasowane odwołania
System.Collections.Immutable
. Definicja interfejsu i implementacja miały identycznie wyglądające sygnatury metod, ale w rzeczywistości zależały od różnych wersjiSystem.Collections.Immutable
, co oznaczało, że środowisko wykonawcze nie uznało klasy implementacji za zgodną z definicją interfejsu.Dodanie następującego przekierowania wiązania do mojego pliku konfiguracyjnego aplikacji naprawiło problem:
źródło
System.Collections.Immutable
. W moim przypadku nie było wielu innych kandydujących parametrów lub typów zwracanych w metodzie, której dotyczy problem. Pamiętam też, jak korzystałem z ILSpy do sprawdzania metadanych zależności w skompilowanych bibliotekach DLL „DefinitionAssembly” i „ImplementationAssembly”, w szczególności patrząc na wersje odnośników.System.Net.Http
pakietu, dodałem do niegodependentAssembly
element i skopiowałem informacje z ILSpy i działa teraz, błąd zniknął!Mam to w zależności od projektu w kształcie „rombu”:
Zrekompilowałem projekt A, ale nie projekt B, który pozwolił Projektowi B „wstrzyknąć” starą wersję biblioteki DLL projektu
źródło
Spotkałem się z tym, kiedy zmieniłem nazwę projektu (i nazwy zestawu), od którego zależał projekt ASP.NET. Typy w projekcie sieciowym implementują interfejsy w zespole zależnym. Pomimo wykonania Czystego rozwiązania z menu Kompilacja, zespół o poprzedniej nazwie pozostał w
bin
folderze i po uruchomieniu mojego projektu internetowegopowyższy wyjątek został zgłoszony, narzekając, że metody interfejsu w implementujących typach sieci nie zostały faktycznie zaimplementowane. Ręczne usunięcie zestawu w
bin
folderze projektu internetowego rozwiązało problem.źródło
Ten błąd również wystąpił, gdy wcześniej włączyłem Pokrycie kodu podczas testowania jednostek dla jednego z zespołów. Z jakiegoś powodu program Visual Studio „buforował” starą wersję tej konkretnej biblioteki DLL, mimo że ją zaktualizowałem, aby zaimplementować nową wersję interfejsu. Wyłączenie pokrycia kodu pozbyło się błędu.
źródło
Ten błąd może być również spowodowany, jeśli zestaw jest ładowany przy użyciu Assembly.LoadFrom (String) i odnosi się do zestawu, który został już załadowany przy użyciu Assembly.Load (Byte []).
Na przykład osadziłeś zestawy główne aplikacji jako zasoby, ale aplikacja ładuje wtyczki z określonego folderu.
Zamiast używać LoadFrom, powinieneś użyć Load. Następujący kod wykona zadanie:
źródło
Kolejne wyjaśnienie tego rodzaju problemu dotyczącego zarządzanego C ++.
Jeśli spróbujesz wkleić interfejs zdefiniowany w zestawie utworzonym przy użyciu zarządzanego C ++, który ma specjalną sygnaturę, otrzymasz wyjątek podczas tworzenia kodu pośredniczącego.
Jest to prawdą w przypadku Rhino Mocks i prawdopodobnie każdego używanego frameworka
System.Reflection.Emit
.Definicja interfejsu otrzymuje następujący podpis:
Zauważ, że typ C ++
long
odwzorowuje naSystem.Int32
(lub po prostuint
w C #). Jest to nieco niejasne,modopt
które powoduje problem, jak stwierdził Ayende Rahien na liście mailingowej Rhino Mocks .źródło
System::Byte
. Zmieniłem podpis, aby zaakceptowaćunsigned short
i niebo znów było niebieskie.Właśnie zaktualizowałem rozwiązanie z MVC3 do MVC5 i zacząłem otrzymywać ten sam wyjątek od mojego projektu testu jednostkowego.
Sprawdziłem wszystkie referencje szukając starych plików, w końcu odkryłem, że muszę wykonać pewne przekierowania wiązania dla Mvc w moim projekcie testu jednostkowego.
źródło
W moim przypadku pomogło zresetować zestaw narzędzi WinForms.
Mam wyjątek podczas otwierania
Form
w projektancie; kompilacja i uruchomienie kodu było jednak możliwe, a kod działał zgodnie z oczekiwaniami. Wyjątek wystąpił w lokalnejUserControl
implementacji interfejsu z jednej z moich bibliotek, do których istnieją odniesienia. Błąd pojawił się po aktualizacji tej biblioteki.Zostało
UserControl
to wymienione w zestawie narzędzi WinForms. Prawdopodobnie Visual Studio zachował odnośnik do nieaktualnej wersji biblioteki lub buforował gdzieś nieaktualną wersję.Oto, jak wyzdrowiałem z tej sytuacji:
Reset Toolbox
w menu kontekstowym. (Spowoduje to usunięcie niestandardowych elementów z Przybornika).W moim przypadku elementy Toolbox zostały przywrócone do stanu domyślnego; brakowało jednak strzałki-wskaźnika w Przyborniku.
W moim przypadku program Visual Studio zakończył działanie z wyjątkiem naruszenia i został przerwany.
Teraz wszystko działa płynnie.
źródło
FWIW, otrzymałem to, gdy istniał plik konfiguracyjny przekierowujący do nieistniejącej wersji zestawu odniesienia. Dzienniki Fusion dla wygranej!
źródło
Wystąpił ten błąd, ponieważ miałem klasę w zestawie „C”, która znajdowała się w wersji 4.5 frameworka, implementując interfejs w zestawie „A”, który był w wersji 4.5.1 frameworka i służąc jako klasa bazowa dla asemblera „B”, który był również w wersji 4.5.1 ram. System zgłosił wyjątek podczas próby załadowania zestawu „B”. Dodatkowo zainstalowałem kilka pakietów nuget ukierunkowanych na .net 4.5.1 na wszystkich trzech zestawach. Z jakiegoś powodu, mimo że odniesienia nuget nie były wyświetlane w zestawie „B”, budowanie przebiegło pomyślnie.
Okazało się, że prawdziwym problemem było to, że zestawy odwoływały się do różnych wersji pakietu nuget zawierającego interfejs, a sygnatura interfejsu zmieniała się między wersjami.
źródło
W moim przypadku wcześniej odwoływałem się do
mylib
projektu w folderze rodzeństwa poza repozytorium - nazwijmy tov1.0
.Później zrobiłem to poprawnie i użyłem go przez submoduł git - nazwijmy to
v2.0
. Jeden projektconsoleApp
nie został jednak poprawnie zaktualizowany. Nadal odwoływał się do staregov1.0
projektu poza moim projektem git.Mylące , mimo że
*.csproj
było to po prostu błędne i wskazujev1.0
, Visual Studio IDE pokazało ścieżkę jakov2.0
projekt! F12, aby sprawdzić interfejs i klasę, również przeszedł dov2.0
wersji.Zespół umieszczony w folderze bin przez kompilator był
v1.0
wersją, stąd ból głowy.Fakt, że IDE mnie okłamał, bardzo utrudnił zrozumienie błędu.
Rozwiązanie : usunięto odniesienia do projektu
ConsoleApp
i odczytałem je.Porada ogólna: Ponownie skompiluj wszystkie zestawy od zera (tam, gdzie to możliwe, oczywiście nie jest to możliwe w przypadku pakietów nuget) i sprawdź znaczniki datetime w
bin\debug
folderze. Wszystkie stare datowane zespoły są twoim problemem.źródło
Napotkałem prawie ten sam problem. Drapałem się w głowę, co powoduje ten błąd. Sprawdziłem krzyżowo, wszystkie metody zostały wdrożone.
Na Googlingu dostałem ten link między innymi. Na podstawie komentarza @Paul McLink, te dwa kroki rozwiązały problem.
i błąd zniknął .
Uruchom ponownie wtyczkę VS
Dzięki Paul :)
Mam nadzieję, że to pomoże komuś, kto napotka ten błąd :)
źródło
Zetknąłem się również z tym problemem podczas uruchamiania moich najsprawniejszych. Aplikacja działała poprawnie i bez błędów. Przyczyną problemu w moim przypadku było to, że wyłączyłem budowę projektów testowych. Ponowne włączenie budowy moich projektów testowych rozwiązało problemy.
źródło
Widziałem to w programie Visual Studio Pro 2008, gdy dwa projekty budowały zestawy o tej samej nazwie, jeden klasowy lib SDF.dll i jeden, który odwoływał się do biblioteki lib o nazwie zestawu sdf.exe. Kiedy zmieniłem nazwę zestawu odniesienia, wyjątek zniknął
źródło
Oznacza to po prostu, że projekt wdrożeniowy jest nieaktualny w moich przypadkach. Biblioteka DLL zawierająca interfejs została przebudowana, ale dll implementacji był nieaktualny.
źródło
Oto moje zdanie na temat tego błędu.
Dodano
extern
metodę, ale moja pasta była wadliwa.DllImportAttribute
Got umieścić na zakomentowanym linii.Sprawdzenie, czy atrybut został faktycznie dołączony do źródła, rozwiązało problem.
źródło
Dostałem to w usłudze WCF ze względu na wybranie typu kompilacji x86, co powoduje, że pojemniki działają pod bin \ x86 zamiast bin. Wybranie dowolnego procesora spowodowało, że skompilowane biblioteki DLL trafiły do właściwych lokalizacji (nie będę szczegółowo omawiał, jak to się stało).
źródło
Miałem ten sam problem. Doszedłem do wniosku, że mój zestaw, który jest ładowany przez program główny, zawierał pewne odniesienia z ustawieniem „Kopiuj lokalnie” na true. Te lokalne kopie referencji szukały innych referencji w tym samym folderze, które nie istniały, ponieważ „Kopiuj lokalnie” innych referencji ustawiono na fałsz. Po usunięciu „przypadkowo” skopiowanych referencji błąd zniknął, ponieważ program główny ustawiono tak, aby szukał poprawnej lokalizacji referencji. Najwyraźniej lokalne kopie referencji spieszyły sekwencję wywoływania, ponieważ te lokalne kopie zostały użyte zamiast oryginalnych kopii obecnych w programie głównym.
Komunikat zabrania do domu jest taki, że ten błąd pojawia się z powodu brakującego łącza do załadowania wymaganego zestawu.
źródło
W moim przypadku próbowałem użyć
TypeBuilder
do utworzenia typu.TypeBuilder.CreateType
rzucił ten wyjątek. W końcu zdałem sobie sprawę, że muszę dodaćMethodAttributes.Virtual
do atrybutów, gdy wzywamTypeBuilder.DefineMethod
metodę, która pomaga zaimplementować interfejs. Wynika to z faktu, że bez tej flagi metoda nie implementuje interfejsu, a zamiast tego nową metodę z tym samym podpisem (nawet bez określeniaMethodAttributes.NewSlot
).źródło
Jako uzupełnienie: może to również nastąpić, jeśli zaktualizujesz pakiet nuget, który został użyty do wygenerowania fałszywego zestawu. Załóżmy, że instalujesz wersję 1.0 pakietu nuget i tworzysz fałszywy zestaw „fakeLibrary.1.0.0.0.Fakes”. Następnie aktualizujesz do najnowszej wersji pakietu nuget, powiedzmy v1.1, która dodała nową metodę do interfejsu. Biblioteka Fakes nadal szuka wersji 1.0 biblioteki. Po prostu usuń fałszywy zespół i zregeneruj go. Jeśli to był problem, prawdopodobnie to rozwiąże.
źródło
Ten błąd wystąpił po ostatniej aktualizacji systemu Windows. Miałem klasę usług ustawioną na dziedziczenie z interfejsu. Interfejs zawierał podpis, który zwrócił ValueTuple, dość nową funkcję w języku C #.
Mogę tylko zgadywać, że aktualizacja systemu Windows zainstalowała nową, ale nawet wyraźnie ją odwołuje, aktualizuje przekierowania wiązania itp. Ostatecznym rezultatem była zmiana podpisu metody na coś „standardowego”. Myślę, że można powiedzieć.
źródło