Skip to main content

Reflection API Changes in .NET 4.5 Applications and Fun with Custom Reflection Context

imageBefore .NET 4.5, as you are aware, the Type class in System namespace was used for most of the reflection scenarios. Though you can use Type class to inspect meta data, this is really heavy weight. As most reflection scenarios are just read only (for example, using attributes for providing meta data etc),  Microsoft decided to introduce a light weight, alternate Type API as part of .NET Core profile. If you are wondering about different .NET profiles, here is a good list compiled together.

Type and TypeInfo

So to keep the long story short - in .NET 4.5 onwards, Type class got ‘shrunk’ to provide a shallow, high speed read only view of an object’s structure (definition). And TypeInfo class got introduced that contains the actual type definitions with more detailed information. See Type and TypeInfo – and check out the platform specific support for it’s members. You can read more about the Reflection API changes here

The TypeInfo class represents type definitions and the Type class represents type references. Given a Type object, you can get the name of the type as a string, without any requirement to load anything more. Alternatively, if you need rich information about a type, you can get a TypeInfo object from a Type object. 

In .NET full profiles used for desktop and web applications, the old Type API (Accessing everything through Type) is still available to maintain backward compatibility, along with the new Type API (TypeInfo etc). And For .NET Framework profiles for new platforms like WinRT that don’t need backward compatibility, Type class got shrunk by removing a number of members as discussed, and TypeInfo is the only way to dive deep into reflection. If you are writing code that should target multiple framework versions (as in Portable Class Libraries), you should use the new API. Otherwise, you can continue to use the old API as .NET framework versions on full profile actually returns the self contained Type object as previously.

Using TypeInfo

You may call GetTypeInfo on any type object as shown below to get the TypeInfo for a Type, and may use the new API (like DeclaredProperties) to traverse the members.

	//Get the basic type
        Type myType = "somestring".GetType();

        //Get more information about that type
        TypeInfo myTypeDetails = myType.GetTypeInfo();

        foreach(var prop in myTypeDetails.DeclaredProperties)
            {
                Console.WriteLine(prop.Name);
            }

Also, you may use TypeInfo to check the relations between types. For example, here is how to use IsAssignableFrom method of TypeInfo to determine variance.

  //Can I assign a string to an object - True
   var canAssignStringToObject = typeof (object).GetTypeInfo()
                                  .IsAssignableFrom(typeof (string));

  //Can I assign an object to a string - False
  var canAssignObjectToString = typeof(string).GetTypeInfo()
                                 .IsAssignableFrom(typeof(object));

Custom Reflection Context

Custom Reflection Context is a new addition in .NET 4.5, to customize how a consumer using the TypeInfo based new Reflection API views reflected information about your types. This will be extremely helpful when you write Libraries and design components that take advantage of meta data. This is much like customizing Type information using techniques like type descriptors. The new API provides run time virtualization over reflection, and looks quite intuitive - I wish this was there when we spend years writing custom tools for extending Visual Studio few years back, to virtualize type information for existing and new components.

You can override properties in CustomReflectionContext to add virtualized properties, custom attributes etc. For example, here is a quick PropertyAdder context that’ll inject some properties while accessed through the custom reflection context

.
    //Just a dummy Dog class
    //See that we don't have any properties
    class Dog
    {

    }

//A PropertyAdder context
    //To add custom properties to the reflection context
    class PropertyAdder : CustomReflectionContext
    {
        private readonly Dictionary _properties;

        public PropertyAdder(Dictionary properties)
        {
            _properties = properties;
        }

        protected override IEnumerable AddProperties(Type type)
        {
            if (type == typeof(Dog))
            {
                foreach (var p in _properties)
                {
                    yield return
                        CreateProperty(MapType(p.Value.GetType().GetTypeInfo()),
                                       p.Key,
                                       (o) => _properties[p.Key],
                                       (o, v) => _properties[p.Key] = v);
                }
            }
            else
            {
                base.AddProperties(type);
            }
        }
    }

And here is a quick example for using our PropertyAdder. Essentially,

  • We are creating a new instance of PropertyAdder
  • Then decorating our Dog class’s type information by mapping the type information via the custom reflection context.
  • Finally, we are creating an instance of Dog class, and look ma- we’ve got the properties via reflection

