Archive for category ASP.NET MVC

Views and Databases Don’t Mix

The Problem

In my MVC applications, I sometimes bind my views directly to NHibernate entities. a lot. like always. I also do session-per-request.

I don’t remember what prompted this thought – probably Twitter – but it seemed questionable to access the database from the view by loading a lazy collection. I knew you shouldn’t put database access code in the view, but this would just be a property, nothing complex at all. Ayende set me straight.

You should avoid it. It is dangerous to do loading in the
view, it is subject to too many changes.

How do we prevent it? Of course, the simple answer is “just don’t do it.” Anything more quickly falls in the category of protecting you from yourself, of which I’m usually not a fan. Still, this is easy to overlook. The Morts of the world – and me – will fall in to this trap easily.

ViewModel Solution

What if we had some sort of model, but instead of being generic for the entire application, it only dealt with the concerns of a specific view. Oh, and what if we called it something weird like viewmodel.

This is the best way to avoid problems. Instead of binding directly to an entity, each view should have a corresponding viewmodel class, that contains all of the data being pushed down to the view as well as all the data collected by the view from the user. It’s a POCO specific to the view, with no association to the NHibernate session, so it can’t accidentally load up some data.

You can easily test your viewmodels. Since they also make your views pretty darn stupid, you can maybe skip some of that time-consuming UI testing. Well, skip it safely this time. ViewModels also work well for all that validation attribute markup. Just sayin’.

This isn’t the point of my post today, and what I’ve described isn’t the traditional Model-View-ViewModel. It’s some weird hybrid of separated presentation patterns. You can read more about view models here and here and on Jose’s Chinook Media Manager application series.

Exploding View Solution

image While I can’t say it’s worse than something silently breaking, I don’t like the idea of something bad silently working. Fragile code only works until the worst possible moment.

So, without going for a full ViewModel implementation, I thought it would be a good thing (or at least slightly better) to make NHibernate throw an exception when we hit the DB in the view so we have to fix it now while we’re debugging instead of later. I initially had thoughts about interceptors or connection providers and all sorts of craziness. Ayende’s answer is simply to close the session at the controller boundary.

How do we implement this? We close the session between the controller action and the view. So, instead of session per (the entire) request, we trim the scope at the end just a bit.

Let’s take a high-level look at a chunk of the ASP.NET MVC lifecycle:

  1. A controller action is chosen based on the request and action filters like HttpGet or HttpPost.
  2. The action (the actual controller method) executes, returning an action result – a ViewResult, RedirectToActionResult, ContentResult, or some other built-in or custom action result.
  3. The action result executes. In the case of a ViewResult, the view is rendered down to actual HTML and written out to the response stream.

We need to close down the session between #2 and #3. Lucky for us, every controller has an overloadable / overridable method called OnResultExecuting. This method gets called just before the action result is executed. We can simply override this method in our application’s base controller class. You have one of those, right? They’re handy for all sorts of stuff.

Just close down any session we may have open inside OnResultExecuting. Considering the references, this takes a little bit of plumbing, but I’ll leave that up to you since it’s dependent on your method of opening and tracking NHibernate sessions through the request.

One last thing

Maybe in a later version of NH Profiler, the problem I described today will trigger an alert. Maybe not.

If you’re using NHibernate without NH Profiler, you’re either writing substandard code or wasting time – probably both. If you don’t believe me, download a trial and see what it tells you about your last NHibernate app.

Tags:

Part 7: NHibernate and Ninject for ASP.NET MVC

In part 6, I explained how to set up Ninject with ASP.NET MVC. In this part, we’ll add NHibernate to the mix. Specifically, we’re going to set up session-per-request using a Ninject and bind all the necessary NHibernate interfaces.

Of course, for the sake of history, read up on part 1, part 2, part 3, part 4, part 5, and part 6.

