AutoMapper & AutoFac

Prelude

So I tend to develop things in the way of

  1. Make it work
  2. Make it pretty

Make it work

So when using AutoMapper after step one I ended up with something like this

.ForMember(d => d.SomeSource, 
     o => o.MapFrom(
          s => new Serializer().Deserialize<SomeViewModel>(s.Serialized)))

Some background, for the destination SomeSource I needed to Deserialize the value as it was currently stored as Json in my database.

Make it pretty

While it works it looks rather horrible, so I started looking into something that allowed me to get a ISerializer from AutoFac (my IoC of choice) instead.

So, first I added a custom ValueResolver that looked like this

public class SomeViewModelResolver 
    : ValueResolver<OrderRow, ScheduleViewModel>
    {
        private readonly ISerializer _serializer;

        public ScheduleViewModelResolver(ISerializer serializer)
        {
            _serializer = serializer;
        }

        protected override SomeViewModel ResolveCore(Source source)
        {
            return _serializer.Deserialize<SomeViewModel>(source.Serialized);
        }
    }

Next was to connect AutoMapper with AutoFac and to register the ValueResolver:

// Register my new valueresolver
builder.RegisterType<SomeViewModelResolver>();

// Connect AutoMapper to AutoFac
Mapper.Initialize(x => x.ConstructServicesUsing(container.Resolve));

Once that is done the last thing to change is to modify the ForMember call to use the new ValueResolver instead

.ForMember(d => d.SomeSource, o => o.ResolveUsing<SomeViewModelResolver>())

Looks a lot cleaner and follows the flow that you would expect when using a IoC container.

Bonus

If you don't want to have calls to the static Mapper.Map<> all over your code, it is possible to register the IMappingEngine in AutoMapper in you IoC container and have that as an dependency for you class too. For AutoFac the registration looks like this

builder.Register(c => Mapper.Engine).As<IMappingEngine>().SingleInstance();

The important thing is to register it as a singelton. Once that is done just add IMappingEngine mappingEngine to the constructors of those classes that use AutomMapper.

Recent changes

So I've made some (mostly) under the hood changes to this blog. Lets start with the visible part I've dropped the blog part from the domain, the redirect is permanent but it might be a good idea to update your rss feed.

The fun parts are that the blog has moved from wordpress to using jekyll and is hosted on github from this repository. Migrating to jekyll was rather simple, there's plugins that support conversion from a wordpress backup xml file to jekylls structure. Since I liked the theme (decode) used on the wordpress site I 'ported' it to jekyll, or well cherry picked some parts and removed most things that I didn't need. Since I also moved the blog up from blog. to the top level I had to support the old links too, that is done using a nginx instance that does a redirect (301, permanent) from blog.* to the top level with the path intact.

A big bonus with jekyll is that I can write my posts in markdown and they are stored as simple text, no weird database or anything.

When I moved of one.com I lost my mail account that was connected to the domain, and since google apps doesn't accept any new accounts for free anymore I looked around for an alternative that could work. While outlook.com does offer custom domain hosting if looked around a bit more and found zoho they offer a bit less space per account than google but has pop3/imap access and overall as fast as gmail.

Getting DOM element as an Image

So I recently needed to create a image from a part of a webpage (html) after a short googling I found a nice library, html2canvas, that can render a part of the dom as a canvas element, complete with all css properties. So that's a good start but I needed some way of making the image downloadable too. Turns out the canvas element has a function called toDataURL that returns the rendered content of the canvas as a data-url. The url can then be used with a <a> tag to create a download link. So the complete example looks something like this.
html2canvas($("#toclone"), {
    onrendered: function (canvas) {
        var $a = $("<a download=\"file.png\" href=\"" + canvas.toDataURL() + "\">download</a>");
        $("#somecontainer").append($a);
    }
});
This works fine in Chrome & Firefox whoever not in Internet Explorer, in IE a small hack is needed. Due to 'security' reasons IE doesn't allow data urls in <a> tags so instead you need to decode the data from the canvas and create a blob object that can be passed to the window.navigator.msSaveOrOpenBlob function.
var isIe = function() {
    var trident = !!navigator.userAgent.match(/Trident\/7.0/);
    var net = !!navigator.userAgent.match(/.NET4.0E/);
    var ie11 = trident && net;
    var iEold = (navigator.userAgent.match(/MSIE/i) ? true : false);
    return ie11 || iEold;
};