So, here we go.

    //Main Driver
    class Program
    {
        static void Main(string[] args)
        {

            //Properties we want to add
            var properties = new Dictionary
                {
                    {"Name", "Joe"},
                    {"Age", 10}
                };

            //An instance of our custom reflection context
            var adderContext = new PropertyAdder(properties);

            //Get the type in the default reflection context.
            var dogTypeInfo = typeof (Dog).GetTypeInfo();

            //Get the type in the customized reflection context.
            //We'll map the context with our PropertyAdder
            var customDogTypeInfo = adderContext.MapType(dogTypeInfo);


            //Just an instance
            var d = new Dog();

            //Display properties and values using custom reflection context. 
            foreach (var prop in customDogTypeInfo.DeclaredProperties)
            {

                //We'll really see the properties we added above
                Console.WriteLine("{0}={1}",prop.Name, 
                    customDogTypeInfo.GetProperty(prop.Name).GetValue(d));
            }

            Console.ReadLine();
        }
    }

And here is the output. You’ll see that we are accessing the properties we added via the reflection context. Here you go.

image

So this is fun especially when you work with libraries that leverage meta data and on the tooling side. For example, the RegistrationBuilder class in MEF 2.0 inherits custom reflection context to provide meta data based conventions that describes rules for decorating entities.

Happy Coding Smile. Also, see my other C# posts here

Popular posts from this blog

Top 7 Coding Standards & Guideline Documents For C#/.NET Developers

Some time back, I collated a list of 7 Must Read, Free EBooks for .NET Developers, and a lot of people found it useful. So, I thought about putting together a list of Coding Standard guidelines/checklists for .NET /C# developers as well.As you may already know, it is easy to come up with a document - the key is in implementing these standards in your organization, through methods like internal trainings, Peer Reviews, Check in policies, Automated code review tools etc. You can have a look at FxCop and/or StyleCop for automating the review process to some extent, and can customize the rules based on your requirements.Anyway, here is a list of some good Coding Standard Documents. They are useful not just from a review perspective - going through these documents can definitely help you and me to iron out few hidden glitches we might have in the programming portion of our brain. So, here we go, the listing is not in any specific order.1 – IDesign C# Coding StandardsIDesign C# coding stand…

5 Awesome Learning Resources For Programmers (To help you and your kids to grow the geek neurons)

Happy New Year, this is my first post in 2012. I’ll be sharing few awesome learning resources I’ve bookmarked, and will be pointing out some specific computer/programming related courses I've found interesting from these resources.Also, thought about saving this blog post for my kids as well - instead of investing in these Child education schemes (though they are too small as of today, 2 years and 60 days respectively ). Anyway, personally my new year resolution is to see as much videos from this course collections (assuming I can find some free time in between my regular job && changing my babies diapers).1 – Khan AcademyAs I mentioned some time back, you and your kids are missing some thing huge if you havn’t heard about Khan Academy.  It is an awesome learning resource, especially if you want to re-visit your basics in Math, Science etc.With a library of over 2,600 videos covering everything from arithmetic to physics, finance, and history and 268 practice exercises, th…

Hack Raspberry Pi – How To Build Apps In C#, WinForms and ASP.NET Using Mono In Pi

Recently I was doing a bit of R&D related to finding a viable, low cost platform for client nodes. Obviously, I came across Raspberry Pi, and found the same extremely interesting. Now, the missing piece of the puzzle was how to get going using C# and .NET in the Pi. C# is a great language, and there are a lot of C# developers out there in the wild who are interested in the Pi.In this article, I’ll just document my findings so far, and will explain how develop using C# leveraging Mono in a Raspberry Pi. Also, we’ll see how to write few minimal Windows Forms & ASP.NET applications in the Pie as well.Step 1: What is Raspberry Pi?Raspberry Pi is an ARM/Linux box for just ~ $30. It was introduced with a vision to teach basic computer science in schools. How ever, it got a lot of attention from hackers all around the world, as it is an awesome low cost platform to hack and experiment cool ideas as Pi is almost a full fledged computer.  More About R-Pi From Wikipedia.The Raspberry Pi