NerdDinner with Fluent NHibernate Part 1 - The domain model

Monday, 10 August 2009 06:00 by bengtbe

This is the first post in a series of three where I'm going to see how we can change the NerdDinner project to use Fluent NHibernate instead of LINQ to SQL:

Introduction

NerdDinner.com is a site where you can organize dinner meetings for nerds, but even more, it is a great tutorial to the ASP.NET MVC framework. If you want to learn this framework (you should!) download the free tutorial (186 pages) from the site and get going!

NerdDinner uses LINQ to SQL as a data access layer generator. LINQ to SQL is perfectly suitable for this project, since the domain is small, and not very complex. However in these posts I would like to explore how the project would look using a real Object/Relational Mapper (O/RM). More specifically, I'm going to use Fluent NHibernate. 

Preperations

First I downloaded the latest source code from CodePlex using the Subversion client TortoiseSVN. Then I added references to the NHibernate, Fluent NHibernate, and LINQ to NHibernate assemblies.

The existing domain model

Most of the domain model in NerdDinner is auto generated from the database as partial classes by the LINQ to SQL designer. You can find the Dinner and RSVP class in the NerdDinner.Designer.cs file; however since they are auto generated they are not very readable.

The Dinner class is also extended (using partial classes) with additional methods in the Dinner.cs file.

The new domain model

Since most of the existing domain model is auto generated we need to write a new domain model. The new Dinner class looks as follows:

public class Dinner

{

    public Dinner()

    {

        RSVPs = new List<RSVP>();

    }

 

    public virtual int DinnerID { get; private set; }

    public virtual string Title { get; set; }

    public virtual string Description { get; set; }

    public virtual DateTime EventDate { get; set; }

    public virtual double Latitude { get; set; }

    public virtual double Longitude { get; set; }

    public virtual string Country { get; set; }

    public virtual string Address { get; set; }

    public virtual string HostedBy { get; set; }

    public virtual string ContactPhone { get; set; }

 

    public virtual IList<RSVP> RSVPs { get; private set;}

 

    public virtual void AddRSVP(string attendeeName)

    {

        if (dinner.IsUserRegistered(User.Identity.Name)) return;

 

        RSVPs.Add(new RSVP

                      {

                          AttendeeName = attendeeName,

                          Dinner = this

                      });

    }

 

    public virtual bool IsHostedBy(string userName) { ... }

    public virtual bool IsUserRegistered(string userName) { ... }
    public virtual bool IsValid { ... }

    public virtual IEnumerable<RuleViolation> GetRuleViolations() { ... }

}

The new RSVP class looks as follows:

public class RSVP

{

    public virtual int RsvpID { get; private set; }

    public virtual Dinner Dinner { get; set; }

    public virtual string AttendeeName { get; set; }

}

If you wonder why every method is marked by virtual, this is a requirement of NHibernate in order to support Lazy-Loading. I explained this in more detail in the post Mapping a Twitter like domain with Fluent NHibernate.

The public interface of the domain model is more or less identical to the existing domain model. However I did make some changes.

Protect thy privates!

One of the changes I made was to make some of the property setters private; DinnerID, RSVPs, and RsvpID. Since the consumer code (the controllers) is not supposed to change to these properties we want to communicate this to our fellow programmers. The next change is also about protecting privates.

New method to add a RSVP to a dinner

To the Dinner class I added a new method called AddRSVP. By using terms from Domain Driven Design, the Dinner entity is the aggregate root of the RSVP entity. This basically means that a RSVP must belong to a Dinner; hence I want the Dinner class to control the list of RSVPs.

This change will help reduce code in the controllers and remove duplication. Previously the creating and adding of RSVPs was done both in the RSVPController.Register and the DinnerController.Create action methods. The Register method is shown below:

[Authorize, AcceptVerbs(HttpVerbs.Post)]

public ActionResult Register(int id) {

 

    Dinner dinner = dinnerRepository.GetDinner(id);

 

    if (!dinner.IsUserRegistered(User.Identity.Name)) {

 

        RSVP rsvp = new RSVP();

        rsvp.AttendeeName = User.Identity.Name;

 

        dinner.RSVPs.Add(rsvp);

        dinnerRepository.Save();

    }

 

    return Content("Thanks - we'll see you there!");

}

Thanks to our new method, this can now be reduced to:

[Authorize, AcceptVerbs(HttpVerbs.Post)]

public ActionResult Register(int id) {

 

    Dinner dinner = dinnerRepository.GetDinner(id);

    dinner.AddRSVP(User.Identity.Name);   

 

    return Content("Thanks - we'll see you there!");

}

Similar reduction can be done to the Create method. BTW if you wonder what happened to the call to the Save method then we will come back to this in part 3 (teaser!).

As a rule of thumb always try to keep your action methods as simple as possible! 