var workInHorribleIE = function(canvas, filename) {
    var image = canvas.toDataURL();
    image = image.substring(22); // remove data stuff
    var byteString = atob(image);
    var buffer = new ArrayBuffer(byteString.length);
    var intArray = new Uint8Array(buffer);

    for (var i = 0; i < byteString.length; i++) {
        intArray[i] = byteString.charCodeAt(i);
    }

    var blob = new Blob([buffer], { type: "image/png" });
    window.navigator.msSaveOrOpenBlob(blob, filename +".png");
};

html2canvas($("#cctree"), {
    onrendered: function (canvas) {
        var $a;
        if (isIe()) {
            $a = $("<a>download</a>").on("click", function () {
                workInHorribleIE(canvas, "file");
            });
        } else {
            $a = $("<a download=\"file.png\" href=\"" + canvas.toDataURL() + "\">download</a>");
        }
        $("table", $cntnt).parent().append($a);
    }
});
Guess there's better ways to detect if IE is present and most of the data-url to blob stuff should be replaced with a toBlob call once it's supported.

Making sure resource files are kept in sync

Lets assume you have a site that uses resource files to handle translations, in that case you might need a way to make sure that everything is kept in sync and translated. One way of solving this with tests, that way it can be checked during commits & builds. Since resource files are loaded based on the CurrentUICulture the test needs a way to swap culture during it's run. So here's a small class that does just that (from Stackoverflow, lost the link tho).
public class SwitchCultureContext : IDisposable
{
    private CultureInfo previousCultureInfo { get; set; }

    public SwitchCultureContext(CultureInfo temporaryCulture)
    {
        previousCultureInfo 
          = Thread.CurrentThread.CurrentUICulture;
        Thread.CurrentThread.CurrentUICulture
          = temporaryCulture;
    }

    public SwitchCultureContext(string code) 
        : this(new CultureInfo(code)) { }

    public void Dispose()
    {
        Thread.CurrentThread.CurrentUICulture 
         = previousCultureInfo;
    }
}
Basically use it inside a using() {} statement to temporarily run with a different culture. So in my case I have a resource file called Strings that is the baseline I use during development, I also have one that is for translation (using the ta-IN culture) that has all texts as placeholders to allow for them to be easily identified. So my test will read all items in by baseline and then compare it to everything from the translation. If something is missing in the translation file then the value from the baseline file will be used instead. Because I have placeholders in my translation file I can simply look at the value from the file and compare it to the value form the baseline file in no case should the be the same. So the 'litte' test
[Test]
public void AllPropertiesOnBaseShouldBeOnTranslation()
{
    var baseLine = new Dictionary&lt;string, string&gt;();
    var translated = new Dictionary&lt;string, string&gt;();

    var props = typeof (Strings).
        GetProperties(BindingFlags.Public | BindingFlags.Static).
        Where(p =&gt; p.PropertyType == typeof(string)).ToArray();

    foreach (var propertyInfo in props)
    {
        var info = typeof(Strings).GetProperty(propertyInfo.Name,
             BindingFlags.Public | BindingFlags.Static);
        var value = info.GetValue(null) as string;

        baseLine.Add(propertyInfo.Name, value);
    }

    using (new SwitchCultureContext("ta-IN"))
    {
        var type = typeof (Strings);
        foreach (var baseProperty in props)
        {
            var info = type.GetProperty(baseProperty.Name,
                 BindingFlags.Public | BindingFlags.Static);
            var value = info.GetValue(null) as string;

            translated.Add(baseProperty.Name, value);
        }
    }

    bool pass = true;
    foreach (var item in baseLine)
    {
        var t = translated[item.Key];
        if (item.Value == t)
        {
            pass = false;
            Debug.WriteLine(item.Key + " not translated!");
        }
    }

    Assert.That(pass, Is.True, 
        "Translation resource file is not in sync!");
}
So if the test fails it will have outputted which keys that haven't been translated. In this case my resource files only contain strings so I ignore all other properties.