Created
August 7, 2009 15:48
-
-
Save tncbbthositg/163975 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[Serializable] | |
[AttributeUsage(AttributeTargets.Property)] | |
public class PropertyDefault : OnMethodInvocationAspect | |
{ | |
private enum AccessorType | |
{ | |
Get, | |
Set | |
} | |
// a place to store the parameters passed to the property | |
private object[] _parameters; | |
// gonna need at least an empty parameter collection | |
public PropertyDefault() : this(new Type[]{}) | |
{ } | |
// save the parameters | |
public PropertyDefault(params object[] parameters) | |
{ | |
_parameters = parameters; | |
} | |
// named parameter to support either a direct assignment or | |
// a backup plan if reflection fails to find a valid constructor | |
// on your object | |
public object DefaultValue { get; set; } | |
public override void OnInvocation(MethodInvocationEventArgs eventArgs) | |
{ | |
// make sure eventArgs isn't null | |
if (eventArgs == null) return; | |
// if the accessor type is set, just go ahead and execute the method | |
if (GetAccessorType(eventArgs.Delegate.Method) == AccessorType.Set) | |
{ | |
base.OnInvocation(eventArgs); | |
return; | |
} | |
// if it's the get accessor, get the current value | |
eventArgs.ReturnValue = eventArgs.Delegate.DynamicInvoke(eventArgs.GetArgumentArray()); | |
// if the current value isn't null, return the value | |
if (eventArgs.ReturnValue != null) return; | |
// otherwise, get the default value | |
eventArgs.ReturnValue = GetDefaultObject(eventArgs.Delegate.Method.ReturnType); | |
// now that we have the value, we need to make sure | |
// we store the reference to it so we take our new | |
// result and assign it to our property | |
Type target = eventArgs.Delegate.Target.GetType(); | |
PropertyInfo property = target.GetProperty(eventArgs.Delegate.Method.Name.Substring(5)); | |
property.SetValue(eventArgs.Delegate.Target, eventArgs.ReturnValue, null); | |
} | |
private object GetDefaultObject(Type type) | |
{ | |
// if you specified a default value only, then | |
// you probably want that value back instead of | |
// the empty constructor | |
if (_parameters.Length == 0 && DefaultValue != null) | |
return DefaultValue; | |
// get the array of types from the parameters you specified | |
// to try to find a valid constructor | |
Type[] types = (from p in _parameters | |
select p.GetType()).ToArray(); | |
// get the constructor with the type array | |
ConstructorInfo constructor = type.GetConstructor(types); | |
// if there's not a valid constructor then go with | |
// the backup plan (i.e., DefaultValue) | |
if (constructor != null) | |
return constructor.Invoke(_parameters); | |
return DefaultValue; | |
} | |
private AccessorType GetAccessorType(MethodInfo method) | |
{ | |
// the tilde is put there by postsharp | |
// the get_ and set_ are put there by c sharp | |
if (method.Name.StartsWith("~get_")) | |
return AccessorType.Get; | |
else if (method.Name.StartsWith("~set_")) | |
return AccessorType.Set; | |
else throw new Exception("Unknown method type for property accessor."); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment