I recently received an email from a Simon Gorski asking where the AutoMapper code went, and sad to say I deleted it from GitHub. Why did I do that, you may ask? Well after many moons of using AutoMapper I have moved on to better frameworks that can do this far easier for me. I didn’t want anyone using that code because it would be painful for them (it was for your own good, I promise). Currently I use ValueInjecter which is a convention based mapping framework and helps make mapping a negligible part of my work day. Oh the early days of my career, where I thought mapping was all there really was to do in programming. I’ve wised up and now I’m going to show you how you can spend almost no time doing your own mappings.

The code to this sample can be found on GitHub at https://github.com/khalidabuhakmeh/ValueInjecter-Sample

My sample is pure POCO, but I currently use the code first approach with Entity Framework in real world projects and this would also work with most ORMs. My sample is also written in an ASP.NET MVC application, so I’ll be making mention of controllers and actions, but this would work easily as nicely in any .NET application.

Let’s start with the final look and feel of your controller, how will this feel when you are developing with it?

      Person Current {
            get { return Session["Person"] as Person; }
            set { Session["Person"] = value; }
        }

        [HttpGet]
        public ActionResult Index() {
            var model = Current.ToViewModel<PersonViewModel>();
            return View(model);
        }

        [HttpPost]
        public ActionResult Index(PersonViewModel model) {
            Current = model.ToDomain(Current).Audit();
            return RedirectToAction("Index");
        }

The mapping code is one line in both my actions: From a domain model (EF, Linq2SQL, POCO) to a view model, from a viewmodel back to a domain model. Now if you are familiar with what happens originally with AutoMapper then you are dreading seeing the mapping classes that make this happen. Fear not, I’ll show you this in a second but you will see that there really isn’t much to it.

public static class Extensions
    {
        public static T ToDomain(this object source, T domain = default(T))
            where T: class, new()
        {
            if (domain == null)
                domain = new T();

            if (source == null)
                return domain;

              domain.InjectFrom(source)
                .InjectFrom<IgnoreAudit>(source)
                .InjectFrom<FlatLoopValueInjection>(source)
                .InjectFrom<UnflatLoopValueInjection>(source);

            return domain;
        }

        public static T ToViewModel(this object source, T viewmodel = default(T))
            where T : class, new()
        {
            if (viewmodel == null)
                viewmodel = new T();

            if (source == null)
                return viewmodel;

           viewmodel.InjectFrom(source)
                .InjectFrom<FlatLoopValueInjection>(source)
                .InjectFrom<UnflatLoopValueInjection>(source)
                .InjectFrom<NullablesToNormal>(source)
                .InjectFrom<NormalToNullables>(source)
                .InjectFrom<IntToEnum>(source)
                .InjectFrom<EnumToInt>(source);

            return viewmodel;
        }

        public static T Audit( this IAudit&lt;T&gt; target, string user = "system")
        {
            if (!target.CreatedAt.HasValue) {
                target.CreatedAt = DateTime.UtcNow;
                target.CreatedBy = user;
            }

            target.UpdatedAt = DateTime.UtcNow;
            target.UpdatedBy = user;

            return (T) target;
        }
    }

I know, how boring. That’s it?!? Yes it is, this is all the code you will need to map from complex objects to your view models. Never again will you have to do trivial mapping (unless you like that sort of thing). I do also want to show you one more thing about the Audit method.

When you say Audit() on your objects you want to make sure that it doesn’t overwrite the previous values, even if there are values coming from somewhere else. These are read only values and the mapping should respect that. So I wrote a specific convention to make sure that these properties retain their original value regardless of what happens.

 public class IgnoreAudit : ConventionInjection
    {
        private static readonly string[] AuditNames = typeof (IAudit).GetProperties().Select(p => p.Name).ToArray();

        protected override bool Match(ConventionInfo c) {
            var result = AuditNames.Contains(c.TargetProp.Name);
            return result;
        }

        protected override object SetValue(ConventionInfo c) {
            // don't override these values
            return c.TargetProp.Value;
        }
    }

So it’s that easy to make sure those original values are respected.

My revelation when it comes to mapping is that I follow a lot of conventions and by doing so I save myself a ton of time coding. You can use this same technique to cut a lot of noise out of your own code base and make your intentions clearer. So here you go Simon (and anybody else). Hope this helps out. Please feel free to ask any questions.

The code to this sample can be found on GitHub at https://github.com/khalidabuhakmeh/ValueInjecter-Sample