AutoMapperAutoMapper is one of those tools that took me a little while to like. There isn't really anything to dislike, but... I just didn't "feel the pain" that it solves. I think the reason is, that I wasn't building good enough software to really NEED AutoMapper. So here's my pitch: "If you don't need AutoMapper, you're probably writing stinky code."
So what is it anyway? AutoMapper allows you to automatically map fields from one object to another. Let's say you have the following two classes defined:
Now, you certainly could write code like this:
But with AutoMapper you could just write this instead:
And you wouldn't even need that silly GetViewModelForCar method, or the class that it lives in anymore, right? There is a tiny bit of setup/configuration not shown, but you get the idea. So, I'm sure you've noticed, the "auto" part happens because the field names exactly match up. What if yours don't? So if you're mapping from:
Because, you know, trucks don't have descriptions, they have STORIES! You would configure it like this:
And your "usage" would still be exactly like before:
One of the fancy value-adds is that you can make "global" rules such as "any time AutoMapper maps from a DateTime to a String, I want it to be in ShortDate format." To do that, you create a "ValueFormatter" class, and use it in your mapping configuration. That may sound hard, but really it isn't:
Of course they can be over-ridden for specific mappings as needed.
Of course, there is a lot more to see and learn. But what about that comment I made above about your stinky code? Here is my reasoning. In a well-factored application, there is never just one "model." I know, I know.. maybe you don't even have ONE model yet. Get one. Trust me on this. Anyway, even the super-awesome ASP.NET MVC framework, the "M" is wrong. It should really be something like "MMMVC." Because you need three models to do it right.
- The "domain model." The full and correct and authoritative definition of "what is a car?" Your persistence layer knows how to do CRUD on the types defined here.
The "view model." Your controller needs to send some data to your view. You don't want to send an actual CAR object to the view. There are MANY reasons for this, but some of the
quick ones are:
- Even if we are talking about the "Car Details Page" it is likely your view likely needs more data than just what a CAR provides. The current user name, the count of other visitors online right now. Whatever. So you need to send a type that is more than just a CAR object.
- It is highly likely that your view will need much LESS data than the CAR object provides. Depending on how you build it, there may also be security implications in having more data here than is needed.
- The "input model" or "posted data model" as Dino Esposito calls it. Sooner or later, your view will want to post some data back to the controller for processing. It certainly shouldn't be a CAR object. Likely it shouldn't be the "view model" object either. That object would have too much data. Why post back the current user name when that has nothing to do with the car details that were updated in the form?
So then, you have lots of models, and most of them are similar, or even subsets of each other. I think if you give that some serious thought, you'll end up with only one objection:
It's just too much typing - especially the mapping of each model to the other. The "bang for the buck" just isn't there. Blah.
AutoMapper takes that argument out of the way.