This post is in response to a question on a recent article I wrote about mapping domain entities to presentation models with AutoMapper, an object-object mapper for .NET. Today I will give a brief example of how we can tie it all together in an ASP.NET MVC application using dependency injection and application services.

First, let’s start with the controller and the application service it talks to:

public class TasksController : Controller
{
    readonly ITaskService tasks;

    public TasksController(ITaskService tasks)
    {
        if (tasks == null)
            throw new ArgumentNullException("tasks");

        this.tasks = tasks;
    }

    public ActionResult Index()
    {
        IEnumerable<TaskView> results = this.tasks.GetCurrentTasks();
        return View(results);
    }

    ...
}
public interface ITaskService
{
    IEnumerable<TaskView> GetCurrentTasks();
    TaskView AddTask(TaskForm task);
    TaskView SaveTask(TaskForm task);
    void DeleteTask(int id);
}

Note the service’s inputs and outputs are defined in terms of view models (TaskView) and edit models (TaskForm). Performing this mapping in the application services layer keeps our controllers nice and simple. Remember we want to keep them as thin as possible.

Inside the tasks service

public class TaskService : ITaskService
{
    readonly ITaskRepository taskRepository;
    readonly IMappingEngine mapper;

    public TaskService(ITaskRepository taskRepository, IMappingEngine mapper)
    {
        if (taskRepository == null)
            throw new ArgumentNullException("taskRepository");

        if (mapper == null)
            throw new ArgumentNullException("mapper");

        this.taskRepository = taskRepository;
        this.mapper = mapper;
    }

    public IEnumerable<TaskView> GetCurrentTasks()
    {
        IEnumerable<Task> tasks = this.taskRepository.GetAll();
        return tasks.Select(t => this.mapper.Map<Task, TaskView>(t));
    }

    ...
}

The tasks service has two dependencies: the tasks repository* and AutoMapper itself. Injecting a repository into a service is simple enough, but for AutoMapper we have to inject an IMappingEngine instance to break the static dependency on AutoMapper.Mapper as discussed in this post.

* Note this is a very simple example — in a bigger app we might use CQS instead of querying the repository directly.

Testing the service

We are using Moq to isolate the tasks service from its repository and AutoMapper dependencies, which always return a known result from the Object Mother. Here are our test cases for all the different things that should occur when retrieving the current tasks:

[TestFixture]
public class When_getting_all_current_tasks
{
    Mock<ITaskRepository> repository;
    Mock<IMappingEngine> mapper;
    ITaskService service;
    IEnumerable<Task> tasks;

    [SetUp]
    public void SetUp()
    {
        repository = new Mock<ITaskRepository>();
        mapper = new Mock<IMappingEngine>();

        service = new TaskService(repository.Object, mapper.Object);

        tasks = ObjectMother.GetListOfTasks();
        repository.Setup(r => r.GetAll()).Returns(tasks);

        mapper.Setup(m => m.Map<Task, TaskView>(It.IsAny<Task>()))
            .Returns(ObjectMother.GetTaskView());
    }

    [Test]
    public void Should_get_all_the_tasks_from_the_repository()
    {
        service.GetCurrentTasks();

        repository.Verify(r => r.GetAll());
    }

    [Test]
    public void Should_map_tasks_to_view_models()
    {
        service.GetCurrentTasks();

        foreach (Task task in tasks)
            mapper.Verify(m => m.Map<Task, TaskView>(task));
    }

    [Test]
    public void Should_return_mapped_tasks()
    {
        IEnumerable<TaskView> results = service.GetCurrentTasks();
        results.Should().Not.Be.Empty();
    }
}

Enter AutoMapper

As you can see, we have both the controller and service under test without needing to involve AutoMapper yet. Remember it is being tested separately as discussed in my previous post.

To wire up AutoMapper so it gets injected into the TaskService, all we have to do is register IMappingEngine in the IoC container:

container.RegisterInstance<IMappingEngine>(Mapper.Engine);

Putting the mapping step in the application service and then mocking out AutoMapper like this allows us to easily test everything in isolation, without having to set up the mapper first.

I hope this answers your question Paul!

August 18th, 2009 | 9 Comments

Gravatar

I’m a big fan of Jimmy Bogard’s AutoMapper – a handy little tool for fluently mapping your domain model objects to presentation model objects.

This week, I added Gravatar support to a small side-project I’m working on. For those that don’t know, Gravatar is a globally recognized avatar with a URL based on the MD5 hash of your e-mail address, e.g.:

http://www.gravatar.com/avatar/3b3be63a4c2a439b013787725dfce802.jpg

Any site that knows your e-mail address can therefore generate your Gravatar URL and show your profile pic. If you’re using AutoMapper, mapping an e-mail address to a Gravatar URL is a perfect case for a custom IValueResolver, e.g.:

Mapper.CreateMap<User, UserProfile>()
    .ForMember(p => p.Username, opt => opt.MapFrom(u => u.Username))
    .ForMember(p => p.About, opt => opt.MapFrom(u => u.Profile.About))
    .ForMember(p => p.Location, opt => opt.MapFrom(u => u.Profile.Location))
    .ForMember(p => p.Url, opt => opt.MapFrom(u => u.Profile.Url))
    .ForMember(p => p.DisplayImage,
               opt => opt.ResolveUsing<GravatarUrlResolver>()
                         .FromMember(u => u.Profile.Email));

