Reflection - Complicate Example in C#
C#
24
Reflection
1
Example
1
White

Rice viết ngày 06/10/2018

Mình khá là lười, nên mình sẽ không đưa định nghĩa hay usage của reflection vào đây. Vì dù sao mình cũng sẽ chỉ copy thôi :smile:. Vậy nên chúng ta đi thằng vào ví dụ luôn nhé.

Mình tạo ra một class Person và mình muốn user đưa tên và tuổi của Person vào. Mình muốn đặt ra một số từ bị cấm trong attribute Name (Hoặc trong bất cứ attribute nào là string). Đầu tiên mình tạo class Person.

class Person
{
public string Name { get; set; }
public int Age { get; set; }
}

Sau đó mình tạo class ForbiddenWordAttribute Class sử dụng Attribute.

[AttributeUsage(AttributeTargets.Property,AllowMultiple =false)]
class ForbiddenWordAttribute: Attribute
{
public string word { get; private set; }
public ForbiddenWordAttribute(string word)
{
this.word = word;
}
}

Syntax để định nghĩa một Attribute là:

[AttributeUsage(
validon — target, in here is property
AllowMultiple=allowmultiple — optional
Inherited=inherited — optional
)]

Sau đó mình tạo class ForbiddenWordValidation để tạo logic cho ForbidenWordAttribute.

class ForbiddenWordValidation : IValidation
{
public bool Validate(object instance, PropertyInfo property)
{
ForbiddenWordAttribute word = property.GetCustomAttribute<ForbiddenWordAttribute>();
if(property.PropertyType == typeof(string))
{
string value = (string)property.GetValue(instance);
return !value.Contains(word.word);
}
else
{
throw new InvalidOperationException();
}
}
}

Ở đây mình tạo một explicit interface Ivalidation sẽ chứa bool Validate để xác định logic. Mình tao nó vì mình không biết tương lai liệu có Attribute nào có cùng target không, nếu có mình có thể để nó sử dụng interface này để giảm bớt việc viết lại bool Validate.

Logic ở đây khá đơn giản, Mình check xem property có phải string không, nếu phải thì mình check xem nó có chưa forbidden word không. Nếu có thì trả về False, không thì về True. Nếu User dùng Attribute này với property không phải string thì throw Exception.

Vì mình không chắc mình sẽ chỉ dùng 1 attributes trong tương lai nên mình đẩy hết về 1 class để dễ xử lí. Cái đó gọi là Factory Pattern.

class ValidatorFactory
{
public IValidation GetValidation(Attribute attribute)
{
if(attribute is ForbiddenWordAttribute)
{
return new ForbiddenWordValidation();
}
return null;
}
}

Cuối cùng mình dùng class Validator để kiểm tra mọi thứ và wrap mọi thứ lại.

class Validator
{
public bool Validate(object instance)
{
ValidatorFactory factory = new ValidatorFactory();
PropertyInfo[] properties = instance.GetType().GetProperties();
foreach(PropertyInfo property in properties)
{
var attributes = property.GetCustomAttributes();
foreach(Attribute attr in attributes)
{
IValidation validation = factory.GetValidation(attr);
if(attr != null && !validation.Validate(instance,property))
{
return false;
}
}
}
return true;
}
}

Giờ mình quay lại class Person để set Forbidden word là "Hoang"

class Person
{
[ForbiddenWord(“Hoang”)]
public string Name { get; set; }
public int Age { get; set; }
}

Giờ chúng ta test trong Main Program:

class Program
{
static void Main(string[] args)
{
Person goodPerson = new Person { Name = “Rice”, Age = 22 };
Person badPerson = new Person { Name = “Hoang”, Age = 22 };
Validator validator = new Validator();
Console.WriteLine($”FIRST: {validator.Validate(goodPerson)}”);
Console.WriteLine($”SECOND: {validator.Validate(badPerson)}”);
Console.ReadLine();
}
}

alt text

Vậy là xong một cái ví dụ phức tạp rồi. :D

Full source code: https://github.com/PhiHuyHoang/Programming3/tree/master/Reflection/Reflection

Bình luận


White
{{ comment.user.name }}
Bỏ hay Hay
{{comment.like_count}}
Male avatar
{{ comment_error }}
Hủy
   

Hiển thị thử

Chỉnh sửa

White

Rice

7 bài viết.
12 người follow
Kipalog
{{userFollowed ? 'Following' : 'Follow'}}
Cùng một tác giả
White
12 8
Sản phẩm sau khi làm http://coffeetube.herokuapp.com/ Yêu cầu Nói chung thì giờ download nhạc từ youtube thì nó có vô số cách rồi. Nhưng tự mình...
Rice viết 2 tháng trước
12 8
White
7 4
Trước giờ logic code của mình vẫn luôn dễ dãi như gái làng chơi nên đôi khi nó đã support thêm cho mình cái đức tính càng lúc càng không (thèm) kiê...
Rice viết 2 tháng trước
7 4
White
4 0
Mục tiêu Mình muốn làm một chương trình: Đọc rss (definition and usage of rss :arrow_right: https://en.wikipedia.org/wiki/RSS) Lựa chọn những ...
Rice viết 1 tháng trước
4 0
{{like_count}}

kipalog

{{ comment_count }}

bình luận

{{liked ? "Đã kipalog" : "Kipalog"}}


White
{{userFollowed ? 'Following' : 'Follow'}}
7 bài viết.
12 người follow

 Đầu mục bài viết

Vẫn còn nữa! x

Kipalog vẫn còn rất nhiều bài viết hay và chủ đề thú vị chờ bạn khám phá!