Wednesday, August 21, 2013

Homemade Lightweight Automapper Part 2

Again, please forgive any code mistakes. I've written this post up largely without the help of a compiler to help catch the bugs. The initial solution I came up with was some sort of case statement but after a few hours of research I came to the realization that C# simply doesn't support a case statements on types. A dictionary object was my next port of call. More specifically a Dictionary of Dictionaries. The nice thing about dictionaries in C# is that you can access them like arrays, using a key in place of the index. So a Dictionary of Dictionaries can be used the same way as a 2 dimensional array. In our case we want to use types as our keys so our dictionary syntax becomes:
dict[typeof(Source)][typeof(Dest)];
Linq syntax uses Func<TSource, TDest> for L2SQL and wraps it into a much less restricted Expression<...> for L2OBJs. It is really easy to pull the Func out of the Expression so our actual Projections are going be of type Expression<Func<TSource, TDest>>

Our key will be the destination type. Given that, our inner dictionary will need to be a dictionary of type:
IDictionary<TDest, Expression<Func<TSource, TDest>>>;
Where TDest is our Key and our Expression is our Value. If that looks ugly, it's because it is.

Our outer dictionary will need to hold our inner dictionary and be accessed by our source type, so it's type will be:
IDictionary<TSource, IDictionary<TDest, Expression<Func<TSource, TDest>>>>;
That is *really* ugly. Not to mention that our code isn't generic at all, and our dictionary object is strongly typed so it won't just accept actual types. It needs the more generic Type type. And for convenience sake, MS have included a non generic Expression class (which is as it turns out more generic.)
IDictionary<Type, IDictionary<Type, Expression>>;
That's about as nice as we're going to get in this case I think. There's not a whole lot we can do to clean that up. So what's the next best thing to getting rid of the dust in the house? Sweeping it under the rug! So what we want to do is abstract the nastiness away from the programmer.

Currently we can only set up our projection dictionary by doing something like the following:
IDictionary<Type, IDictionary<Type, Expression>> projections = new Dictionary<Type, Dictionary<Type, Expression>>() {
   { typeof(Source1), new Dictionary<Type, Expression>() {
      { typeof(Dest1), (Expression)(() => {
         return new Dest1() {
            ...
         }
      }) }
      , { typeof(Dest2), (Expression)(() => {
         return new Dest2() {
            ...
         }
      }) }
   } }
   , { typeof(Source2), new Dictionary<Type, Expression>() {
      { typeof(Dest3), (Expression)(() => {
         return new Dest3() {
            ...
         }
      }) }
      , { typeof(Dest4), (Expression)(() => {
         return new Dest4() {
            ...
         }
      }) }
   } }
};
Which is pretty brutal, especially since in MVC.NET you're going to be working with probably at least 10+ domain models and twice as many view models. The whole point of this exercise is to reduce the amount of code we have to write while still having flexibility. So, lets get to refactoring.

The obvious starting point is to wrap the previous code into an Add function. To use the Source and Dest types we'll have to make it a generic function, which is fine:
void Add<TSource, TDest>(IDictionary<Type, IDictionary<Type, Expression>> Projections, Expression Expression) {
   Type source = typeof(TSource);
   Type dest = typeof(TDest);
   
   if(true == Projections.ContainsKey(source)) {
      Projections[source].Add(Expression);
   } else {
      IDictionary<Type, Expression>> d = new Dictionary<Type, Expression>>();
      d.Add(dest, Expression);

      Projections.Add(source, d);
   }
}

IDictionary<Type, IDictionary<Type, Expression>> projections =
   new Dictionary<Type, IDictionary<Type, Expression>>
;

Expression e = (Expression)(() => {
   return new TDest() {
      ...
   }
});

Add<Source, Dest>(projections, e);
That's not bad, but we can do better. After all, you don't want to have to type all that mess every time. One easy thing we can do to clean the syntax up is move our Expressions to variables rather than methods.
Expression e = (Expression)(o => new TDest() {
      ...
   }
);
But we're not done yet. Since the generic Expression class derives from the Expression class, we can do away with the casting...
Expression e = o => new TDest() {
      ...
   }
