AutoMapping view-models in ASP.NET MVC

A lot of developers are seeing the wisdom in using AutoMapper to cut out the unpleasant “middle-man” of view-model design – converting Models into ViewModels.

Of course, the mappings must first be created, and once-per-application thank you. And here arises the question: do we keep the Mappings where we should - in the vicinity of the code they concern, or where we must – the Application_Begin() method of our Global class?

Personally I’d prefer the former.

So then the challenge is, how do we make sure the CreateMapping() statements are called once per application, but are still stored nearby the code they concern?

Here’s my solution (I also posted it on StackOverflow):

I add some logic to the constructor of my BaseController, which runs the ‘CreateMappings’ method, but only once per Controller Type:

public abstract class BaseController : Controller
{
    public BaseController()
    {
        if (!controllersWithMappingsCreated.Contains(GetType()))
        {
            CreateMappings();
            controllersWithMappingsCreated.Enqueue(GetType());
        }
    }

    protected virtual void CreateMappings() { }
}

Then, in each concrete controller, I use CreateMappings to declare the mappings for all the Models/ViewModels relevant to that controller.

public class AccountController : BaseController
{
    public AccountController() : base() { }

    protected override void CreateMappings()
    {
        Mapper.CreateMap<Models.User, ViewModels.UserProfile>();
        Mapper.CreateMap<Models.User, ViewModels.ChangePassword>();
    }
}

Now I can simply override CreateMappings() in any controller class I wish, and declare only those mappings that concern the behavior of that controller.

Since I try to limit the number of concerns each controller deals with, I’m confident that none of the CreateMappings().

Attribute soup

I’ve been working on a personal project – of course using the latest incarnation of ASP.NET MVC.

Now I’m a good developer, and I keep my domain models separate from my views, using a layer of ViewModels.

So what happens if I’m representing a sub-set of a domain object in more than one ViewModel, and each sub-set has the same validation attributes?

For example, say I’m storing a User with the following domain object:

I might have two separate Views for managing that user, each with a ViewModel and Validation attributes:

Spot the problem?

Managing validation is going to be rather laborious once we have 5 or more ViewModels intermediating one Domain object.

Allow me to indulge in a Venn diagram:

I found an awesome answer on StackOverflow from a user called Sam, which basically involves attaching a meta-data object to the ViewModels, using MetadataType and thus allowing us to re-use Validators.

Here’s a diagram to represent this:

The snag? Your ViewModels have to explicitly declare every member for which the Metadata object provides meta-data.

Thus, in our example above, we’d have to have HomeAddress and PostalAddress in EditBasicInfo, which would invalidate the purpose of using ViewModels.

I’m considering of cutting my own version of MetadataTypeAttribute, which allows you to attach it to a class without declaring all of its members.

Any other ideas? Drop me a comment/tweet.

Batching it

It’s been about a decade since I touched batch programming. Of course, I loved it back in the day.

<geekMoment>I used to borrow books like this from the library and read them 5 times.</geekMoment>

So just today a co-worker asked me for some help.

He’d written a batch file that lists every file in a directory including sub-directories. All he wanted to do was put an HTML tag around each filename.

Of course, the pre-1980 ‘DIR’ command couldn’t do much for him.

Now it seems that Microsoft have added a ‘for’ statement to the batch language. I managed to dig up an article describing it in fairly human terms.

The result was this:

for /r C:\HC %%X in (*) do ( echo ^<span^>%%X^</span^> )

How cryptic is this?

  • The basic structure is “for {set} {variable} in {filter} do {command}
  • The /r switch means ‘recursive’. I guess it only works if {set} is a directory path?
  • The variable names are ugly – %%X – even worse than PHP’s dollar sign!
  • Oh yeah and the hats – ^ – are for escaping angle brackets.

I don’t know why I used to love this language.

But I suppose this beats 20 lines of C# code.

Generating map marker images with Python

I’ve been working a lot with Google Maps and trying to optimize things on the client-side.

Now when it came to the marker icons, I initially snatched them from Google’s Chart API.

I needed 50 marker icons (numbered 1 to 50), so it worked well to dynamically generate a URL.

However, in the interests of greater performance (and not being evil) I decided to write a script to download every we’d need as a PNG file, which we could serve ourselves.

From personal experience, C# is often overkill for this kind of thing. So I decided to give Python a chance to prove itself.

(It’s my first time doing anything in Python, but I know the fundamentals of the language, and I found some excellent articles that steered me in the right direction.)

So here’s my first Python script, generateGoogleImages.py:

from urllib import urlopen

for i in range(1, 51):

page = urlopen("http://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=" + str(i) + "|FFD800|000000&bogus=.png")
image = page.read()
file = open("mm_21_34_blue_" + str(i) + ".png", "wb")
file.write(image)
file.close()

