Note: This is a follow-up to an answer on a previous question.
I\'m decorating a property\'s setter with an Attribute called TestMaxStringLength
As far as I know, there's no way to get a PropertyInfo from a MethodInfo of one of its setters. Though, of course, you could use some string hacks, like using the name for the lookup, and such. I'm thinking something like:
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);
Needless to say, though, that's not exactly performant.
Also, be careful with the StackTrace class - it's a performance hog, too, when used too often.
You could consider, as an alternative approach, delaying validation until later, thus removing the need to inspect the stack trace.
This example provides an attribute...
public class MaxStringLengthAttribute : Attribute
{
public int MaxLength { get; set; }
public MaxStringLengthAttribute(int length) { this.MaxLength = length; }
}
... a POCO with the attribute applied to a property...
public class MyObject
{
[MaxStringLength(50)]
public string CompanyName { get; set; }
}
... and a utility class stub that validates the object.
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;
}
}
In the class that declares the method, you could search for the property that contains that setter. It's not performant, but neither is 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.
}