More object-oriented

The last change is the removal of the DinnerId property from the RSVP class. This property is purly database related, and does not belong in an object-oriented domain model. You can use the Dinner propety to get the DinnerId.

finally{}

In my opinion one of the benefits of using an OR/M like NHibernate as supposed to LINQ to SQL is that the domain model is much clearer. When trying to understand a new project one of the best places to start is by looking at the domain. I also did some changes (improvements?) to the domain model to better communicate intent, and to reduce code duplication.

The next step is to tell NHibernate how to map this domain model to the database. This will be explained in the next post where we look at the mapping.

If you liked this post then please shout and kick me :)

kick it on DotNetKicks.com

Shout it

Use specific return types in your ASP.NET MVC action methods

Wednesday, 1 July 2009 19:00 by bengtbe

When looking at ASP.NET MVC examples on the web almost all action methods return ActionResult, even methods that could return a specific subclass. Here is an example from the NerdDinner source code: 

public ActionResult Index(int? page)

{

    const int pageSize = 25;

 

    var upcoming = dinnerRepository.FindUpcomingDinners();

    var paginated = new PaginatedList<Dinner>(upcoming, page ?? 0, pageSize);

 

    return View(paginated);

}

This method always returns a ViewResult, still they declare the return type as the ActionResult base class. This practice often leads to test code like the following:

ViewResult result = controller.Index(0) as ViewResult;

Assert.IsNotNull(result, "Controller should return a ViewResult");

 
In NerdDinner they even have a whole test just to make sure that the result is a ViewResult:
 

[TestMethod]

public void IndexAction_Should_Return_View()

{

    // Arrange

    var controller = CreateDinnersControllerAs("robcon");

 

    // Act

    var result = controller.Index(0);

 

    // Assert

    Assert.IsInstanceOfType(result, typeof(ViewResult));

}

 
All this testing code are unnecessary, if you just let your action methods use specific return types, like shown below:
 

public ViewResult Index(int? page)

{

    const int pageSize = 25;

 

    var upcoming = dinnerRepository.FindUpcomingDinners();

    var paginated = new PaginatedList<Dinner>(upcoming, page ?? 0, pageSize);

 

    return View(paginated);

}

This also makes it immediately clear for people reading the code, what this action method returns.

The only time I would return ActionResult is when different paths of the action method returns different subclasses. In these cases, you should of course write tests that verify the return types of the different paths.

In the book Pro ASP.NET MVC Framework Steven Sanderson also recommends returning specific types. Take a look at the quote below:

"This action method specifically declares that it returns an instance of ViewResult. It would work just the same if instead the method return type was ActionResult (the base class for all action results). In fact, some ASP.NET MVC programmers declare all their action methods as returning a nonspecific ActionResult, even if they know for sure that it will always return one particular subclass. However, it's a well-established principle in object-oriented programming that methods should return the most specific type they can (as well as accepting the most general parameter types they can). Following this principle maximizes convenience and flexibility for code that calls your method, such as your unit tests."

BTW: This blog post is not meant to criticize the NerdDinner tutorial. It is a great free tutorial, and is probably one of the best ways to get introduced to the ASP.NET MVC framework :)

kick it on DotNetKicks.com

Shout it

Using AutoMapper to map view models in ASP.NET MVC

Tuesday, 14 April 2009 06:27 by bengtbe

In projects that have complex domain models it is often necessary to map the domain models to simpler objects such as Data Transfer Objects (DTO) which is "an object that carries data between processes in order to reduce the number of method calls" or Presentation Models which "represent the state and behavior of the presentation independently of the GUI controls used in the interface".

The mapping code is often boring and tedious to write, so when I first read about AutoMapper it triggered my interest. In this post I will take a first look at AutoMapper, and show how it can be used to map a complex domain model to a view model in an ASP.NET MVC application.

About AutoMapper

The project homepage describes AutoMapper as "a fluent configuration API to define an object-object mapping strategy. AutoMapper uses a convention-based matching algorithm to match up source to destination values. Currently, AutoMapper is geared towards model projection scenarios to flatten complex object models to DTOs and other simple objects, whose design is better suited for serialization, communication, messaging, or simply an anti-corruption layer between the domain and application layer."

AutoMapper is a fairly new project; the current version is 0.30 Beta, and it seems to be in active development.

A complex domain model

The domain model that I'm going to use in this example is a Customer class that has a reference to an Address class: 

public class Customer

{

    public string FirstName { get; set; }

    public string LastName { get; set; }

    public string Email { get; set; }

    public Address HomeAddress { get; set; }

 

    public string GetFullName()

    {

        return string.Format("{0} {1}", FirstName, LastName);

    }

}

The Address class is as follows: 

public class Address

{

    public string Address1 { get; set; }

    public string Address2 { get; set; }

    public string City { get; set; }

