Dynamic reflection versus static reflection

Since the very beginning the new Fluent NHibernate framework which provides an internal DSL for mapping the domain entities to the underlying database has attracted me very much. Why?

The standard way in NHibernate to map an entity to an underlying table is by defining an XML mapping document. These documents are often written by the developer but can also be generated by some tool. It is a very flexible way to accomplish the mapping.

On the other hand Fluent NHibernate uses what is called static reflection to do the mapping. Lambda functions and expression trees are used to obtain the desired result. This has some advantages over the mapping via XML documents since

  • it supports intellisense
  • refactoring is supported
  • it is wrist friendly
  • etc.

If you have a hard time with delegates, anonymous methods, lambda expressions and the like you might have a look at this post where a provide a step-by-step introduction to these concepts.

Reflection

Reflection can be defined as any functionality offered by a programming system that allows the programmer to inspect and manipulate code entities without knowing their identification or formal structure ahead of time. Inspection entails analyzing objects and types to gather structured information about their definition and behavior. Typically this is done with little or no prior knowledge about them, apart from some basic provisions.

Manipulation uses the information gained through inspection to invoke code dynamically, create new instances of discovered types, or even restructure types and objects on the fly.

Dynamic reflection

Dynamic Reflection or what I would also call it “Classical Reflection” accesses the meta information of the types and members accessible via the Type class. Each object has a method GetType() through which I can get access to the meta data of the respective type. Another possibility is to use the typeof(ClassName) function to get access to the meta data of a type.

Specific members (methods, constructors, properties and fields) or types (classes, interfaces, structs, enums) are identified by their name. Some times it’s the fully qualified name and some times just the name is enough. If I want to access the meta information of an interface ISomeInterface defined in the namespace SomeNamespace in an assembly SomeAssembly.dll I could do this like this

var assembly = Assembly.LoadFrom("SomeAssembly.dll");
var type = assembly.GetType("SomeNamespace.ISomeInterface");

Note that one of the major problems of code like this is the use of so called magic strings. I have to identify the type or member for which I want to get the meta information via a string. This is problematic since it is not refactor-friendly. Imagine what happens if I rename the Interface ISomeInterface to IOtherInterface. The above code would break since the content of the string is not automatically refactored.

On the other hand is dynamic reflection not supported by intellisense!

Example using Dynamic Reflection

As an example let’s assume that we have an entity with several properties. We now want to write a service which can map specific properties of this entity to an XML fragment. We want to keep this mapping function as generic as possible and thus decide to use reflection for it. We then come up with the following method

public void Map<T>(T entity, string propertyName, TextWriter writer)
{
    var propertyInfo = typeof (T).GetProperty(propertyName);
    var value = propertyInfo.GetValue(entity, null);
    writer.WriteLine("<node name="{0}">{1}</node>", propertyInfo.Name, value);
}

I have a generic method which expects an entity of type T as it’s first parameter. The property of the entity we want to map is given by it’s name. And the output should be written to the text writer passed in as a parameter.

The body of the method is straight forward. No magic is involved. First I get the PropertyInfo object for the requested property. Then I extract the value of the property via the GetValue method of the PropertyInfo object. Finally I generate the XML fragment and write it to the text writer.

Assume I have the following entity

public class SampleEntity
{
    public int Id { get; set; }
    public string Name { get; set; }
    public DateTime StartDate { get; set; }
}

then code to map this entity by using the above Map method will look similar to this

var builder = new StringBuilder();
using (var writer = new StringWriter(builder))
{
    mapper.Map(entity, "Id", writer);
    mapper.Map(entity, "Name", writer);
    mapper.Map(entity, "StartDate", writer);
    Console.WriteLine(builder); 
}

and the output produced is

<node name="Id">2</node>
<node name="Name">foo</node>
<node name="StartDate">14.04.1964 00:00:00</node>

To summarize: statements like the following

mapper.Map(entity, "Id", writer);

use magic strings which is bad. And there is no intellisense provided to me when writing such code. Typos are not detected early (TDD helps here a lot to immediately detect such errors!).

Static reflection

Static Reflection gathers meta information through the inspection of the Expression Tree.

Instead of using magic string like in the sample above (and again shown here)

mapper.Map(entity, "Name", writer);

I would rather prefer to write something similar to this

mapper.Map(entity, e => e.Name, writer);

Instead of a magic string I have used a Lambda Expression e => e.Name. Since the introduction of C# 3.0 we have the so called Lambda Expression which is nothing else than an anonymous delegate just much less verbose.

How can I achieve this? I first change the signature of my mapping method to look like this

public void Map<T>(T entity, Expression<Func<T, object>> expression, TextWriter writer)

The significant difference lies in the second parameter which is now an expression instead of a string as before. It’s an expression of a delegate. This time the delegate has a single parameter of type T and returns an object.

Now let me also show the body of the mapping method

public void Map<T>(T entity, Expression<Func<T, object>> expression, TextWriter writer)
{
    var memberExpression = GetMemberExpression(expression);
    var propertyInfo = memberExpression.Member as PropertyInfo;
    var func = expression.Compile();
    var value = func(entity);
    writer.WriteLine("<node name="{0}">{1}</node>", propertyInfo.Name, value);
}

It’s definitely more complex than our first method which is using dynamic reflection. But that’s not a problem since we are writing this code only once but make our life much more agreeable when using it compared to the first method.

The first line of the method extracts the member expression from the passed expression. I will discuss the method GetMemberExpression in detail later on. Once we have the member expression we can get the PropertyInfo object from it as done in the second line. Now we just need the value of the property we want to map. For this we can take the Lambda expression. But wait, we first have to compile our expression to get the Lambda function which we then call to get the property value.

