# Friday, May 29, 2009

I have a few issues with the standard ASP.NET MVC view engine.  First off it is too verbose…you have type too much and in my opinion the views don’t look like html.  Luckily there are alternatives.  One of the most popular ASP.NET MVC view engine replacements is Spark.  Spark is replacement view engine that allows you to type less and makes your Views much easier to read.  So for part 3 of NerdDinnerAdvanced I am replacing the built in ASP.NET MVC view engine with Spark.

Replacing the view engine in the NerdDinnerAdvanced project was very straight forward.  Here are the steps.

    1. Reference Spark.dll and Spark.Web.MVC.dll in NerdDinnerAdvanced.UI
    2. Register Spark as a view engine in Global.asax Application_Start
      /// <summary>
      /// Application Start
      /// </summary>
      protected void Application_Start() {
          //Wire Up Spark as our ViewEngine (Step 1)
          //Initialize IoC
          //Wire up controller factory
          ControllerBuilder.Current.SetControllerFactory(new IoCControllerFactory());
    3. Add a declaration for the Spark configuration section to the Web.config
      <!-- Spark Config Section Declaration (Step 2) -->
      <section name="spark" type="Spark.Configuration.SparkSectionHandler, Spark"/>
    4. Add Spark configuration to the Web.config
      <!-- Spark Configuration Section -->
          <compilation debug="true">
              <add assembly="NerdDinnerAdvanced.UI"/>
              <add assembly="System.Web.Mvc, Version=, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
              <add namespace="System.Collections.Generic"/>
              <add namespace="System.Linq"/>
              <add namespace="System.Web.Mvc"/>
              <add namespace="System.Web.Mvc.Html"/>
              <add namespace="System.Web.Mvc.Ajax"/>
              <add namespace="NerdDinnerAdvanced.Domain.Models" />
          <use content="MainContent" />
    5. Create Spark master page

      How master pages are implemented in Spark is very cool.  I am not going to go into details all the ways you can implement master pages in Spark, but you can check it out here.  I am going to use the default behavior in which Spark will look for a file name Application.spark in either the Views/Layout or Views/Shared folders and will apply that to all the views in project.  So I no longer have to explicitly tell my view what master to use. So to setup our master page we need to;

      1. Add a new class file under Views –> Shared and name it Application.spark.
      2. Copy all the code from Site.master into Application.spark
      3. Remove the Page directive
      4. Remove the title content place holder
      5. Replace the main content place holder with Spark content div
        <div id="content">
      6. Replace all '<%= xxx %>' with '${ xxx }'
      7. You should end up with…
        <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
        <html xmlns="http://www.w3.org/1999/xhtml">
        <head runat="server">
            <link href="../../Content/Site.css" rel="stylesheet" type="text/css" />
            <script src="/Scripts/MicrosoftAjax.js" type="text/javascript"></script>
            <script src="/Scripts/MicrosoftMvcAjax.js" type="text/javascript"></script>    
            <script src="/Scripts/jQuery-1.3.2.js" type="text/javascript"></script>
            <div class="page">
                <div id="header">
                    <div id="title">
                        <h1>Nerd Dinner For The Real World</h1>
                    <div id="logindisplay">
                        <% Html.RenderPartial("LogOnUserControl"); %>
                    <div id="menucontainer">
                        <ul id="menu">              
                            <li>${ Html.ActionLink("Find Dinner", "Index", "Dinners")}</li>
                            <li>${ Html.ActionLink("Host Dinner", "Create", "Dinners")}</li>
                            <li>${ Html.ActionLink("About","About","Home") }</li>
                <div id="main">
                    <div id="content">
                        <use content="MainContent" />
                    <div id="footer">
    6. Convert our first page.  Home/Index.aspx
      1. Rename Index.aspx to Index.spark
      2. Remove Page directive
      3. Remove Title content
      4. Replace ASP main content tag with Spark main content tag
      5. Replace all '<%= xxx %>' with '${ xxx }'
    7. Now we ran it!  What to notice here is first of all it runs.  The second thing to notice is the really cool part.  We are seeing a view created using the Spark View Engine but we are displaying a partial view created using the standard ASP.NET MVC View Engine.  The Log In/Out user control is still being rendered by the default view engine.
    8. Now we are ready to convert the remaining pages.  One difference from the built in view engine is how you tell the view about the model.  You need to explicitly specify what model the view uses.
      <viewdata model="NerdDinnerAdvanced.UI.Utility.PaginatedCollection<NerdDinnerAdvanced.Domain.Models.Dinner>"/>

The complete code can be downloaded here.  Stay tuned for part 4.

posted on Friday, May 29, 2009 11:05:00 PM (Central Daylight Time, UTC-05:00)  #    Comments [7]
# Wednesday, May 27, 2009

In part 2 of the NerdDinnerAdvanced code I replaced the LinqToSql DAL with a DAL that uses NHibernate.  NHibernate is an open sourced object relational mapper.  If you are not familiar with ORM and/or NHibernate I highly suggest you check them out.  Because of the way we architected our project in Part 1 implementing an NHibernate DAL had little to no impact on any code above the DAL.

To start I re-structured the project a little.  I created a NerdDinnerAdvanced.Data.LinqToSql project and moved the LinqToSql DinnerRepository and the NerdDinner.dbml file into the new project.  This left just the IDinnerRepository in the NerdDinnerAdvanced.Data project.  You could certainly move the IDinnerRepository class to the NerdDinnerAdvanced.Common project and remove the NerdDinnerAdvanced.Data project if you wish.


Now it was time to create my NHibernate mappings.  If you are not familiar with how ORM’s work the basic concept is that the ORM framework maps data from a database to your entity/domain objects In order to accomplish this you need to tell the ORM what tables/columns map to what objects/fields and this is typically done via an XML file.  In this case we only have 2 objects to map, Dinner and Rsvp, so the mapping would not be complex.  Often, though, you are dealing with hundreds of objects with a lot of fields and the management of the XML mapping files can get very difficult.  For this reason, and because I wanted to have a chance to play with it, I decided to use Fluent NHibernate to do my mapping.  Fluent NHibernate allows you to do your mappings using strongly typed C# code.

In my NerdDinnerAdvanced.Domain project I created a new folder called Mappings and added two mapping classes, one for each of my two domain objects.



Because this is not a Fluent NHibernate tutorial I am not going to go into detail on how you create the mappings…and for the most part it is fairly intuitive.

 /// <summary>
 /// Fluent NHibernate mapping for the Dinner class
 /// </summary>
 public class DinnerMap : ClassMap<Dinner> {
     public DinnerMap() {
         SetAttribute("lazy", "false");
         Id(x => x.DinnerId);
         Map(x => x.Title);
         Map(x => x.Description);
         Map(x => x.EventDate);
         Map(x => x.HostedBy);
         Map(x => x.Address);
         Map(x => x.Country);
         Map(x => x.ContactPhone);
         Map(x => x.Latitude);
         Map(x => x.Longitude);
         HasMany(x => x.Rsvps).Inverse().KeyColumnNames.Add("DinnerId").Cascade.All().SetAttribute("lazy", "false");

Next it was time to create the NHibernate DAL so I added a NerdDinnerAdvanced.Data.NHibernate project to the solution.  The first thing you have to do when using NHibernate, after creating your mapping files, is create your NHibernate Session class.  Session to NHibernate is like DataContext to Linq.   The Session for the most part contains connection string and mapping info and it is the mediator between you and your data.

    /// <summary>
    /// NHibernate session factory
    /// </summary>
    public class SessionFactory {

        public static ISessionFactory CreateSessionFactory() {
            return Fluently.Configure()
                .Database(MsSqlConfiguration.MsSql2005.ConnectionString(c => c.Is("Data Source=keith-166938fd4;Initial Catalog=NerdDinner;Integrated Security=True")))  
                .Mappings(m =>  m.FluentMappings.AddFromAssemblyOf<Dinner>())  

After creating the NHibernate Session class I can now implement my DinnerRepository using NHibernate.  Below is an example of the FindAllDinners method.

        /// <summary>
/// Returns a list of all dinners
/// </summary>
/// <returns>List of all dinners</returns>
public IQueryable<Dinner> FindAllDinners() {
var sessionFactory = SessionFactory.CreateSessionFactory();
using (var session = sessionFactory.OpenSession()) {
using (session.BeginTransaction()) {
return session.CreateCriteria(typeof(Dinner)).List<Dinner>().AsQueryable();

After completing the DinnerRepository we can tell our application to use the the new DAL by changing one line in our InversionOfControlHelper class.

        /// <summary>
        /// Initializes the inversion of control mappings
        /// </summary>
        public static void Initialize() {
//Tell Structure Map we are using Fluent mapping rather than onfiguration file based mapping! StructureMapConfiguration.UseDefaultStructureMapConfigFile = false;
//This is the only line of code outside of the DAL that needed to be modified to implement the NHibernate data access layer! //StructureMapConfiguration.BuildInstancesOf<IDinnerRepository>().TheDefaultIsConcreteType<Data.LinqToSql.DinnerRepository>();

Once again the complete source can be downloaded here.  Stay tuned for Part 3!

posted on Wednesday, May 27, 2009 8:52:17 AM (Central Daylight Time, UTC-05:00)  #    Comments [13]
# Saturday, May 16, 2009

The first chapter of Professional ASP.NET MVC 1.0 walks you through creating the basic NerdDinner site.  This is a great introduction to ASP.NET MVC but really isn’t something you could as reference for creating a real world ASP.MVC site.  With this in mind I set out on a multi part project to create a real world ASP.NET reference application based on the base NerdDinner code.

It the first installation of what I am calling NerdDinnerAdvanced I extended the base NerdDinner code in the following ways;

    • Created 3-tier architecture.  One of the major misconceptions about ASP.NET MVC is that it is a UI framework.  I think this is mainly due to the fact that the major changes that developers need to wrap their head around are in the UI.  To help alleviate this misconception I structured the MVC project architecturally that developers who have experience in n-tier architecture will find familiar.
       The layers, as you can see highlighted above, are UI, Business, and Data.  Because of the overall simplistic nature of the underlying code I did not include a Service layer.  The other projects are shared by the layers.  The Domain project contains my models and the Common project contains common utility classes.


    • The base NerdDinner code used LINQ to SQL and was content with passing the LINQ to SQL entities between the layers of the application.  I would guess that Mr. Gu did this for simplicity and brevity and not a show of best practice.  If you are asking yourself what is wrong with architecting around LINQ to SQL entities I would recommend picking up Dino Esposito’s latest book.  The main reason is that you are tightly coupling yourself to the database.  So in my Domain project I created a Models namespace and created Dinner, Rsvp, and DinnerFormView domain objects.


    •   Implemented Inversion Of Control/Dependency Injection using Structure Map.  The base NerdDinner code used manual IoC/Di in the DinnersController but I decided to take that a step further because I am on a bit of an Ioc/Di fix lately.  I implemented it on the repository and the dinner services business object as well as the Dinner and Rsvp controllers.


    • Implemented a full suite of unit testing using MOQ for mocking objects.

The code can be downloaded here.  Stay tuned for the next installment which will include nHibernate as the DAL.

posted on Saturday, May 16, 2009 4:10:32 PM (Central Daylight Time, UTC-05:00)  #    Comments [6]