If you aren’t familiar with NHibernate in an ASP.NET MVC application, the most common way to manage your sessions is to open one session per web request. Just about everything you need to know about session-per-request is explained in the content and comments of this post on Ayende’s blog, but I’ll summarize for you.

  • While building a session factory may be a big operation, once it’s built, opening a session is lightweight.
  • Opening a session does not open a connection to the database
  • NHibernate has a built in method for doing session-per-request, but Ayende doesn’t use it for simple stuff and neither will we. When your application doesn’t do anything other than session-per-request, it’s just easier to do it this way.
  • Multiple business transactions and therefore multiple sessions in a single web request are usually not necessary, just because of how users tend to interact with the application. Even then, you can usually accomplish the same thing with multiple DB transactions on the same session.

SessionPerConversation

NHibernate Burrow is available to help with complex session management in web apps where session per conversation is used. Basically, this allows you to span your NHibernate sessions across several web requests. Just a quick note: If you disregarded everyone’s advice and used Identity (integer auto-number) ID fields, Burrow won’t work for you. If you want more information, check out the Burrow posts on NHForge. Also,  Jose Romaniello’s uses Conversation per Business Transaction in his NHibernate and WPF series on NHForge.org. It’s definitely worth a read.

OK. Back to session-per-request. I’m taking a slightly different approach than Ayende. Even though opening a session is lightweight, I don’t like the idea of opening a session for requests that may not use NHibernate at all. For example, in an application I’m building at work, only about 7 views out of nearly 50 actually use an NHibernate session. That’s a lot of unused sessions.

First things first, we need to make a Ninject module for all of our NHibernate bindings. Where are we going to put it? We have two options. We could put it in NStackExample.Data with all of our NHibernate mappings and configuration. We could also put it in NStackExample.Web. Like Ayende, we will be storing the NHibernate session in the context of the current web request and relying on our application’s EndRequest event to close the session. Since we’re unfortunately coupled to the web application, we’ll put it in the web project.

  1. In the web project, make a new folder called Code.
  2. Make a class in that folder called NHibernateModule.
  3. NHibernateModule should inherit from Ninject.Core.StandardModule.

The process of configuring NHibernate is a lot of work and only needs to be done once. Since our configuration object also creates the session factory, another potentially heavy operation, we kill two birds with one stone. The binding for our NHibernate configuration looks like this:

    Public Overrides Sub Load()
        Dim Cfg As New NStackExample.Data.Configuration
        Cfg.Configure()

        Bind(Of NStackExample.Data.Configuration).ToConstant(Cfg)
    End Sub
    public override void Load()
    {
        NStackExample.Data.Configuration Cfg = new NStackExample.Data.Configuration()
        Cfg.Configure();

        Bind().ToConstant(Cfg);
    }

ToConstant bindings essentially create singletons, at least within the scope of our Ninject kernel. Unlike true singletons, this isn’t evil because our tests are free to mock, replace, and re-implement them as necessary.

Now that we have NHibernate configured and our session factory built, we need to bind our NHibernate session. The scope of our session is somewhat complex (per-request). We could use the OnePerRequestBehavior of Ninject, but that requires the registration of an IIS HTTP module. Instead, we’ll just bind it to a method and manage it ourselves. This method will create up to one session per request. If a particular request doesn’t require a session, Ninject will never call the method, so an unnecessary session won’t be created. If a particular request asks for a session more than once, perhaps to build more than one DAO, the method will create a single session and use it throughout the web request. Here’s what our module looks like with the binding for our session:

    Friend Const SESSION_KEY As String = "NHibernate.ISession"

    Public Overrides Sub Load()
        Dim Cfg As New Configuration
        Cfg.Configure()

        Bind(Of Configuration).ToConstant(Cfg)
        Bind(Of NHibernate.ISession).ToMethod(AddressOf GetRequestSession)
    End Sub

    Private Function GetRequestSession(ByVal Ctx As IContext) As NHibernate.ISession
        Dim Dict As IDictionary = HttpContext.Current.Items
        Dim Session As NHibernate.ISession
        If Not Dict.Contains(SESSION_KEY) Then
            'Create an NHibernate session for this request
            Session = Ctx.Kernel.Get(Of Configuration)().OpenSession()
            Dict.Add(SESSION_KEY, Session)
        Else
            'Re-use the NHibernate session for this request
            Session = Dict(SESSION_KEY)
        End If
        Return Session
    End Function
        internal const string SESSION_KEY = "NHibernate.ISession";

        public override void Load()
        {
            Configuration Cfg = new Configuration();
            Cfg.Configure();

            Bind<Configuration>().ToConstant(Cfg);
            Bind<NHibernate.ISession>().ToMethod(x => GetRequestSession(x));
        }

        private NHibernate.ISession GetRequestSession(IContext Ctx)
        {
            IDictionary Dict = HttpContext.Current.Items;
            NHibernate.ISession Session;
            if (!Dict.Contains(SESSION_KEY))
            {
                // Create an NHibernate session for this request
                Session = Ctx.Kernel.Get<Configuration>().OpenSession();
                Dict.Add(SESSION_KEY, Session);
            } else {
                // Re-use the NHibernate session for this request
                Session = (NHibernate.ISession) Dict[SESSION_KEY];
            }
            return Session;
        }