Now let’s have a look at the GetMemberExpression method. This is a helper method to extract the MemberExpression from the given expression (I did steal it from the Fluent NHibernate code base).

private MemberExpression GetMemberExpression<T>(Expression<Func<T, object>> expression)
{
    MemberExpression memberExpression = null;
    if (expression.Body.NodeType == ExpressionType.Convert)
    {
        var body = (UnaryExpression)expression.Body;
        memberExpression = body.Operand as MemberExpression;
    }
    else if (expression.Body.NodeType == ExpressionType.MemberAccess)
    {
        memberExpression = expression.Body as MemberExpression;
    }
    if (memberExpression == null)
    {
        throw new ArgumentException("Not a member access", "member");
    }
    return memberExpression;
}

The code to map an entity by using static reflection looks similar to this

var builder = new StringBuilder();
using (var writer = new StringWriter(builder))
{
    mapper.Map(entity, e => e.Id, writer);
    mapper.Map(entity, e => e.Name, writer);
    mapper.Map(entity, e => e.StartDate, writer);
    Console.WriteLine(builder);
}

and as shown in the following image – intellisense is fully supported – which is a huge benefit

intellisense

Summary

I briefly described what reflection is and then introduced the dynamic reflection with it’s use of magic strings. The usage is shown with a simple example. This dynamic reflection is contrasted with the static reflection where no magic strings are used but rather lambda expressions. The same sample is refactored and the usage of static reflection is shown.

Related Articles:

Post Footer automatically generated by Add Post Footer Plugin for wordpress.

About Gabriel Schenker

Gabriel N. Schenker started his career as a physicist. Following his passion and interest in stars and the universe he chose to write his Ph.D. thesis in astrophysics. Soon after this he dedicated all his time to his second passion, writing and architecting software. Gabriel has since been working for over 12 years as an independent consultant, trainer, and mentor mainly on the .NET platform. He is currently working as chief software architect in a mid-size US company based in Austin TX providing software and services to the pharmaceutical industry as well as to many well-known hospitals and universities throughout the US and in many other countries around the world. Gabriel is passionate about software development and tries to make the life of developers easier by providing guidelines and frameworks to reduce friction in the software development process. Gabriel is married and father of four children and during his spare time likes hiking in the mountains, cooking and reading.
This entry was posted in introduction, lambda expressions, reflection. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • http://scottcreynolds.lostechies.com Scott

    dude, you’re a machine

  • http://blog.kamstrup-linnet.dk Jesper Kamstrup Linnet

    Yeah, you are approaching the number one position on my list of favorite bloggers. Please, please, more posts of this quality!

  • http://mailto:sendtomikesmith@gmail.com Michael A. Smith

    Genius. This is new to me. Much thanks.

  • http://www.lostechies.com/members/gnschenker/default.aspx Gabriel N. Schenker

    @Jesper: I have more to come. Hold on!

  • http://neilmosafi.blogspot.com Neil Mosafi

    I’ve usually just done

    ((MemberExpression) expression.Body).Member.Name

    To get the name of the property. Can you explain what the other code is trying to achieve?

  • Mike

    Excellent post :)

  • Tom

    Hi Gabriel, excellent post. But I wonder, is there any other use for this construction other than mapping properties?

    Could you elaborate on that one?

    KR,
    Tom

  • http://www.lostechies.com/members/gnschenker/default.aspx Gabriel N. Schenker

    @Tom: there is an “infinite” number of possibilities for what static reflection can be used. A good example is code generation (e.g. HTML snippets –> see the FubuMVC project on Google Code). Another example is the mapping of entities to database tables as shown by “Fluent NHibernate”

  • ThorHalvor

    Hi,
    Tnx for some great posts! I have added you to my top 10 list now ;)
    - I would like to point out that the link to the “lamda-explanation-post” is incorrect.Both from this post and some of the other posts you got. there is a typo in the url “/blogs/gabrielschenker/blogs/gabrielschenker/archive/”.

    TH

  • john

    very nice, i wish java had this, we have the magic strings =/

  • raj

    Nice one…

    Is static reflection faster than dynamic reflection? Do you have any idea?

  • Xor

    Hi,
    I loved the way you explain it in a clearer way.

    mapper.Map(entity, “Name”, writer);
    mapper.Map(entity, e => e.Name, writer);

    I have a question,
    If I know the entity type then I should know it’s member I am trying to get value of. If I am unsure of the name of the member I do type “entity”(as in example) and press dot in visual studio to get the list of available members using intellisense , so Magic string is not a big problem

    I would be more than happy to know what are the application areas of the Static reflection, and I hope you write them
    Thank you very much.

  • http://www.lostechies.com/members/gnschenker/default.aspx Gabriel N. Schenker

    @Xor: where ever you don’t want to use “magic” strings you use static reflection. Examples of well known projects are
    -Fluent NHibernate, NHibernate 3.0 (trunk uses static reflection to define criteria queries), FuBu MVC, Fluent Silverlight and others

  • http://www.lostechies.com/members/gnschenker/default.aspx Gabriel N. Schenker

    @raj: I have not done any research about the performance of the two approaches. But in my experience the performance usually is not an issue wherever I use static reflection… But the increased robustness of the code is a clear benefit

  • Mark C

    I think that referring to the use of lambda expressions as static reflection is a bit of a misnomer. While you gain the advantage of not using magic strings, the actual lambda function is generated dynamically by the expression.Compile() method (which, IIRC, uses Reflection.Emit under the hood).

  • Michael Freidgeim

    According to http://stackoverflow.com/questions/7061237/static-reflection-performance static reflection is slower than classic one.