Jakiś (bardzo długi) czas temu – we wpisie o Mono.Cecil (Mono.Cecil – ciekawostka) pokazałem małą ciekawostkę na którą można natrafić porównując działanie Mono.Cecil oraz System.Reflection. Polega ona na tym, że kod wyświetlający liczbę klas w danym assembly, różni się o 1 w zależności czy użyjemy Mono.Cecil czy Reflection. Tym razem wyjaśnienie fenomenu.
Na rozwiązanie nakierował mnie @SimonCropp poniższym tweetem

@pawel_lukasik cecil is correct. u can even inject code into module github.com/Fody/ModuleInit
— Simon Cropp (@SimonCropp) 2 lutego 2013

Mając takie informacje przystąpiłem do działania. Oczywiście na pierwszy ogień Google. StackOverflow wyrzuca dokładnie takie samo pytanie jakiej odpowiedzi szukam, ale odpowiedź jest dla mnie niezadowalająca. Biorąc jednak pod uwagę, że odpowiedzi udzielał sam John Skeet zakładam, że odszukanie zadowalającej mnie informacji nie będzie proste…

Szperając w kodzie jednego z modułów Fody’iego (o nim także niedługo wpis) można natrafić na nazwę związaną z tą funkcją Module Initializers. Mając ją można odnaleźć sporo informacji na ich temat. Nie będę wklejał linków, bo każdy może poszukać sobie samemu.

Podsumowując w kilku słowach, jest to specjalna cecha CLR’a niedostępna z poziomu C# czy VB a polegająca na uruchomieniu kod znajdującego się w typie <Module> w momencie ładowania Assembly do pamięci. Mamy również zagwarantowane, że kod ten wykona się przed każdym innym kodem z tego modułu. Jest kilka potencjalnych miejsc gdzie można by to wykorzystać.

Ciekawe tylko czemu wywołanie GetTypes – nie zwraca tego typu wśród odnalezionych w module. Ale wyjaśnienie tego może w jeszcze innym wpisie.


dotnetomaniak.pl