2010-09-02 23 views
5

Lưu ý: Đây là lần theo dõi answer trên previous question.Sử dụng phản chiếu để nhận thuộc tính của thuộc tính thông qua phương thức được gọi từ thiết lập số

Tôi đang trang trí setter của một thuộc tính với một Thuộc tính được gọi là TestMaxStringLength được sử dụng trong phương pháp được gọi từ trình thiết lập để xác thực.

Khách sạn hiện trông như thế này:

public string CompanyName 
{ 
    get 
    { 
     return this._CompanyName; 
    } 
    [TestMaxStringLength(50)] 
    set 
    { 
     this.ValidateProperty(value); 
     this._CompanyName = value; 
    } 
} 

Nhưng tôi thà cho nó trông như thế này:

[TestMaxStringLength(50)] 
public string CompanyName 
{ 
    get 
    { 
     return this._CompanyName; 
    } 
    set 
    { 
     this.ValidateProperty(value); 
     this._CompanyName = value; 
    } 
} 

Mã cho ValidateProperty đó là chịu trách nhiệm về nhìn lên các thuộc tính của setter là :

private void ValidateProperty(string value) 
{ 
    var attributes = 
     new StackTrace() 
      .GetFrame(1) 
      .GetMethod() 
      .GetCustomAttributes(typeof(TestMaxStringLength), true); 
    //Use the attributes to check the length, throw an exception, etc. 
} 

Làm cách nào để thay đổi ValidateProperty mã để tìm thuộc tính trên thuộc tính thay vì phương thức thiết lập ?

Trả lời

7

Theo như tôi biết, không có cách nào để có được một PropertyInfo từ một MethodInfo của một trong các setters của nó. Mặc dù, tất nhiên, bạn có thể sử dụng một số chuỗi hack, như sử dụng tên cho tra cứu, và như vậy. Tôi đang nghĩ đến điều gì đó như:

var method = new StackTrace().GetFrame(1).GetMethod(); 
var propName = method.Name.Remove(0, 4); // remove get_/set_ 
var property = method.DeclaringType.GetProperty(propName); 
var attribs = property.GetCustomAttributes(typeof(TestMaxStringLength), true); 

Không cần phải nói, tuy nhiên, điều đó không thực sự chính xác.

Ngoài ra, hãy cẩn thận với lớp StackTrace - đó cũng là một con heo hiệu suất, khi được sử dụng quá thường xuyên.

2

Trong lớp khai báo phương thức, bạn có thể tìm kiếm thuộc tính chứa setter đó. Nó không hoạt động, nhưng không phải là StackTrace.

void ValidateProperty(string value) 
{ 
    var setter = (new StackTrace()).GetFrame(1).GetMethod(); 

    var property = 
     setter.DeclaringType 
       .GetProperties() 
       .FirstOrDefault(p => p.GetSetMethod() == setter); 

    Debug.Assert(property != null); 

    var attributes = property.GetCustomAttributes(typeof(TestMaxStringLengthAttribute), true); 

    //Use the attributes to check the length, throw an exception, etc. 
} 
2

Bạn có thể xem xét, như một phương pháp thay thế, trì hoãn xác thực cho đến sau này, do đó loại bỏ sự cần thiết phải kiểm tra theo dõi ngăn xếp.

Ví dụ này cung cấp một thuộc tính ...

public class MaxStringLengthAttribute : Attribute 
{ 
    public int MaxLength { get; set; } 
    public MaxStringLengthAttribute(int length) { this.MaxLength = length; } 
} 

... một POCO với thuộc tính áp dụng cho một tài sản ...

public class MyObject 
{ 
    [MaxStringLength(50)] 
    public string CompanyName { get; set; } 
} 

... và vẫn còn sơ khai lớp tiện ích xác nhận đối tượng.

public class PocoValidator 
{ 
    public static bool ValidateProperties<TValue>(TValue value) 
    { 
     var type = typeof(TValue); 
     var props = type.GetProperties(BindingFlags.Public | BindingFlags.Instance); 
     foreach (var prop in props) 
     { 
      var atts = prop.GetCustomAttributes(typeof(MaxStringLengthAttribute), true); 
      var propvalue = prop.GetValue(value, null); 

      // With the atts in hand, validate the propvalue ... 
      // Return false if validation fails. 
     } 

     return true; 
    } 
} 
+0

Ooh. Tôi thích cách tiếp cận này tốt hơn nhiều so với quan điểm mã hóa. Tất nhiên, việc trang trí thuộc tính là vô dụng trừ khi việc xác nhận được thực thi, điều này khó hơn một chút để giả định trong mô hình này, nhưng tổng thể nó phải nhanh hơn và sạch hơn. –

+0

bạn có thể vui lòng cho tôi biết làm cách nào để xác thực giá trị đối với các atts? Cảm ơn! – VladL

Các vấn đề liên quan