    public string PostalCode { get; set; }

    public string Country { get; set; }

}

Ok, I admit that this domain model is not very complex, but it will serve the purpose of this post :)

The simple view model

The view is going to show a list of customers with name, email and country. We therefore create a view model called CustomerListViewModel:

public class CustomerListViewModel

{

    public string FullName { get; set; }

    public string Email { get; set; }

    public string HomeAddressCountry { get; set; }

}

I save this view model in the file ViewModel/Customers/CustomerListViewModel.cs in the web-project. In an ASP.NET MVC application the view models belong to the Web-project, they are not part of the domain model. Usually a view model belongs to a single controller, and its views.

The controller

The URL used to display the customers should be http://application/Customers/, hence the name of the controller is CustomersController, and the action used is the Index():

public class CustomersController : Controller

{

    private readonly ICustomerService m_CustomerService;

 

    public CustomersController(ICustomerService customerService)

    {

        m_CustomerService = customerService;

    }

 

    // GET: /Customers/

    public ActionResult Index()

    {

        IList<Customer> customers = m_CustomerService.GetCustomers();

 

        Mapper.CreateMap<Customer, CustomerListViewModel>();

        IList<CustomerListViewModel> viewModelList =

           Mapper.Map<IList<Customer>, IList<CustomerListViewModel>>(customers);

 

        return View(viewModelList);

    }

}

In the above controller I use Dependency Injection to inject the CustomerService in the constructor. In a previous post I have shown how to use Dependency Injection in the controllers.

When using AutoMapper you first have to create a map between the two classes:

Mapper.CreateMap<Customer, CustomerListViewModel>();

The following line maps the list of Customers to a list of CustomerListViewModel:

IList<CustomerListViewModel> viewModelList =

   Mapper.Map<IList<Customer>, IList<CustomerListViewModel>>(customers);

If you just wanted to map a single instance you would use: 

CustomerListViewModel viewModel = Mapper.Map<Customer, CustomerListViewModel>(customer);

AutoMapper will perform the following mapping automatically:

  • FullName gets its value by calling the Customer.GetFullName() method.
  • Email gets its value from the Customer.Email propery.
  • HomeAddressCountry gets its value from the Customer.HomeAddress.Country property.

The view

Below is the view used to display the view model: 

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master"

       Inherits="System.Web.Mvc.ViewPage<IEnumerable<CustomerListViewModel>>" %>

<%@ Import Namespace="MyApp.Web.ViewModels.Customers"%>

 

<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">

 

    <h2>Customer list</h2>

 

    <table>

        <tr>

            <th>Name</th>

            <th>Email</th>

            <th>Country</th>

        </tr>

    <% foreach (var customer in Model) { %>

        <tr>

            <td><%= Html.Encode(customer.FullName) %></td>

            <td><%= Html.Encode(customer.Email) %></td>

            <td><%= Html.Encode(customer.HomeAddressCountry) %></td>

        </tr>

    <% } %>

    </table>

</asp:Content>

 

<asp:Content ID="Content2" ContentPlaceHolderID="head" runat="server"></asp:Content>

As you can see from the Inherits attribute, this view is strongly typed to the IEnuerable<CustomerListViewModel>. The foreach uses the Model property to retrieve the list of CustomerListViewModel, and creates a table row for each instance.

Some advanced features of AutoMapper

In the example above I have shown some simple usages of AutoMapper. I will now take a quick look at some of its more advanced features:

Let's say that the Customer has a Birthday property of type DateTime that we want to map to a YearOfBirth property of type int

Mapper.CreateMap<Customer, CustomerListViewModel>()

    .ForMember(dest => dest.YearOfBirth, opt => opt.MapFrom(src => src.Birthday.Year));

Don't get confused by all the lamdas (=>). The ForMember method just says YearOfBirth should get its value from Birthday.Year.

AutoMapper can also help you test the mapping: 

[Test]

public void Should_be_able_to_map_Customer_to_CustomerListViewModel()

{

    Mapper.CreateMap<Customer, CustomerListViewModel>()

        .ForMember(dest => dest.ThisIsMappedElsewhere, opt => opt.Ignore());

    Mapper.AssertConfigurationIsValid();

}

In the above test AutoMapper will check to make sure that every single member on CustomerListViewModel has a corresponding member on the Customer, except for the property ThisIsMappedElsewhere that we told it to ignore.

There are many more features that I haven't covered. You can find more information in the following places:

kick it on DotNetKicks.com   Shout it

Using StructureMap with the ASP.NET MVC framework

Friday, 27 February 2009 06:13 by bengtbe

In this post I will try to show you how to use StructureMap with the new ASP.NET MVC framework. You will need to have some basic knowledge about the ASP.NET MVC framework and Dependency Injection (DI)/Inversion of Control (IoC). The method described is not limited to StructureMap; if you prefer, you can of course use another DI/IoC tool.

