Saturday, November 8, 2008

Use expression tree to avoid string literals in reflecting code part 2 (WorkflowArguments, WorkflowOutputParameters, Mapper)

Last time I was writing about a utility class called ReflectionHelper, this time I'll show you two real scenarios where this class or just expression tree have been used.

For last couple of months I've been working on a project built on the top of Workflow Foundation. Now we have C#3.0 many thinks can be done smarter, simpler, quicker, better or ... more cool ;) Let's look at a simple workflow class:

class MyWorkflow : SequentialWorkflowActivity
{
    public int MyInt { get; set; }
    public string MyString { get; set; }            

    public MyWorkflow()
    {
        CodeActivity codeActivity = new CodeActivity("codeActivity1");
        codeActivity.ExecuteCode += delegate
        {
            Console.WriteLine("MyInt : " + MyInt);                    
            Console.WriteLine("MyString : " + MyString);
            MyInt++;
            MyString = "yo";
        };
        Activities.Add(codeActivity);
    }
}

I know that not all of you had the opportunity to use WF so I'll try to give you some basics. The most elementary component in WF is an activity. We can say that activity is just a class with 'Excute' method responsible for doing some action. Workflow process is also an activity containg another activities which are executed one by one (that's why it derives from SequentialWorkflowActivity). Our workflow has only one activity CodeActivity which raises ExecuteCode event when it's executed. Additionally our process manipulates its state stored in properties MyInt and MyString. Let's see how to start this process and initialize its state:

using (WorkflowRuntime workflowRuntime = new WorkflowRuntime())
{                
    var arguments = new Dictionary<string, object>()
        {
            {"MyString", "hello"},
            {"MyInt", Math.Max(5, 10)},
        };

    WorkflowInstance instance = workflowRuntime.CreateWorkflow(typeof(MyWorkflow), arguments);
    instance.Start();
}

The problem is that method CreateWorkflow takes a dictionary where the key is a property name and the value is a value of the property. But what if someone changes the name or the type of the property someday ? The code will compile fine but at runtime we will get an exception. Since we have C#3.0 we can very easily resolve these two problems.

var arguments = new WorkflowArguments<MyWorkflow>()
{
    { w => w.MyString, "hello" },
    { w => w.MyInt, Math.Max(5,10) }
};

WorkflowInstance instance = workflowRuntime.CreateWorkflow(typeof(MyWorkflow), arguments);

public class WorkflowArguments<TWorkflow> : Dictionary<string,object>
{
    public WorkflowArguments<TWorkflow> Add<T>(Expression<Func<TWorkflow, T>> property,
        T propertyValue)
    {
        var propertyInfo = Blog.Post002.ReflectionHelper.GetProperty<TWorkflow,T>(property);
        Add(propertyInfo.Name, propertyValue);
        return this;
    }
}

The same technique we be used to process parameters after execution.

static void workflowRuntime_WorkflowCompleted(object sender, WorkflowCompletedEventArgs e)
{
    Console.WriteLine("workflowRuntime_WorkflowCompleted");
    var parameters = new WorkflowOutputParameters<MyWorkflow>(e.OutputParameters);

    Console.WriteLine(parameters.GetParameter( w => w.MyInt));
    Console.WriteLine(parameters.GetParameter( w => w.MyString));            
} 

public class WorkflowOutputParameters<TWorkflow> 
{           
    private Dictionary<string, object> Parameters { get; set; }
    
    public WorkflowOutputParameters(Dictionary<string, object> parameters)
    {           
        Parameters = parameters;
    }

    public T GetParameter<T>(Expression<Func<TWorkflow, T>> property)
    {
        var propertyInfo = Blog.Post002.ReflectionHelper.GetProperty<TWorkflow, T>(property);
        return (T)Parameters[propertyInfo.Name];
    }
}

The second example is a Mapper class. It's a quite common scenario when we map instance of class A into instance of class B. For example, we very often load some kind of DAL entity from database into memory then we map it to some kind of business entity. In many cases the shape of both types if very similar, they have the same properties/fields so the mapping code is very simple. It just transfers values of properties or fields from one object to another. Mapper class is a very simple class giving us the ability to record the mapping of two types to each other. Next we can execute mapping process specifying two instances of those classes and the direction of mapping. Lets assume that we have two types:

