8

Potrzebuję uzyskać niektóre metadane dotyczące zespołu, który wywołuje mój komponent. Jako takie, używanie Assembly.GetCallingAssembly() wydaje się być naturalnym dopasowaniem. Jednak odkryłem, że działa wszędzie, z wyjątkiem Windows Store. Gdzie jest obsługiwane:Assembly.GetCallingAssembly nie jest obsługiwany w WinRT, ale jest przeznaczony dla przenośnych bibliotek klas?

Jednakże, jeżeli to nie jest obsługiwany bezpośrednio w aplikacji Windows Store. Mogę utworzyć przenośną bibliotekę klas, a następnie wywołać ją stamtąd wewnątrz aplikacji Windows Store, ale nie mogę po prostu umieścić jej bezpośrednio w bibliotece aplikacji/klasy Sklepu Windows.

Czy istnieje obejście tego lub innego sposobu uzyskania typu metadanych dostarczonych przez Assembly?

Odpowiedz

7

Assembly.GetCallingAssembly nie jest narażony na WinRT - przypuszczalnie dlatego, że jego semantyka są zawodne w obliczu inline etc (source), ale to też nie pasuje zbytnio ograniczonego odbicia dozwolonym w systemie Windows Store aplikacji. można dostać coś takiego Assembly.GetCurrentAssembly(), np tak:

typeof(MainPage).GetTypeInfo().Assembly 

Ale to nie to samo co wszyscy. W przypadku modelu z ograniczonym odbiciem uzyskanie śledzenia stosu w czasie wykonywania, jak to jest możliwe w .NET, również nie będzie możliwe.

Jak do przenośnego klasy biblioteki, miałem powiedzieć, że Assembly.GetCurrentAssembly() jest obsługiwana w przenośnych bibliotek klas w ogóle, ale po prostu nie w WinRT - co miałoby sensu, jeśli nie jest to po prostu w tej platformie. W rzeczywistości wygląda na to, że jest obecny we wszystkich profilach, w tym WinRT, z wyjątkiem WinRT + .NET4.5 - wydaje się, że z tą niekonsekwencją musi być jakiś nadzór. Tak więc metoda dostępna w WinRT (a ponadto nie ma żadnego rodzaju przekierowania), ale nie jest widoczna w metadanych dostępnych w czasie kompilacji.

Dlatego można wywołać metodę z refleksji:

var assembly = (Assembly) typeof(Assembly).GetTypeInfo() 
    .GetDeclaredMethod("GetCallingAssembly") 
    .Invoke(null, new object[0]); 

Przypuszczam niepodlegania widoczność tej metody w systemie Windows Store aplikacji jest „chcemy to odejdzie”.

(Ta odpowiedź dotyczy tylko "może ja", a nie "powinienem").

2

Metoda została wycięta po prostu dlatego, że jest zbyt niewiarygodna w aplikacji WinRT. Silnym celem projektu dla WinRT było sprawienie, aby współdziałanie pomiędzy różnymi środowiskami językowymi było łatwe i bezproblemowe. Co działa dobrze, możesz z łatwością utworzyć komponent WinRT w języku takim jak C# i użyć go w aplikacji napisanej w niezarządzanym języku, takim jak C++ lub Javascript.

Jest to również możliwe w aplikacji .NET na komputery stacjonarne, ale jest o wiele bardziej skomplikowane, gdy trzeba wrócić do zespołu [ComVisible] lub utworzyć zestaw w trybie mieszanym w języku C++/CLI. Korzystanie z Assembly.GetCallingAssembly() w takim przypadku również zakończy się niepowodzeniem, jednak programista powinien ponieść porażkę, ponieważ jest świadomy, że robi coś specjalnego.

To staje się dużo bardziej mętne w komponencie WinRT. Zwłaszcza, że ​​nie jest to konieczne, jeśli wywołanie zostało wykonane z innego zestawu .NET.Ale nie ma nadziei, gdy pochodzi z niezarządzanego kodu.

Ten losowy rodzaj niepowodzenia to po prostu kompletna nędza bez przyzwoitego obejścia. W związku z tym metoda została przerwana. Używanie PCL to możliwe obejście problemu, ale Microsoft ostro ostrzegał w przeszłości, że tego rodzaju hakorama jest wysoce niezalecana. Przy niezerowych szansach, że zostanie przechwycony przez procedurę sprawdzania poprawności sklepu i spowoduje odrzucenie.