The example starts with a UserController that has an dependency to a IUserService in the business layer, which again has a dependency to a IUserRepository in the database layer. The UserController uses inversion of control in regards to the IUserService. This means that the concrete UserService class must be injected into the UserController through the constructur:

public class UserController : Controller

{

    private readonly IUserService m_UserService;

 

    public UserController(IUserService userService)

    {

        m_UserService = userService;

    }

 

    public ActionResult Edit(int id)

    {

        return View(m_UserService.GetById(id));

    }

}

This is also called constructor injection. If you try to access this controller in the ASP.NET MVC framework you will get the following error:

No parameterless constructor defined for this object.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.MissingMethodException: No parameterless constructor defined for this object.
 

By default, the ASP.NET MVC framework requires a parameterless constructor in the controllers. One way to fix this is to add a parameterless constructor:

public UserController() : this(new UserService(new UserRepository()))

{

}

This constructor is calling the other constructor using this passing in it's dependencies. Overloading the constructor in this manner is sometimes called Poor Man's Dependency Injection. It is a valid approach if you don't have access to an DI/IoC tool.

The downside of this approach is that you create a tight coupling between the controller and a concrete implementation of IUserService. You also have to take care of the dependencies (UserRepository) of the UserService class. Hence, the controller in the presentation layer now has a direct dependency to the UserRepository in database layer. If the UserRepository also had some dependencies then it really would start to get ugly :)

Let's fix this by using StructureMap's ObjectFactory to get an instance of IUserService.

public UserController() : this(ObjectFactory.GetInstance<IUserService>())

{

}

Much cleaner! The direct dependencies are now gone. However, every controller in your ASP.NET MVC application now needs to have an extra parameterless constructor and an reference to the ObjectFactory. This is just plumbing code, let's see if we can get rid of it all together.

The ASP.NET MVC framework uses the factory pattern to create controllers, and it also provides a base class called DefaultControllerFactory that you can derive from to customize the creation of controllers:

public class StructureMapControllerFactory : DefaultControllerFactory

{

    protected override IController GetControllerInstance(Type controllerType)

    {

        if(controllerType == null) return null;

 

        try

        {

            return ObjectFactory.GetInstance(controllerType) as Controller;

        }

        catch (StructureMapException)

        {

            System.Diagnostics.Debug.WriteLine(ObjectFactory.WhatDoIHave());

            throw;

        }

    }

}

The GetControllerInstance method is called when the framework needs a controller, specifed by its type. The code then asks StructureMap's ObjectFactory to create the controller. Since the controller is a concrete class (not an interface), it doesn't need to be configured with StructureMap. StructureMap will manage to create an instance of the controller and resolve all it's dependencies.

Now we have to tell the ASP.NET MVC framework to use the StructureMapControllerFactory. You can do this in the Application_Start method in Global.asax.cs:

protected void Application_Start()

{

    RegisterRoutes(RouteTable.Routes);

 

    StructureMapConfiguration.Configure();

 

    ControllerBuilder.Current.SetControllerFactory(new

       StructureMapControllerFactory());

}

As you can see the last line tells the framework to use the new factory. You can now remove the parameterless constructor, and the reference to StructureMap in the controllers.

Configuration of StructureMap

The second line in the Application_Start method is the configuration of StructureMap. This is done using the awesome new fluent configuration; no XML-configuration is needed!

public class StructureMapConfiguration

{

    public static void Configure()

    {

        ObjectFactory.Initialize(InitializeStructureMap);

    }

 

    private static void InitializeStructureMap(IInitializationExpression x)

    {

        x.Scan(y =>

                   {

                       y.Assembly("MvcWithNHibernate.Repositories");

                       y.Assembly("MvcWithNHibernate.Services");

                       y.With<DefaultConventionScanner>();

                   }

            );

    }

}

As you can see this uses the DefaultConventionScanner. This scanner uses a naming convention to automatically register the class UserService with the the interface IUserService, and the class UserRepository with IUserRepository.

Summary

In this post I have shown you how to use StructureMap with the new ASP.NET MVC framework. I described how you can implement your own controller factory to reduce the plumbing code in the controllers. When I first started to use StructureMap I had several calls to ObjectFactory.GetInstance throughout the solutions. A much better approach is to reduce these calls as much as possible. In this solution the only call to ObjectFactory.GetInstance is in the controller factory.

I also gave you a short glimpse of how you could configure StructureMap using the new fluent configuration and the default convention scanner. This follows the Convention over Configuration (CoC) paradigm made popular by Ruby on Rails. By following strict naming conventions, you don't need to configure the specific interfaces and classes with the DI/IoC tool, they are automatically added based on the conventions. In StructureMap you can also create your own auto register conventions.

kick it on DotNetKicks.com   Shout it