class CustomerDal
{
    public int Id { get; set; }
    public string Name { get; set; }
    public double Age { get; set; }            
    public char Gender { get; set; }
    public string City { get; set; }
    public string Street { get; set; }
}

class CustomerBO
{
    public int Id { get; private set;  }    // only getter
    public string Name { get; set; }        // exactly the same name
    public double Age;                      // field
    public char Sex { get; set; }           // another name
    public string Address { get; set; }     // more complicated mapping
}

Now we want to map an instance of CustomerDal type to instance of CustomerBo. Firstly we need to define how the properties of types should be transformed. Once we have it we can start mapping.

var m1 = new Mapper<CustomerDal, CustomerBO>    // A type, B type
  {
      {a => a.Id, b => b.Id, Direction.A2B},    // member of type A, member of type B, mapping direction
      {a => a.Name, b => b.Name},               // by default map in both directions
      {a => a.Age, b => b.Age},                  {a => a.Gender, b => b.Sex},
      { (a, b, d) => b.Address = a.City + " " + a.Street , Direction.A2B} 
        // code snippet executed during mapping
  };
      
var customerDal = new CustomerDal { Id = 1, Name = "Michael", 
    City = "Chicago", Street = "W Washington", Age = 25, Gender = 'M'};
    
var customerBO = new CustomerBO();
m1.Map(customerDal, customerBO);

customerBO.Name = customerBO.Name + "!";
customerBO.Sex = 'F';
customerBO.Age = customerBO.Age + 1;
         
m1.Map(customerBO, customerDal);

Again, instead of specifying mapped properties in code as string literals we use expression trees. Using expression trees is safer, cleaner and much more powerful. I showed you just two examples of real life application of ExpressionTrees that goes for beyond Linq. You saw the potential. Now imagine what you can do in your project with it.

The source code for both examples you can be found here.

Use expression tree to avoid string literals in "reflecting code" (ReflectionHelper)

Reflection is a very useful mechanism letting us build very smart and flexible solutions. It is used in many places in .Net framework, for instance in Windows Forms to identify bound members or in Workflow Foundation to pass some parameters to workflow instance and many others. Those two samples have one common thing, we have to use string literals in code to identify type members such as properties. And of course it's not a problem if the types we use are not changing, it means once specified, member won't be changed in the future. Like which shouldn't change like .net framework types (it shouldn't be change cause of backward compatibility).

Lets imagine that we bind one property of our business object to a TextBox's property Text and one day during refactoring someone else changes the name or the type of the property or even worse - deletes it. The code will compile correctly but we can't be sure how it will work at runtime because it depends on the sort of change. Maybe some exception will be thrown, maybe everything will look fine but the property won't be set after modifying text in the TextBox or maybe all will work just fine. Such bugs are very unpredictable and very hard to find. Wouldn't it be nice if we could know just after change about possible problems (compilation failed). Sometimes we know than the property is used in many places in the code, so we rename it via our IDE (for instance in Visual Studio we can choose option 'Refactor -> Rename...') and we want be sure that everything works fine. Is this possible ?

Today I'll show you a utility class called ReflectionHelper giving us the ability to realize mentioned scenario. Currently when we extract information about property via reflection we write something like this:

public class SomeClass
{
    public int InstanceProperty { get; set; }
    public static int StaticProperty { get; set; }
}

PropertyInfo property1 = typeof(SomeClass).GetProperty("InstanceProperty");
PropertyInfo property2 = typeof(SomeClass).GetProperty("StaticProperty");

With ReflectionHelper the same code can be written like this:

PropertyInfo property3 = ReflectionHelper.GetProperty((SomeClass o) => o.InstanceProperty );            
PropertyInfo property4 = ReflectionHelper.GetProperty(() => SomeClass.StaticProperty);

This is exactly what we wanted to achieve. We have created instance of PropertyInfo class without using any string literals. Now when we manually change the name of a property in one place, the code won't compile. If you rename it by 'Rename...' option in VS, code inside lambda expression will be changed too.