All we have left to do is dispose our session at the end of the request. Let’s go back to the Global.asax codebehind.

    Private Sub MvcApplication_EndRequest(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.EndRequest
        If Context.Items.Contains(NHibernateModule.SESSION_KEY) Then
            Dim Session As NHibernate.ISession = Context.Items(NHibernateModule.SESSION_KEY)
            Session.Dispose()
            Context.Items(NHibernateModule.SESSION_KEY) = Nothing
        End If
    End Sub
        public MvcApplication()
        {
            this.EndRequest += MvcApplication_EndRequest;
        }

        private void MvcApplication_EndRequest(object sender, System.EventArgs e)
        {
            if (Context.Items.Contains(NHibernateModule.SESSION_KEY))
            {
                NHibernate.ISession Session = (NHibernate.ISession) Context.Items[NHibernateModule.SESSION_KEY];
                Session.Dispose();
                Context.Items[NHibernateModule.SESSION_KEY] = null;
            }
        }

To illustrate how this will work, I’ve made several additions to the code download. I’ve added a BaseController and HomeController so we can begin to run our web application. I’ve also added a IStudentDao and ICourseDao interfaces to the core project and corresponding implementations in the Data project. I’ve bound the DAO interfaces to their corresponding implementations and added debug statements to output exactly what’s happening with our session. Finally, I’ve set up a constructor in HomeController making it dependent on IStudentDao and ICourseDao.

When we run our application, we see from the debug output that the session is created when we create our IStudentDao. The session is reused to create our ICourseDao. This gives us everything we need to create the HomeController. The web request executes. When the request ends, the session is disposed. If you remove one of the Dao dependencies from HomeController, you’ll see that our session is created. It’s not reused because nothing else needs a session. If you remove both of the Dao dependencies from HomeController, you’ll see that our session is never even created. Since we didn’t create a session, we don’t dispose it when the web request ends.

That’s all for part 7. In part 8, we’ll wrap the NHibernate transaction for use in our controllers project and build a real DAO or two.

Get your code here! We have VB.NET and CSharp flavored bits.

Jason

- NHibernating Ninja Wannabe

Part 6: Ninject and MVC or How to be a Web Ninja

NinjectNope. I don’t mean this guy. He’s cool – well, maybe, maybe not – but I was thinking less comedic assassin and more dependency injection (DI.) Ninject is the illegitimate brain child of Nate Kohari, and the subject of today’s post. For those of you looking for another NHibernate fix, we’ll set up session-per-request in part 7.

If you’re new here, you can check out Part 1, Part 2, Part 3, Part 4, and Part 5 to catch up. Grab the latest source from the end of Part 5.

If you remember back in the part 1, I said we’d be using Ninject v1. I lied. We’ll be using v1.5. This is the version built by horn, and the version that includes Ninject.Framework.MVC.dll. Save yourself some time. Go get the source for horn, build it, and then let horn build Ninject, Fluent NHibernate, and MVCContrib.

Let’s talk about Ninject’s constructor dependency injection. Say you have an AccountBuilder object that builds up a user account object from some fields on a “new user” form and saves it to the database. That’s a pretty complicated task for just one object. You should split off the persistence responsibility to a DAO or Repository and the password hashing / encryption to a password service. The AccountBuilder doesn’t care how the DAO saves the data, just that it does. It also doesn’t care how the password is secured. AccountBuilder has a dependency on each of these services. If ever there was a time to code to interfaces, this is it. The constructor looks like this:

Public Sub New(DAO As ISaveUserAccounts, PwdHasher As IHashPasswords)
public AccountBuilder(ISaveUserAccounts DAO, IHashPasswords PwdHasher)

The details of the constructor aren’t important, only the signature. AccountBuilder is a concrete type, meaning we can create an instance of it, so Ninject can auto self-bind it. We don’t have to tell Ninject ahead of time that it will be creating an AccountBuilder for us. When we ask Ninject to get an AccountBuilder for us, it checks to see if it has a binding for it (more on that in a minute). Since it doesn’t, it checks to see if it can create an object of type AccountBuilder. Since AccountBuilder isn’t abstract (MustInherit in VB.NET) or an interface, Ninject decides that it will just create an AccountBuilder for us.

it goes through all the constructors searching for one with the Inject attribute or the one with the most parameters. Once it’s decided on a constructor, it tries to resolve each of those parameters. Let’s say for a minute that instead of the interfaces, we had specified the actual concrete implementations as parameters. Ninject would resolve each of those the same way it is resolving AccountBuilder. It goes on and on recursively as deep as necessary to resolve each and every dependency until it has instances of DAO and PasswordHasher to use as parameters for the AccountBuilder constructor. Finally, it calls the constructor with those parameters and gives us our AccountBuilder.

Now, because we’ve coded to interfaces, we have to tell Ninject exactly which implementation of those interfaces we want to use. So, we tell Ninject that each time anything needs an ISaveUserAccounts, build up a new instance of UserAccountDAO. It has to be a new instance each time, because UserAccountDAO depends on NHibernate.ISession, which isn’t constant throughout the application. We’ll bind ISession to a Ninject provider. You’ll see an example of that in our application in part 7. The binding for ISaveUserAccounts looks like this:

        Bind(Of ISaveUserAccounts).To(Of UserAccountDAO)()
        Bind<ISaveUserAccounts>().To<UserAccountDAO>();

The password hasher service can be handled a little differently. Let’s suppose for a minute that encryption algorithms can be fairly heavy-weight. We don’t want to build the algorithm over and over, possibly thousands or millions of times an hour on a popular site. Even if it doesn’t bring the site to a screeching halt, it would slow it down significantly. Since the algorithm is reusable, we’re only going to build one for our entire application. Of course, your first thought is “the evil singleton anti-pattern.” Would I do that to you? Well yes, but not intentionally. We are going to create an instance of our PasswordHasher and tell Ninject to pass it out anytime our application needs an implementation of IHashPasswords. The binding looks like this:

        Bind(Of IHashPasswords).ToConstant(New PasswordHasher)()
        Bind<IHashPasswords>().ToConstant(New PasswordHasher());

Of course, if you use just one instance across your entire web, WPF, or multi-threaded application, PasswordHasher will almost certainly need to be thread-safe, but that’s another series of posts.

Now that Ninject knows what implementations to use for those parameters of our AccountBuilder constructor, it builds a new UserAccountDAO, grabs our one-and-only instance of PasswordHasher, calls the constructor and gives us our AccountBuilder. Of course, this is still a pretty basic example.

Now let’s look at ASP.NET MVC. Up to this point in the series, we’ve talked a lot about the model. Now it’s time to talk about controllers. Controllers in an MVC application manage the flow of your application from view to view, call in to the model to perform actions, and pass data between the model and the views.

Suppose our AccountBuilder is actually a service consumed by our Account controller to carry out the work of registering a new user account. If you’re new to this, you may think that we’re just going to somehow pass in the Ninject kernel to our controller and get our AccountBuilder from there. While I don’t recommend it, you can do that. You’ll essentially end up with the ServiceLocator pattern. We’re going to take this to what may seem an illogical or even perverse extreme. Why not let Ninject build your controllers and inject all of your dependencies? You won’t have any ServiceLocator clutter in your controllers. At least as far as user code goes, the controller is near the bottom of the call stack. You’re in this perfect world where EVERYTHING is injected for you. Let that sink in for a minute. You don’t have to new up a single service ever again. Just ask for it in the constructor wherever you need it. Of course, that’s an absolute and absolutes are evil for the same reason singletons are – you can’t easily prove them with tests.

But wait, doesn’t ASP.NET MVC build the controllers? Yes it does, but it doesn’t have to. Deep inside the mother ship, apparently while hiding from that guy who invented the sealed keyword, Haacked and Co.  built all sorts of extension points in to ASP.NET MVC. One of these extension points happens to be the ability to replace the default controller factory using ControllerBuilder.Current.SetControllerFactory. Just supply the type of your new controller factory implementation.

So, you set up a controller factory to resolve the controllers using Ninject and register all of your controllers with the kernel, right? Wrong. Well, not exactly. Ninject.Framework.MVC has all of that pre-built for you – just use it. Ninject actually has an implementation of HttpApplication that will set up all of this for you. In your Global.asax codebehind file, inherit from Ninject.Framework.Mvc.NinjectHttpApplication. You’ll still have to register your routes. You also have to build the Ninject kernel with all of your ninject modules.

A ninject module is a class that sets up your bindings. So for instance, if you have a module for binding your DAO interfaces to their implementations, it might look something like this:

Public Class DaoModule
     Inherits StandardModule

     Public Overrides Sub Load()
          Bind(Of ISaveUserAccounts)().To(Of UserAccountDao)()
          Bind(Of ILookupUserAccounts)().To(Of UserAccountDao)()
          Bind(Of IUserAccountDao)().To(Of UserAccountDao)()
          Bind(Of ISaveContacts)().To(Of ContactDao)()
          ' and so on...
     End Sub

End Class
public class DaoModule : StandardModule
{
    public override void Load()
    {
        Bind<ISaveUserAccounts>().To<UserAccountDAO>();
        Bind<ILookupUserAccounts>().To<UserAccountDAO>();
        Bind<IUserAccountDao>().To<UserAccountDAO>();
        Bind<ISaveContacts>().To<ContactDAO>();
        // and so on...
    }
}

Of course, we haven’t built any DAOs to bind yet. We haven’t built any controllers to bind yet either. That brings up another point. If there is a single point of constant change during the development of your application, it will most likely be the controllers. Will you always remember to bind new controllers as you build them? Yeah, neither will I. Wouldn’t it be nice if Ninject just went looking for them instead? That’s exactly what AutoControllerModule is for. Just point it at an assembly. It will find all of your controllers and wire them in to Ninject and its controller factory.

At this stage, our Global.asax codebehind looks something like this:

Imports Ninject.Framework.Mvc
Imports Ninject.Core

Public Class MvcApplication
    Inherits NinjectHttpApplication

    Protected Overrides Function CreateKernel() As Ninject.Core.IKernel
        Dim ControllerModule As New AutoControllerModule( _
            GetType(NStackExample.Controllers.BaseController).Assembly)
        Dim Kernel As IKernel = New StandardKernel(ControllerModule)
        Return Kernel
    End Function

    Protected Overrides Sub RegisterRoutes(ByVal routes As System.Web.Routing.RouteCollection)
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}")

        ' MapRoute takes the following parameters, in order:
        ' (1) Route name
        ' (2) URL with parameters
        ' (3) Parameter defaults
        routes.MapRoute( _
            "Default", _
            "{controller}/{action}/{id}", _
            New With {.controller = "Home", .action = "Index", .id = ""} _
        )
    End Sub