;
The Add function could also be refactored more. Instead of having to write Add<Source, Dest>(d, e) for every single projection, wouldn't it be nicer to simply split it out into two? Add<Source>(d) and Add<Dest>(d, e).

Lets do that.
void Add<TSource>(IDictionary<Type, IDictionary<Type, Expression>> Projections, IDictionary<Type, Expression> Dictionary) {
   Projections.Add(typeof(TSource), Dictionary);
}

void Add<TDest>(IDictionary<Type, Expression> Dictionary, Expression Expression) {
   Dictionary.Add(typeof(TDest), Expression);
}
One of the nice features of C# is the ability to make Extension methods. Make your method static and slap it in a static class, add the 'this' keyword to the first parameter and the type of object that it is will allow you to use that method as if it was a part of the original class while abstracting away the parameter. Lets do that here:
static class Mapper {
   static void Add<TSource>(this IDictionary<Type, IDictionary<Type, Expression>> Projections, IDictionary<Type, Expression> Dictionary) {
      Projections(typeof(TSource), Dictionary);
   }

   static void Add<TDest>(this IDictionary<Type, Expression> Dictionary, Expression Expression) {
      Dictionary.Add(typeof(TDest), Expression);
   }
}
Our Add methods can now be called like so:
d2.Add<Dest>(e);
d1.Add<Source>(d2);
Almost done with the Add functions. Rather than calling d1.Add(); many times, wouldn't it be nicer to simply chain them?
static IDictionary<Type, IDictionary<Type, Expression>> Add<TSource>(this IDictionary<Type, IDictionary<Type, Expression>> Projections, IDictionary<Type, Expression> Dictionary) {
   Projections.Add(typeof(TSource), Dictionary);
   return Projections;
}

static void Add<TDest>(this IDictionary<Type, Expression> Dictionary, Expression Expression) {
   Dictionary.Add(typeof(TDest), Expression);
   return Dictionary;
}
Thus we can call them:
d2
   .Add<Dest1>(e1)
   .Add<Dest2>(e2)
   ...
;

d1
   .Add<Source1>(d2)
   .Add<Source2>(d3)
   ...
;
Okay, one last update to the Add function and we'll be close to done. In our haste to refactor, we've committed the cardinal programmer sin. Optimizing at the start. We've made things a little TOO generic. I've always found the generic method syntax (f<t>()) to be a little verbose. The other great thing about extension methods is that if we play our cards right, the 'this' parameter can actually imply the type of the generic, abstracting it away so that it looks like a normal function. Once our projection goes into the dictionary it loses its type and becomes a standard Expression rather than an Expression<> so we can't actually do anything for the outer dictionary Add method, but we can certainly clean up the inner Add.
static Dictionary<Type, Expression> Add<TSource, TDest>(this Dictionary<Type, Expression> Dictionary, Expression<Func<TSource, TDest>> Expression) {
   Dictionary.Add(typeof(TDest), Expression);
   return Dictionary;
}
Now for one final cleanup method:
static Expression GetProjection(Type Source, Type Dest) {
   return Projections[Source][Dest];
}
Altogether our code is looking pretty nice so far:
public static class Mapper {
   private static Dictionary<Type, Expression> Add<TDest>(this Dictionary<Type, Expression> Dictionary, Expression Expression) {
      Dictionary.Add(typeof(TDest), Expression);
      return Dictionary;
   }

   private static Dictionary<Type, Expression> Add<TSource, TDest>(this Dictionary<Type, Expression> Dictionary, Expression<Func<TSource, TDest>> Expression) {
      Dictionary.Add(typeof(TDest), Expression);
      return Dictionary;
   }

   private static Dictionary<Type, Dictionary<Type, Expression>> Add<TSource>(this Dictionary<Type, Dictionary<Type, Expression>> Dictionary, Dictionary<Type, Expression> Projections) {
      Dictionary.Add(typeof(TSource), Projections);
      return Dictionary;
   }

   private static Expression GetProjection(Type Source, Type Dest) {
      return Projections[Source][Dest];
   }