Now, lets see how ReflectionHelper works. ReflectionHelper is a static class with 2 methods extracting information about given property. One for static properties and one for instance. The implementation is quite short and looks like this:

public static PropertyInfo GetProperty<TObject,T>(Expression<Func<TObject,T>> p) 
{ 
    return GetPropertyImpl(p); 
}
public static PropertyInfo GetProperty<T>(Expression<Func<T>> p) 
{ 
    return GetPropertyImpl(p); 
}
private static PropertyInfo GetPropertyImpl(LambdaExpression p)
{
    return (PropertyInfo)((MemberExpression)(p.Body)).Member;
}

The key point to understand how the code works is a new feature of C#3.0 called expression trees. In new version of C# we can use lambda expression in code. There are two kinds of lambda expression where the body of the method is a single expression ( x => x.ToString() ) or one or many statements (x => {return x.ToString(); } ).

Func<int, int> expressionBody = (a) => a + 1;
Func<int, int> statementBody = (a) => { return a + 1; };

In many places we use lambda with single expression body just because it's shorter but there is a scenario when we have to use it. Generally when compiler sees lambda expression in code it's treated as an anonymous method, but lambda expression can be also used to build expression trees. Lets look at the example:

Expression<Func<int, int>> exp1 = (a) => a + 1;
Expression<Func<int, int>> exp2 = (a) => { return a + 1; }; 
// Error: A lambda expression with a statement body cannot be converted to an expression tree

Ok, but what is an expression tree actually? When compiler sees lambda with expression body not in the context of delegate type but in the context of special generic type 'System.Linq.Expressions.Expression<TDelegate>' a lot of code is generated behind the scenes.

ParameterExpression p;
Expression<Func<int, int>> exp1 = Expression.Lambda<Func<int, int>>
(
    Expression.Add // body
    (
        p = Expression.Parameter(typeof(int), "a"),
        Expression.Constant(1, typeof(int))
    ),
    new ParameterExpression[] { p } // parameters
);

The code of lambda expression is interpreted and translated into code that actually builds its structure. Use 'Expreesion Tree Visualizer' to better visualize the structure of expression tree.

When we look back to implementation of GetProperty method we can see that it takes an expression tree as a parameter. Inside the the method we make some assumptions about the structure of tree so we know exactly where information about property is stored. Of course if the structure of the tree would look differently, some exception could be thrown. The same technique can be used to extract information about fields, methods and constructors (ReflectionHelper has appropriate functionality). In case of getting information about the methods there are different ways of doing it.

public class SomeClass
{
    public void InstanceMethod(int i) { }
}

Instead of writing literal call

var method = typeof(SomeClass).GetMethod("InstanceMethod");

use ReflectionHelper like this:

var method = ReflectionHelper.GetMethod<SomeClass,int>(o => o.InstanceMethod);

or like this:

var method = ReflectionHelper.GetMethodByCall<SomeClass>(o => o.InstanceMethod(1));

The implementation looks like this:

public class ReflectionHelper
{    
    public static MethodInfo GetMethodByCall<TObject>(Expression<Action<TObject>> expression) 
    { 
        return GetMethodByCallImpl(expression); 
    }
    public static MethodInfo GetMethodByCall(Expression<Action> expression) // for static methods 
    { 
        return GetMethodByCallImpl(expression); 
    }
    private static MethodInfo GetMethodByCallImpl(LambdaExpression expression)
    {
        return ((MethodCallExpression)expression.Body).Method;
    }    
    
    public static MethodInfo GetMethod<TObject, T>(Expression<Func<TObject, Action<T>>> expression) 
    { 
        return GetMethodImpl(expression); 
    }
    public static MethodInfo GetMethod<T>(Expression<Func<Action<T>>> expression) // for static methods 
    { 
        return GetMethodImpl(expression); 
    }
    private static MethodInfo GetMethodImpl(LambdaExpression expression)
    {
        return (MethodInfo)((ConstantExpression)((MethodCallExpression)((UnaryExpression)expression.
            Body).Operand).Arguments.Last()).Value;
    }
}

