Trong bài viết này, chúng ta sẽ đi qua 3 phần chính: Assembly, Reflection, và cách thực thi 1 phương thức trong reflection.
Một vài Properties trong Assembly
TypeInfo chứa những định nghĩa về Type.
Type chứa dữ liệu tham chiếu
VD:
Giá trị trả về của phương thức GetMethod là một đối tượng kiểu System.Reflection.MethodInfo chứa các thông tin về phương thức.
VD:
Thêm hàm SayHello với parameter name thì cùng đoạn code trên, bạn sẽ bị báo lỗi:
System.Reflection.AmbiguousMatchException: Ambiguous match found
Khắc phục: gọi hàm GetMethod và truyền thêm type:
Trường hợp tạo đối tượng kèm parameter
https://dotnetcademy.net/Learn/4/Pages/3
Chúc các bạn thành công!
Assembly
Assembly là một thư viện gồm các đoạn code đã được dịch sẵn, do đó có thể chạy được bởi nhiều chương trình khác. Các chương trình khác chỉ cần bổ sung thư viện này và gọi các hàm trong thư viện, các hàm sẽ chạy ngay (do đã được dịch sẵn) mà không cần bộ dịch ngôn ngữ tương ứng và người viết chương trình cũng không cần tốn công viết lại các hàm đó nữa.Một vài Properties trong Assembly
public virtual string CodeBase { get; } //Gets the location of the assembly as specified originally, for example, in an AssemblyName object.
public virtual string FullName { get; } //Gets the display name of the assembly.
public virtual IEnumerable DefinedTypes { get; } //Gets a collection of the types defined in this assembly.
public virtual IEnumerable Modules { get; } //Gets a collection that contains the modules in this assembly.
Ví dụ: Load assembly từ 1 type
public class Student
{
public string FullName { get; set; }
public int Class { get; set; }
public DateTime DateOfBirth { get; set; }
public string GetCharacteristics()
{
return "";
}
}
private static void GetAssemblyFromType(Type t)
{
var assembly = System.Reflection.Assembly.GetAssembly(t);
Console.WriteLine("Assembly Name: " + assembly.GetName().Name);
Console.WriteLine("Version: " + assembly.GetName().Version);
}
Kết quả:
Assembly Name: ReflectionInActionVD 2: Load assembly từ Name và file DLL
Version: 1.0.0.0
private static void CallReflection()
{
Utilities.GetAssemblyFromAssemblyName("Services");
var fileInfo = new FileInfo(Assembly.GetEntryAssembly().Location);
var executingDll = Path.Combine(fileInfo.DirectoryName, "Services.dll");
Utilities.GetAssemblyFromDll(executingDll);
}
public static void GetAssemblyFromCallingMethod()
{
var assembly = System.Reflection.Assembly.GetCallingAssembly();
Console.WriteLine("Assembly Name: " + assembly.GetName().Name);
Console.WriteLine("Version: " + assembly.GetName().Version.ToString());
}
public static void GetAssemblyFromAssemblyName(string name)
{
Console.WriteLine("Get Assembly From Assembly Name");
var assembly = System.Reflection.Assembly.Load(name);
Console.WriteLine("Assembly Name: " + assembly.GetName().Name);
Console.WriteLine("Version: " + assembly.GetName().Version.ToString());
}
Kết quả:
Get Assembly From Assembly Name
Assembly Name: Services
Version: 1.0.0.0
Get Assembly From File Dll
Assembly Name: Services
Version: 1.0.0.0
Reflection là gì?
Reflection cung cấp các đối tượng (kiểu Type) mô tả các assembly, các module và các type. Bạn có thể sử dụng reflection để tạo tự động một đối tượng của một type, liên kết type với một đối tượng hiện có, hoặc lấy type từ một đối tượng hiện có và gọi các phương thức của nó hoặc truy cập các trường và thuộc tính của nó. Nếu bạn có sử dụng các attribute trong code, reflection sẽ cho phép bạn truy cập các attributes đó.Type and type info
Lớp System.Type là một abstract class đại diện cho các kiểu dữ liệu: kiểu lớp, interface, mảng, giá trị, kiểu liệt kê (enumberation types), kiểu tham số, …TypeInfo chứa những định nghĩa về Type.
private static void Example1()
{
var studentInfo = typeof(Student).GetTypeInfo();
var declaredProperties = studentInfo.DeclaredProperties;
var declaredMethods = studentInfo.DeclaredMethods;
Console.WriteLine("-------Declared Properties:------");
foreach (var prop in declaredProperties)
{
Console.WriteLine(prop.Name);
}
Console.WriteLine("-------Declared Methods:------");
foreach (var method in declaredMethods)
{
Console.WriteLine(method.Name);
}
}
Type chứa dữ liệu tham chiếu
private static void Example2()
{
var studentType = typeof(Student);
var name = studentType.Name;
var ns = studentType.Namespace;
Console.WriteLine("Name: " + name);
Console.WriteLine("Namespace: " + ns);
}
Fields
Reflection cho phép liệt kê các fields và các properties theo tên và giá trị của chúng.VD:
public class MyClass
{
public string Name { get; set; }
public static int TheField;
public void SayHello() { }
}
static void Main(string[] args)
{
Type type = typeof(MyClass); // Get type pointer
FieldInfo[] fields = type.GetFields(); // Obtain all fields
foreach (var field in fields) // Loop through fields
{
string name = field.Name; // Get string name
Console.WriteLine(name);
}
}
Kết quả:Thực thi một phương thức
Để thực thi 1 phương thức, bạn dùng hàm GetMethod() kết hợp với thông tin MethodInfo.Giá trị trả về của phương thức GetMethod là một đối tượng kiểu System.Reflection.MethodInfo chứa các thông tin về phương thức.
VD:
var myClass = new MyClass();
var myType = myClass.GetType();
// get method info SayHello
var myMethodInfo = myType.GetMethod("SayHello");
// invoke method SayHello with parameter null
myMethodInfo.Invoke(myClass, null);
Kết quả:HelloVD 2: Thực thi phương thức với parameter name
Thêm hàm SayHello với parameter name thì cùng đoạn code trên, bạn sẽ bị báo lỗi:
System.Reflection.AmbiguousMatchException: Ambiguous match found
Khắc phục: gọi hàm GetMethod và truyền thêm type:
var myClass = new MyClass();
var myType = myClass.GetType();
// get method info SayHello
var myMethodInfo = myType.GetMethod("SayHello", new[] { typeof(string) });
var mParams = new object[] { "Nhatkyhoctap" };
// invoke method SayHello with parameter null
myMethodInfo.Invoke(myClass, mParams);
Kết quả:
Hello NhatkyhoctapVD 3: gọi hàm generic
var myClass = new MyClass();
var myType = myClass.GetType();
// get method info SayHello
var myMethodInfo = myType.GetMethod("SayHi", new[] { typeof(string) });
var mParams = new object[] { "Nhatkyhoctap" };
var genericMethodInfo = myMethodInfo.MakeGenericMethod(typeof(string));
genericMethodInfo.Invoke(myClass, mParams);
Kết quả:Type: System.StringTạo đối tượng Class Activator chứa các method dùng để tạo ra đối tượng cục bộ hoặc từ xa, hoặc lấy tham chiếu đến các đối tượng từ xa hiện có. Lớp này không thể được thừa kế. Vd:
Hello Nhatkyhoctap
var dateTime = (DateTime)Activator.CreateInstance(typeof(DateTime));
Console.WriteLine(dateTime.Date);
Kết quả:
1/1/0001 12:00:00 AMVD 2:
Trường hợp tạo đối tượng kèm parameter
public class Category
{
public Category(string name)
{
Name = name;
}
public int Id { get; set; }
public string Name { get; set; }
public string UrlSlug { get; set; }
public string Description { get; set; }
}
Hàm Main:
static void Main(string[] args)
{
// create instance of class Category
var category = (Category)Activator.CreateInstance(typeof(Category), "Nhatkyhoctap");
Console.WriteLine(category.Name);
}
Kết quả:
Nhatkyhoctap
Tham khảo
https://www.dotnetperls.com/reflectionhttps://dotnetcademy.net/Learn/4/Pages/3
Chúc các bạn thành công!
Nhatkyhoctap's blog
Nhận xét
Đăng nhận xét