You can download my implementation here: GravatarUrlResolver.cs and tests (of course) here: GravatarUrlResolverTests.cs

June 10th, 2009 | No Comments Yet

I’m a big fan of AutoMapper, an open-source object/object mapper for .NET. One thing I’ve noticed, however, is that all the examples I’ve seen all talk to the static Mapper class. This becomes a real pain when you need to test something that uses AutoMapper, because you can’t swap it out for testing purposes:

public class ReadingListService : IReadingListService
{
    IValidator<ReadingListForm> validator; // injected
    ReadingListRepository repository; // injected

    ...

    public ReadingList SaveReadingList(ReadingListForm form)
    {
        this.validator.ValidateAndThrow(form);

        // ugly global dependency :(
        ReadingList readingList = Mapper.Map<ReadingListForm, ReadingList>(form);

        this.repository.Save(readingList);
        return readingList;
    }

I don’t want to have to set up the Mapper when I’m testing ReadingListService’s interaction with the repository, validator, etc — especially because this particular mapping scenario uses custom resolvers which in have services injected into them as well (yawn).

Instead, I can break this dependency by replacing the Mapper reference with an instance of IMapperEngine, which has methods with the same signature as Mapper.Map:

public class ReadingListService : IReadingListService
{
    IValidator<ReadingListForm> validator; // injected
    ReadingListRepository repository; // injected
    IMappingEngine mapper; // injected!

    ...

    public ReadingList SaveReadingList(ReadingListForm form)
    {
        this.validator.ValidateAndThrow(form);

        // now mockable just like validator and repository :)
        ReadingList readingList = this.mapper.Map<ReadingListForm, ReadingList>(form);

        this.repository.Save(readingList);
        return readingList;
    }

I can now mock out AutoMapper, and use it A) to test that AutoMapper gets called in the appropriate scenarios B) to streamline other tests by just returning a known value etc.

The Mapper class holds a singleton to IMapperEngine in its Engine property, so you can register this with your IoC container etc.

May 7th, 2009 | 3 Comments

This is the second half of a two-part article. Read the first half here: Domain entities vs presentation model objects.

In my last post, I wrote about the difference between domain entities and presentation model objects. Remember my two task classes — the transactional domain entity and the UI presentation object? They’re very similar, and this could lead to a lot of ugly hand-written plumbing code mapping fields on one to the other.

// Task domain entity.
public class Task
{
    public int Id;
    public string Name;
    public DateTime? DueDate;
    // ...etc.
}

// Task presentation model object.
public class TaskView
{
    public int Id;
    public string Name;
    public string DueDate;
    public bool IsUnscheduled;
    public bool IsOverDue;
    public long SortIndex;
}

Instead, I’m using an open-source .NET library called AutoMapper by Jimmy Bogard — an object-object mapper (OOM) that sets values from one type to another.

Setting up a map from one type to another is dead simple — AutoMapper will automatically match fields with the same name. For other stuff we use lambda expressions, or delegate to another class. Here’s what my Task-to-TaskView mapping looks like:

// Set up a map between Task and TaskView. Note fields with the same names are
// mapped automagically!
Mapper.CreateMap<Task, TaskView>()
    .ForMember(dest => dest.DueDate, opt => opt.AddFormatter<DueDateFormatter>())
    .ForMember(dest => dest.SortIndex, opt => opt.ResolveUsing<SortIndexResolver>());

That was easy! Note I’m using a custom value formatter for the DueDate:

public class DueDateFormatter : IValueFormatter
{
    public string FormatValue(ResolutionContext context)
    {
        DateTime? d = context.SourceValue as DateTime?;

        if (d.HasValue)
            return d.Value.ToString("dddd MMM d");
        else
            return "Anytime";
    }
}

…and a custom resolver for the sort index (an integer derived from the task’s due date). Note that, while a formatter transforms one field by itself; a resolver examines the whole object to derive a value:

public class SortIndexResolver : IValueResolver
{
    public ResolutionResult Resolve(ResolutionResult source)
    {
        Task t = source.Value as Task;

        DateTime sortDate = t.DueDate.HasValue ?
            t.DueDate.Value : DateTime.MaxValue;

        long sortIndex =
            Convert.ToInt64(new TimeSpan(sortDate.Ticks).TotalSeconds);

        return new ResolutionResult(sortIndex);
    }
}

With dedicated classes for formatting and resolving values, tests become very easy to write (although I did write my own ShouldFormatValueAs() test helper extension method):

[TestFixture]
public class When_displaying_a_due_date
{
    [Test]
    public void Should_display_null_values_as_anytime()
    {
         new DueDateFormatter().ShouldFormatValueAs<DateTime?>(null, "Anytime");
    }

    [Test]
    public void Should_format_date()
    {
        new DueDateFormatter().ShouldFormatValueAs<DateTime?>(
                new DateTime(2009, 02, 28), "Saturday Feb 28");
    }
}

Putting it to practice, it becomes a one-liner to create a new TaskView instance given a Task.

// Grab a Task from the repository, and map it to a new TaskView instance.
Task task = this.tasks.GetById(...);
TaskView taskView = Mapper.Map<Task, TaskView>(task);

Awesome!

March 2nd, 2009 | 3 Comments