End Class

If you don’t want Ninject invading your application that deeply, with a good understanding of Ninject and controller factories, you can easily do all of this by hand. Still, I’m pretty confident Nate wrote better code and tests than most of us would have.

That’s it for part 6. In part 7, we’ll wire up NHibernate to Ninject, talk about our options for session handling in a web app, and set up session-per-request. With a bit of luck, part 7 will be out this weekend. 

Once again, these are just my practices, not necessarily best practices. As always, feedback welcome, flames by appointment only.

Jason

- 6 down, 52 to go. maybe.

How-To: Using the N* Stack, part 2

Last Saturday, I posted the first part in a series about building an ASP.NET MVC application from the ground up using NHibernate and Ninject. It dealt with setting up the structure of your solution and referencing some 3rd party assemblies.

In part 2, we’re going to set up the persistence object model. The persistence object model is a set of objects that we use to persist (save) data to the database.

Warning: This is a sample application. There are widely varying opinions on the correct structure for these types of applications. As with most advanced subjects in the ALT.NET space, Ayende has some great information on the difference between a persistence object model and a domain model. For the purposes of this series, they’re the same thing.

First, we build the structure of our persistence model as plain old CLR objects (POCO). I like to do this in the Visual Studio class designer. It helps keep me focused on the high-level entities and relationships instead of wandering off to do detailed implementation code.