When we use GetMethod method we don't need to write methods parameters inside brackets but we need to provide their types as generic method arguments (if parameters exist or method returns something). In the second approach we just write code executing method inside lambda expression. The code is never executed so we don't have to pass any correct arguments. These two approaches have one common disadvantage. When we change the signature of the method by changing parameters or return type, we need to change the code reflecting that method too. Maybe there is some solution but I couldn't find it :(

Full implementation of ReflectionHelper class with code presenting many different scenarios of using them can be found here. In the next post I'll show you how the ReflectionHelper is used in real life :) Stay tuned!

Thursday, September 25, 2008

XmlContentLoader

As a subject of my first technical post I've chosen a small utility class built on the top of Linq. I have a pleasure to work with this really useful and powerful .Net Framework 3.5 feature which is Linq. It's quite possible that in next few posts I'll be writing about many issues related to Linq (LinqToXml, new C#3.0 in action and many others...)

Few weeks ago my team got a task to build very simple wizard application based on Windows Forms. The main goal of the wizard was to free end-users from doing configuration our applications by editing configuration files by hand. It was really straightforward, 4 or 5 step wizard basically giving ability to set some connection strings, email server settings and some WCF stuff. My part of the task was to prepare a component responsible for loading and saving selected xml elements or attributes from configuration file. As you can imagine the file was pretty big but we needed to change only some parts of them.

I decided to build more general-purpose component which I called XmlContentLoader. Firstly I'll show you sample scenario of using it, than some interesting parts of the realization.

Assume than we have xml file looking like this:

<Root>
   <A>some string...</A>
   <AA>
       <AAA>yo</AAA>
   </AA>
   <B>true</B>
   <BB></BB>
   <C>
       <C1 c1Attribute="some string..." >1</C1>
   </C>
   <D dAttribute="2008.02.02">
   </D>
</Root>

Now we want to load some parts of the file into memory, change it and save back to file. Assume than we want to write as little code as possible.

So we create the class (or structure) responsible for holding data from xml file (please note that the class can already exist in our application) containing properties corresponding to appropriate xml file items (elements or attributes). The xml item is chosen by defining xpath query returning xml element and optional attribute name (in case of choosing xml attribute).

internal class XmlContentLoaderTest
{
   [XmlItem(@"/Root/A[1]")]
   [XmlItem(@"/Root/C/C1", "c1Attribute")]
   public string MyString { get; set; }

   [XmlItem(@"/Root/B[1]")]
   public bool MyBool { get; set; }

   [XmlItem(@"/Root/D[1]", "dAttribute")]
   public DateTime MyDateTime { get; set; }

   [XmlItem(@"/Root/C[1]/C1[1]")]
   public Decimal MyDecimal { get; set; }
}

As you can see above one property can be mapped to many xml items. Once we have the data structure, we can load, modify and save xml file content.

string filePath = "...";
var a = XmlContentLoader.Load<XmlContentLoaderTest>(filePath);

a.MyBool = !a.MyBool;
a.MyString = a.MyString + ".";
a.MyDecimal = a.MyDecimal + 1;
a.MyDateTime = a.MyDateTime.AddDays(1);

XmlContentLoader.Save(filePath, a);

It's all we can do with XmlContentLoader. Now let's see some details of the implementation.

XmlContentLoader has only 3 public methods.

public static T Load<T>(string filePath)
   where T : new()
{
   return Load(filePath, new T());
}

public static T Load<T>(string filePath, T @object)
{
   if (!File.Exists(filePath))           
       throw new FileNotFoundException(string.Format("File {0} does not exist", filePath));

   XDocument document = XDocument.Load(filePath);
   foreach (var p in GetPropertyToXmlItemsMappings(@object, document,
       new { Property = Type<PropertyInfo>(), XmlItems = Type<XmlItem[]>() }))
   {
       p.Property.SetValue(@object,
           Converters[p.Property.PropertyType].ConvertFromString(p.XmlItems.First().Value),
           null);
   }

   return @object;
}

