How to customize a reflection context to override default reflection behavior?

We can achieve this using CustomReflectionContext class. provides a way for you to add or remove custom attributes from reflection objects, or add dummy properties to those objects, without re-implementing the complete reflection model. The default CustomReflectionContext simply wraps reflection objects without making any changes, but by subclassing and overriding the relevant methods, you can add, remove, or change the attributes that apply to any reflected parameter or member, or add new properties to a eflected type.

For example: suppose the code follows the convention of applying a particular attribute to factory methods, but we are now required to work with third-party code that lacks attributes. We can use CustomReflectionContext to specify a rule for identifying the objects that should have attributes and to supply the objects with those attributes when they are viewed from our code. 

Note: To use CustomReflectionContext effectively, the code that uses the reflected objects must support the notion of specifying a reflection context, instead of assuming that all reflected objects are associated with the runtime reflection context. Many reflection methods in the .NET Framework provide a ReflectionContext parameter for this purpose.
To modify the attributes that are applied to a reflected parameter or member, override the GetCustomAttributes(ParameterInfo, IEnumerable) or GetCustomAttributes(MemberInfo, IEnumerable) method. These methods take the reflected object and the list of attributes under its current reflection context, and return the list of attributes it should have under the custom reflection context.

//A blank example attribute.
class myAttribute : Attribute
{
}
//Reflection context with custom rules.
class myCRC : CustomReflectionContext
{
//Called whenever the reflection context checks for custom attributes. 
protected override IEnumerable<object> GetCustomAttributes(MemberInfo member, IEnumerable<object> declaredAttributes)
{
//Add example attribute to "To*" members.
if (member.Name.StartsWith("To")) 
{
yield return new myAttribute();
}
//Keep existing attributes as well.
foreach (var attr in declaredAttributes) yield return attr;
}
}
class Program
{
static void Main(string[] args)
{
myCRC mc = new myCRC();
Type t = typeof(String);
//A representation of the type in the default reflection context.
TypeInfo ti = t.GetTypeInfo();
//A representation of the type in the customized reflection context.
TypeInfo myTI = mc.MapType(ti);
//Display all the members of the type and their attributes.
foreach (MemberInfo m in myTI.DeclaredMembers)
{
Console.WriteLine(m.Name + ":");
foreach (Attribute cd in m.GetCustomAttributes())
{
Console.WriteLine(cd.GetType());
}
}
Console.WriteLine();
//The "ToString" member as represented in the default reflection context.
MemberInfo mi1 = ti.GetDeclaredMethods("ToString").FirstOrDefault();
//All the attributes of "ToString" in the default reflection context.
Console.WriteLine("'ToString' Attributes in Default Reflection Context:");
foreach (Attribute cd in mi1.GetCustomAttributes())
{
Console.WriteLine(cd.GetType());
}
Console.WriteLine();
//The same member in the custom reflection context.
mi1 = myTI.GetDeclaredMethods("ToString").FirstOrDefault();
//All its attributes, for comparison. myAttribute is now included.
Console.WriteLine("'ToString' Attributes in Custom Reflection Context:");
foreach (Attribute cd in mi1.GetCustomAttributes())
{
Console.WriteLine(cd.GetType());
}
Console.ReadLine();
}
}

Need Help? Contact Us.

Log in

*
*

Forgot password?

*

New User

*
*
*
*