Here’s the model we’ll start with:

image

Let’s look at the relationships between courses and sections. We have a one to many relationship from a Course to it’s Sections represented by an ICollection(Of Section) property in Course. We also have a many-to-one relationship from each section back to it’s Course represented by the Course property on Section.

Public Class Course

    Public Property Sections() As ICollection(Of Section)
        Get

        End Get
        Set(ByVal value As ICollection(Of Section))

        End Set
    End Property

End Class

Public Class Section

    Public Property Course() As Course
        Get

        End Get
        Set(ByVal value As Course)

        End Set
    End Property

    'Other properties here...

End Class
public class Course
{

    public ICollection<Section> Sections {
        get { }

        set { }

    }

}

public class Section
{

    public Course Course {
        get { }

        set { }

    }

    //Other properties here...

}

Now that we have all of that built, there’s a couple of small requirements to use these classes with NHibernate.

  1. All properties and methods must be overridable. That’s virtual for your C# folks.
  2. Unless you’re using a dependency injection bytecode provider, you need a parameter-less constructor. If you don’t know what a bytecode provider is, don’t worry about it. We’ll get in to it later on in the series. If you don’t have any constructors, you’re fine. There’s an implied parameterless constructor. As soon as you add a constructor with parameters, you’ll need to create one without parameters, just for NHibernate.
  3. You need some sort of identity property for your database primary key. This can be inherited from a base class, which is exactly what we’re going to do. Edit: Not true. Thanks for the correction Ayende!
  4. In the case of readonly properties, you have some options. You can tell NHibernate your naming convention for backing fields. I don’t like this. I prefer to make my properties read/write and make the setter protected. If you’re new to NHibernate, you’ve probably never seen this before.
    Public Class Course
        Inherits Entity
    
        Private m_Sections As ICollection(Of Section) = New HashSet(Of Section)
    
        Public Overridable Property Sections() As ICollection(Of Section)
            Get
                Return m_Sections
            End Get
            Protected Set(ByVal value As ICollection(Of Section))
                m_Sections = value
            End Set
        End Property
    
    End Class
    public class Course : Entity
    {
    
        private ICollection<Section> m_Sections = new HashSet<Section>();
    
        public virtual ICollection<Section> Sections {
            get { return m_Sections; }
            protected set { m_Sections = value; }
        }
    
    }

    This is how I set up all of my collection properties. You can manipulate the contents of the collection, but you can’t replace it with another instance without inheriting this class and overriding the property. If you were to make this property readonly, you’d have to configure NHibernate to write to m_Sections using reflection. It’s sort of a pain, and completely unnecessary. This is easier and accomplishes the same end result.

    Also, notice that we’re inheriting from a class called Entity. More on that later.