public static void Save(string filePath, object @object)
{
   if (!File.Exists(filePath))           
       throw new FileNotFoundException(string.Format("File {0} does not exist", filePath));

   XDocument document = XDocument.Load(filePath);
   foreach (var p in GetPropertyToXmlItemsMappings(@object, document,
       new { Property = Type<PropertyInfo>(), XmlItems = Type<XmlItem[]>() }))
   {
       object propertyValue = p.Property.GetValue(@object, null);
       foreach (var c in p.XmlItems)
           c.Value = Converters[p.Property.PropertyType].ConvertToString(propertyValue);
   }

   document.Save(filePath);
}


private static Dictionary<Type, TypeConverter> Converters { get; set; }

private static T Type<T>()
{
   return default(T);
}

The implementation of both Load and Save methods is very similar. We load xml document content into the memory using XElement class (added in new LinqToXml API in .Net3.5), then we just iterate throught collection of items returned from GetPropertyToXmlItemsMappings method. Each loop iteration sets new property value or gets the value from property and stores in xml document object structure. What's worth notice, we use TypeConverter class to provide convertion between Syste.String type and property type.

We don't know yet what is the type of the collection item :) So let's see the implementation of GetPropertyToXmlItemsMappings method.

private static T[] GetPropertyToXmlItemsMappings<T>(object @object, XNode document,
   T mappingTypeShape)
{
   var q =
       from p in @object.GetType().GetProperties()
       where Attribute.IsDefined(p, typeof(XmlItemAttribute)) &&
             StoreTypeConverter(p.PropertyType) != null // check if type has TypeConverter
       select new
       {
           Property = p,
           XmlItems =
           (
               from XmlItemAttribute a in Attribute.GetCustomAttributes(p,
                   typeof(XmlItemAttribute))
               select GetXmlItem(document, a)
           ).ToArray() // Force execution 'GetXmlItem()' method 
                       // (check if all specified xml items exist)
       };

   return q.Cast<T>().ToArray(); // Force execution 'GetXmlItem()' method 
                                 // (check if all specified xml items exist)
}

private static XmlItem GetXmlItem(XNode document, XmlItemAttribute a)
{
   return a.IsAttribute
              ? new XmlItem(ExtractAttribute(document, a.ElementPath, a.AttributeName))
              : new XmlItem(ExtractElement(document, a.ElementPath));
}

internal class XmlItem
{
   private XElement Element { get; set; }
   private XAttribute Attribute { get; set; }
   internal string Value
   {
       get
       {
           if (Element != null)
               return Element.Value;
           return Attribute.Value;
       }
       set
       {
           if (Element != null)
               Element.Value = value;
           else
               Attribute.Value = value;
       }
   }

   public XmlItem(XElement element)
   {
       Element = element;
   }
   public XmlItem(XAttribute attribute)
   {
       Attribute = attribute;
   }
}

ReSharper is so smart to tell me: "Parameter 'mappingTypeShape' is never used". So, what for did I add it to the method signature ? Is it really needed or not? Yes, it is. Because I wanted to use an anonymous type inside the method body instead of defining additional type myself (what for if compiler can do that for me ? ;) ) but outside of the method I needed to know the type of collection item. I had to specify somehow the type. But how ? it's an anonymous type. I gave exactly the same type shape as I did inside the method. The compiler is smart enough to use the same generated anonymous type. Don't ask me why I did it this way ... :)

I think XmlContentLoader can be very useful utility when you need to change only some parts of xml file in typed way without necessity to use xml serialization. Additionally when you use PropertyGrid control you can build pretty nice application in just few lines of code.

You can find source code here.

Friday, September 12, 2008

Introduction

I'd like to welcome you on my blog!
I have been thinking about blogging since last couple of months. Now the time has come and I'm here :)
At the beginning I'll introduce myself and try to explain why I'have just started this blog.
My name is Marcin Najder, I work as a software developer in one of the biggest Polish companies. Mostly I work with newest Microsoft technologies such as VS2008, Sql Server 2008 and many, many other useful tools and frameworks. Just about those technologies I'm going to write. There are 2 main reasons for my blog:
  • Blog as a place for improving my english. This is the first and foremost reason,
  • In my day to day work I'm very often looking for solutions to many different problems. Many of them I find on blogs on the web. Maybe I'll be able to give you my solutions for your problems. It's all about sharing knowledge...
I think it's enough for the first post. :) See you next time!