   private static Dictionary<Type, Dictionary<Type, Expression>> Projections {
      get {
         return new Dictionary<Type, Dictionary<Type, Expression>>()
            .Add<Source1>(Source1Projections)
            .Add<Source2>(Source2Projections)
         ;
      }
   }

   private static Dictionary<Type, Expression> Source1Projections{
      get {
         return new Dictionary<Type, Expression>()
            .Add(Dest1.Projection)
            .Add(Dest2.Projection)
         ;
      }
   }

   private static Dictionary<Type, Expression> Source2Projections{
      get {
         return new Dictionary<Type, Expression>()
            .Add(Dest3.Projection)
            .Add(Dest4.Projection)
         ;
      }
   }
}
You can define your actual projections in your view models:
public class Dest1 {
    <properties>
    <constructors>
    <methods>

    public static Expression<Func<Source1, Dest1>> Projection {
       get {
          return o => new Dest1() {
             ...
          };
       }
    }
}
There's probably more I could do to refactor this. There really isn't much reason the projections need to be properties rather than standard variables for example but I'll leave it there. This post is becoming pretty long winded, so I'll save the rest for Part 3. We're 2/3rds of the way there so stay tuned for the Actual implementing the projection methods that will let you use the mapper.

Tuesday, August 20, 2013

Homemade Lightweight Automapper Part 1

I've been using MVC3.NET for just over a year now in a project for work. I find myself liking the approach, I feel more in control of the code that I write, and while I admire MS efforts, I am glad to be rid of the horrible overhead that is the ViewState.

Using Entity Framework, I've learned a *lot* about linq. I went with a POCO approach for my models. I feel that this approach is much more elegant and lightweight than relying on EF to map everything out, and the less auto-generated nightmarish code the better IMHO.

If there is one thing I could complain about MS's bash at the MVC paradigm, it is how code heavy it is. Classes and classes and more classes. And did I mention classes? Once you get used to the slightly over engineered verboseness of it though, you do begin to appreciate the perks that go with it.

In the project I'm currently working on, we decided early on to start work with the Kendo JS framework, which is pretty shiny, and to try and help reduce code a bit, we started using the AutoMapper 3rd party library fairly early on.

Well, if you've used Kendo, you'll know that for the MVC side of things, all of the 'big' data display controls such as grids or lists are designed fairly heavily around taking their data in IQueryable format. They will take any IEnumerable, but if you have more than a few hundred records being pulled from your database, you don't want to materialize those records into memory until you need to, or things get slooooooooowwww very quickly.

Let me back up and give a brief outline of Entity Framework and Linq. There are two kinds of linq that use the same syntax and both work on most any sort of container object... arrays, dictionaries, lists, etc. Linq to Object works on objects in memory, Linq to SQL works specifically in a monadic way to generate a SQL query that is only run at the last minute.

You generally use L2SQL on IQueryables and L2OBJ on everything else. Problems arise when casting IQueryables to their parent interface IEnumerables because then you can quickly lose track of where your data is and run into performance issues (among other things).

After jumping into the deep end (When I started on this project, I personally had *very* little MVC experience no Kendo experience, no linq or Entity Framework experience and had been working in .NET 2.0 until that time) we quickly discovered that Sorting, Grouping, and Paging, the main 3 things you want to do with data in a Grid, did not play nicely unless you were working with IQueryables... oh they work fine if you only have a few hundred records, but once your DB starts filling up, a few thousand records being sorted, paged and grouped in memory rather than at the DB hurts really badly.

The AutoMapper had worked reasonably well up until that point but there was one hitch: It did not work with IQueryables. I did a bit of research and discovered that it indeed worked with IQueryables if you used a certain syntax... something along the lines of Project().To(), but the line of code would always inexplicably crash, no matter how much I coaxed it. Pretty sure that the particular version of the library that we were using had a bug, and unfortunately at the time it was not an option to upgrade.

This lead me to start looking into ways I could simply do it myself. After all, the Automapper code is fairly ugly to work with anyway, albeit fairly powerful if you work it right. I'll use the next 1-2 blog posts to run through how to create a rudimentary automapper that works fairly well in most complex cases.