Let’s talk about the database for a minute. Each of these entity classes will eventually become a database table. What will you use for your primary keys? Fabio Maulo has a great post on the different NHibernate primary key generators. He also has this post about why identity columns probably are not the best choice.

So what’s a good choice? Well, that’s a matter of opinion. Thanks to NHibernate, I don’t go spelunking through the database much anymore, so I like guids. You really can use what you like, or rather, what your DBA likes.

Now, where are you going to put these primary keys in your objects? In my opinion, this is really a persistence detail – meaning your objects shouldn’t really be dealing with it. That’s why we’re going to keep it hidden away in the base class. Remember, we’re inheriting from Entity.

Public MustInherit Class Entity

    Private m_ID As Guid

    Public Overridable Property ID() As Guid
        Get
            Return m_ID
        End Get
        Protected Set(ByVal value As Guid)
            m_ID = value
        End Set
    End Property

End Class
public abstract class Entity
{

    private Guid m_ID;

    public virtual Guid ID {
        get { return m_ID; }
        protected set { m_ID = value; }
    }

}

That’s it for today’s post. In part 3, we’ll configure NHibernate and set up our database. For homework, we’re going to flesh out the other properties in our persistence model. Check out the source code in Visual Basic.NET or C#.

Tags: , , ,

How-To: Using the N* stack, part 1

