Refleksja – odczyt metadanych
Refleksja
Refleksja jest mechanizmem umożliwiającym odczytywanie metadanych. Dzięki niemu możemy odczytać atrybuty i własności obiektów w bibliotekach. Dzięki temu mechanizmowi możemy bez trudu odczytywać własne atrybuty tworzone jak w poprzednim wpisie https://mateuszstanek.pl/2018/02/04/wlasny-atrybut/
Ładowania biblioteki
Informację o bibliotece można pozyskać na kilka sposobów. W zależności jakie assembly chcemy załadować. Do wyboru mamy kilka metod dostępnych w klasie Assembly. Kilka z dostępnych metod to :
- GetAssembly – która jako parametr przyjmuje typ klasy – zwraca nam assembly, które ten typ zawiera
- GetExecutingAssembly – zwraca assembly, które jest aktualnie wykonywane, czyli to assembly, w którym znajduje się kod wywołujący zapytanie
- GetCallingAssembly – zwraca assembly, które wywołało metodę, w której wywołujemy zapytanie
- GetEntryAssembly – zwraca assembly, którego proces jest wykonywany
- LoadFrom – która jako parametr przyjmuje ścieżkę do biblioteki – zwraca nam assembly tego właśnie pliku
1 2 3 4 5 |
var assembly = Assembly.LoadFrom("AdditionalLibrary.dll"); var assembly2 = Assembly.GetExecutingAssembly(); var assembly3 = Assembly.GetEntryAssembly(); var assembly4 = Assembly.GetCallingAssembly(); var assembly5 = Assembly.GetAssembly(typeof(SomeAdditionalClass)); |
Po załadowaniu Assembly, możemy odczytać takie informacje jak atrybuty całego assemby, a także dostępne Typy danych.
Operacje na typach
Kiedy dostaniemy interesujący nas typ danych również możemy odczytać jego metadane. Refleksja umożliwia nam odczyt informacji na temat konstruktorów, pól, właściwości oraz metod.
Poniższy przykład obrazuje jak załadować i odczytać wszystkie właściwości i typy z danego assembly.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
using System; using System.Reflection; namespace ReflectionAssemblyRead { class Program { static void Main(string[] args) { var assembly = Assembly.LoadFrom("ExternalLibrary.dll"); foreach (var atribute in assembly.CustomAttributes) { Console.WriteLine($"{atribute.ToString()}"); } Console.WriteLine(); foreach (var type in assembly.ExportedTypes) { Console.WriteLine(type.ToString()); Console.WriteLine("Constructors"); foreach (var ctrs in type.GetConstructors()) { Console.WriteLine($"\t {ctrs.ToString()}"); foreach (var param in ctrs.GetParameters()) { Console.WriteLine($"\t\t parmeter {param.Name} : {param.ParameterType}"); } } Console.WriteLine("Properties"); foreach (var prop in type.GetProperties()) { Console.WriteLine($"\t {prop.ToString()}"); } Console.WriteLine("Fields"); foreach (var prop in type.GetFields()) { Console.WriteLine($"\t {prop.ToString()}"); } Console.WriteLine("Methods"); foreach (var method in type.GetMethods()) { Console.WriteLine($"\t {method.ToString()}"); foreach(var param in method.GetParameters()) { Console.WriteLine($"\t\t parmeter {param.Name} : {param.ParameterType}"); } Console.WriteLine($"\t\t return : {method.ReturnType}"); } } Console.ReadLine(); } } } |
Jak widzimy odczyt metadanych jest prosty, kompletny projekt możemy znaleść na moim GitHub-ie https://github.com/Matejkos/BlogProjects/
W następnym poście postaram się opowiedzieć, o tym jak za pomocą refleksji tworzyć obiekty, zmieniać ich właściwości czy też wywoływać metody.