This works excellently, and I only have to tweak the script a little to generate any color combination I desire. Python lived up to my expectations.

Future hopes for the script:

  • Control fill/border colors through command-line arguments
  • Output 1 file instead of 50, so I can use CSS sprites instead of individual images.

Vietnam

Going to publish some writing about my trip soon (promise!)

For now, here are some pics from Sapa.

http://picasaweb.google.com/jonathan.conway/VietnamSapa

Upgrading to ASP.NET MVC 2 Preview 2

Well it’s been a long, long time since I blogged anything, so here’s a quick post to break the ice.

I’ve been using ASP.NET MVC for a client project over the past 7 or 8 months (yes, I was using it pre-beta).

There have been good and bad times, but overall I’m optimistic about the framework.

Version 2 (preview 2) was just released and now features support for ‘Areas’ within a single project.

This is awesome and just what I was looking for, as I’m using the areas feature to separate the back-end “admin” portion of the website from the live portion.

(Previously I had put the Admin stuff in a separate project, which made things more complicated in all sorts of ways.)

After installing the update and 25 minutes of refactoring I had everything working and had moved Admin in-project.

If only framework upgrades were always this easy… :)

Plugging Earphones

Phew! After months of on-and-off searching, I think I’ve found the ideal headphone set to suit my noise-a-holic lifestyle. It’s the Sony DR-BT50 bluetooth headset and I got it off eBay for a couple of hundred and a bit (they’re not available in Australia).

I also got this sweet little adapter for my iPhone, because Apple decided that we’re not allowed to stream our music over bluetooth (A2DP), at least not out-of-the-box.

My workmate has been using Seinheiser in-ear-phones, which he says are OK but overpriced. Apparently there’s only one distributer of Seinheiser in Australia, so they can charge what they like. Makes me wonder how much of this goes on in Australia.

Anyway, you’ll hear more about the Sony’s when they finally arrive.

Where’s Google Transit for Sydney?

Google Transit is a new feature that will integrate public transport data into Google Maps.

This would be an excellent tool for Sydney-siders!

How many times have we been frustrated with the lousy user experience offered by 131500.com and WhereIs.com.au, when trying to figure out how to get somewhere on public transport?

My question is, since Google Transit has already been implemented for Adelaide and Perth, why not Sydney?

NB. I’ve started a discussion on this.

Kubrick, Software and Iterations

How this post was written

I didn’t sit down and write this post from beginning to end. I wrote the way most people write – they type something, then hit Backspace a few times then write something else, and repeat the process until they have something they’re relatively happy with.

Kubrick’s Secret

I recently watched “Stanley Kubrick’s Boxes“, an hour-long documentary about what a drooling fan (not myself) found in the late film director’s basement.

Kubrick wasn’t such a genuis after all. But he did have a brilliant method of achieving his brilliant results. He just did everything hundreds of times.

What they found in the basement were collections of photos of the same kind of scene shot in multiple locations. Thousands of gate photos. Thousands of street scenes. Thousands of hooker doorways (eek!).

It doesn’t stop there. Remember the classical music in many of Kubrick’s films? Well I think this was just an easy way to sample hundreds of different pieces to find out which one was most suitable. Certainly saved having to pay professional composers (well most of the time).

And recall how Kubrick would shoot a scene hundreds of times, to the chagrin of many an actor.  He didn’t do this because the actors themselves were crap. He did it so he could sit down later in the editing room and hand-pick the best possible performance. Which also explains why he often took the editing upon himself.

Software development

There are a million people saying this in a million different ways (SCRUM being one of them), but basically, you don’t write a software program from beginning to end. It’s an iterative process. It’s more iterative than other comparably processes (such as building a house) because anything and everything can be changed instantly.

When you’re fiddling with bytes in computer memory, what better way to come up with the best solution than rewriting the program again and again until you get it right? This is called iterative development.

The point?

I guess what I have to say at the end of it all is, iteration is a very powerful tool for achieveing the best possible results. It can take time, but it’s going to save time if you want to build something that will last. That’s why, 30 years later, everyone still loves The Shining.

Top 5 reasons the iPhone 3G sucks

I’m beginning to get what Maddox was on about… post-purchase of course. :(

  1. Crippled hardware – no video, no VOIP and crippled bluetooth.
  2. Poor battery life – 5 hours isn’t much better than most laptops.
  3. Closed-source, heavily proprietary software and hardware architecture. And you thought Microsoft were evil?
  4. Bad call and receiption quality.
  5. You’re locked into a service provider from the work go. And getting it unlocked isn’t as easy as they said – after waiting four weeks, Apple still won’t sent me the unlock code.

Next Page »



Follow

Get every new post delivered to your Inbox.