This is the first post in a series where I show you step-by-step how to get your first ASP.NET MVC website up off the ground. By the end of this series, we’ll have a working web application for registering community college students. More importantly, you’ll have a template you can easily follow for your own projects.

In this first post, I’ll show you how to set up your visual studio solution.

In this series, we’ll use these tools:

  • ASP.NET MVC is a free, fully Microsoft-supported product that, unlike ASP.NET WebForms, gives you complete control over your application. You can use the Web Platform Installer or download the MSI installer package directly.
  • MVCContrib – This is the contrib project for ASP.NET MVC. It adds additional functionality to and makes ASP.NET MVC easier to use.
  • jQuery – This is an open-source javascript library that does just about everything, and supports every major modern browser out there. Yes, you hate javascript. You’re going to love jQuery. I promise. This is included in the ASP.NET MVC download.
  • NHibernate 2,1 is a well-known, mature, open source object relational mapper (ORM). It helps you get on with writing you application, instead of spending days, weeks, or even months writing a data access layer.
  • Fluent NHibernate – This is a library for configuring NHibernate using an english-like syntax. It saves you from hacking through dozens of XML configuration files. Scroll to the bottom of the downloads page and get the latest compiled binaries.
  • Ninject is my personal favorite dependency injection (DI) / inversion of control (IoC) framework. It allows you to automatically wire up services to your objects. If you’ve never done DI or IoC before, you’re going to have a great “ah-ha!” moment. We’ll be using version 1.

You will also need:

  • .NET Framework 3.5 SP1
  • Visual Studio 2008 SP1. The Web Dev Express version may also work. I haven’t tried it.
  • The latest version of NUnit
  • Any major database supported by NHibenate. This can range from Oracle to SQL Server to MySQL to SQLite. I’ll be using SQL server in my examples, but if you have a favorite, you can easily use that instead.

I also suggest you get some kind of source control. You’ll want to play around and experiment as we go along.

OK. You’ve downloaded all of that? Good. Let’s talk terminology for a minute.

  • MVC stands for Model-View-Controller. This separation of responsibilities allows you greater flexibility to adapt and change your application.
  • Model – This term refers to all of your entities – your business objects. In terms of a billing application, this would be your invoices, invoice items, customers, products, etc. – all of the “real-world things” your application represents.
  • View – Each view presents a specific business object in a specific way. For example, you may have a view for editing customer data and another for displaying an invoice. You can also think of views as the pages that make up your application.
  • Controller – Controllers are the glue that bind a view to a specific entity in your model. They are also responsible for all of the flow of your application from page to page.
  • Inversion of Control (IoC) is the concept that your objects do not explicitly create the services that they need. Instead, they get them from some container of services. Hence, the inversion. Your classes don’t specify a specific implementation of the service, only the type of service they need – an interface. This loose coupling allows you to easily swap out implementations of those services without having to touch every class that uses them. I’ve seen two major flavors of IoC: Service Locator and Dependency Injection.
  • A Service Locator is a central container where you specify which implementations of each service your application will use. Your objects request service implementations from the service locator. A service locator is typically a singleton, which is why I don’t like it.
  • Dependency Injection (DI) is a method of wiring your objects to the services they depend on as the object is built. These services are typically passed in as parameters on the object’s constructor. The object itself is built by the DI framework, in this case, Ninject. The process of building dependencies can be many layers deep. The Ninject Dojo has a great tutorial on dependency injection. If you’re new to IoC, it’s a great place to start learning. Once you have the “ah ha!” moment, the migraine will stop and you’ll never look at code the same again. I promise.

Setting up the solution

Disclaimer: This is how I have learned to set up my projects. I’m sure others have differing opinions. I’d love to hear them. I don’t claim to be an expert, just a curious professional looking to improve.

Setting up the project is fairly straight-forward. We’ll do almost everything through Visual Studio. Just follow these steps.

  1. Create the solution and web project

    In Visual Studio, start a new ASP.NET MVC Web Application. This template is added to Visual Studio when you install ASP.NET MVC. I’ll be calling my solution NStackExample.
    image

    There’s a few things to note here. First, we’re creating a solution directory. Second, notice how we’ve appended .Web to the name of our web project, but not the solution.

    This web project will contain all of the views. Despite the implied direction from Microsoft through the ASP.NET MVC template, it won’t contain the model or the controllers.

  2. Create a library directory

    Inside your solution directory, create a directory for all 3rd party libraries used in your project. I call mine Solution Items. The name you give it isn’t as important as the fact that you have one. So, in the example shown above, I would create the directory C:\Users\Jason\Documents\Visual Studio 2008\Projects\NStackExample\Solution items. Copy these 15 assemblies to the library directory:

    • From MVCContrib:
      • MVCContrib.dll
      • Microsoft.Web.Mvc.dll
      • System.Web.Abstractions.dll
      • System.Web.Mvc.dll
      • System.Web.Routing.dll
    • From NHibernate:
      • Antlr3.Runtime.dll
      • Iesi.Collections.dll
      • log4net.dll
      • NHibernate.dll
      • Castle.Core.dll
      • Castle.DynamicProxy2.dll
      • NHibernate.Bytecode.Castle.dll
    • FluentNHibernate.dll from Fluent NHibernate
    • From Ninject:
      • Ninject.Core.Dll
      • Ninject.Framework.Mvc.Dll
  3. Create the core project

    This is your main project. It will contain your model, as well as interfaces for any services and strategies your application will use. It will not contain the implementation of any of those services. Those go in separate, easily replaceable assemblies.

    Add a new “Class Library” project to your solution. We’ll call this project NStackExample.Core.

    Now, right click on the project and select properties, then click on the Application tab on the side. In the root namespace field, remove .Core.

    image
    We’re doing this so our entities will be named NStackExample.Entity1, NStackExample.Entity2, etc. but the assembly will be NStackExample.Core.dll, which better describes it’s purpose.

  4. Create the controller project

    Next, create another project specifically for the controllers of your MVC project. We’re going to call it NStackExample.Controllers. Yes, the Microsoft ASP.NET MVC project template already has a folder for them. We’re not going to use that folder because I think they should be better separated from the content of your website.

  5. Clean up your projects

    Delete all of these:

    • The Class.vb or Class.cs files in the Core and Controllers projects.
    • In the NStackExample.Web project, delete:
      • The Controllers folder and all of it’s contents.
      • The Models folder
      • The Microsoft AJAX script libraries in the Scripts folder
      • The Home and Account folders inside the Views folder
      • The LogOnUserControl in the Views folder

    image

  6. Set up your references

    This is pretty straight forward.

    1. First, in your web project, remove the references to System.Web.Abstractions, System.Web.Mvc, and System.Web.Routing.
    2. Next, in your web project, from the library directory we created in step 2, add references to these 10 assemblies:
      • log4net.dll
      • Microsoft.Web.Mvc.dll
      • MvcContrib.dll
      • NHibernat.Bytecode.Castle.dll
      • NHibernate.dll
      • Ninject.Core.dll
      • Ninject.Framework.Mvc.dll
      • System.Web.Abstractions.dll
      • System.Web.Mvc.dll
      • System.Web.Routing.dll
    3. In the web project, add references to the controllers project and the core project.
    4. In the controllers project, add references to these 3 assemblies:
      • log4net.dll
      • MvcContrib.dll
      • System.Web.Mvc.dll
    5. In the controllers project, add a reference to the core project.

Did you notice how we didn’t add any references in our core project? That’s intentional. When a project needs to reference your model or service interfaces, you don’t want to have required dependencies on other libraries and frameworks.

That’s it. Your solution is set up and you’re ready to start coding. In the next post, we’ll start building the model, configure NHibernate, and set up the database.

Jason

- Blogged-out for the night

Tags: , , , , ,