José F. Romaniello

Las aventuras y desventuras de un codificador.

First of all, I just pushed to Nuget two code-only packages in addition to Jose.MVC.Windsor:

For this example I’d use the Chinook sample database.

Start a new project:

2011-03-07_1338

Then, I’d use the following nuget packages:

  • Jose.MVC.Windsor; this install the basic artifacts to working with Castle.Windsor in Asp.Net MVC.
  • Jose.SessionPerRequest.NHibernate; base classes to work with the Session Per Request pattern.
  • Jose.DataAccessObject.NHibernate; interface and implementation of a simple data access object.

Within Visual Studio you can use the Add Library Package Reference or the Package Manager Console, the output will be like this:

PM> install-package Jose.MVC.Windsor
'Castle.Windsor (≥ 2.5.2)' not installed. Attempting to retrieve dependency from source...
Done
'Castle.Core (≥ 2.5.2)' not installed. Attempting to retrieve dependency from source...
Done
'WebActivator (≥ 1.4)' not installed. Attempting to retrieve dependency from source...
Done
Successfully installed 'Castle.Core 2.5.2'
Successfully installed 'Castle.Windsor 2.5.2'
Successfully installed 'WebActivator 1.4'
Successfully installed 'Jose.MVC.Windsor 1.0.0'
Successfully added 'Castle.Core 2.5.2' to ChinookWithNugets
Successfully added 'Castle.Windsor 2.5.2' to ChinookWithNugets
Successfully added 'WebActivator 1.4' to ChinookWithNugets
Successfully added 'Jose.MVC.Windsor 1.0.0' to ChinookWithNugets

PM> install-package Jose.SessionPerRequest.NHibernate
'NHibernate (≥ 3.0.0)' not installed. Attempting to retrieve dependency from source...
Done
'Iesi.Collections (≥ 1.0.1)' not installed. Attempting to retrieve dependency from source...
Done
'Antlr (≥ 3.1.3.42154)' not installed. Attempting to retrieve dependency from source...
Done
Successfully installed 'Iesi.Collections 1.0.1'
Successfully installed 'Antlr 3.1.3.42154'
'Castle.Core 2.5.2' already installed
Successfully installed 'NHibernate 3.0.0.2001'
Successfully installed 'Jose.SessionPerRequest.NHibernate 1.0.0'
Successfully added 'Iesi.Collections 1.0.1' to ChinookWithNugets
Successfully added 'Antlr 3.1.3.42154' to ChinookWithNugets
ChinookWithNugets already has a reference to 'Castle.Core 2.5.2'
Successfully added 'NHibernate 3.0.0.2001' to ChinookWithNugets
Successfully added 'Jose.SessionPerRequest.NHibernate 1.0.0' to ChinookWithNugets

PM> install-package Jose.DataAccessObjects.NHibernate
'Iesi.Collections 1.0.1' already installed
'Antlr 3.1.3.42154' already installed
'Castle.Core 2.5.2' already installed
'NHibernate 3.0.0.2001' already installed
Successfully installed 'Jose.DataAccessObjects.NHibernate 1.0.0'
ChinookWithNugets already has a reference to 'Iesi.Collections 1.0.1'
ChinookWithNugets already has a reference to 'Antlr 3.1.3.42154'
ChinookWithNugets already has a reference to 'Castle.Core 2.5.2'
ChinookWithNugets already has a reference to 'NHibernate 3.0.0.2001'
Successfully added 'Jose.DataAccessObjects.NHibernate 1.0.0' to ChinookWithNugets

Now you need to do some manual steps:

1-Fix the registration of the HttpModules in the web.config to something like this:

<add name="SessionPerRequest" type="ChinookWithNugets.Infrastructure.SessionManagement.NHibernateSessionModule, ChinookWithNugets" />

2-Add a new connection string in the web.config:

<configuration>
  <appSettings>
        .....
  </appSettings>
  <connectionStrings>
    <add name="Chinook" connectionString="Server=.\sqlexpress; User=test; Password=test; Database=Chinook" />
  </connectionStrings>
  ....

3-Create an installer for Daos, in Infrastructure\Installers\ , the code as follows:

using Castle.MicroKernel.Registration;
using Castle.MicroKernel.SubSystems.Configuration;
using Castle.Windsor;
using ChinookWithNugets.Data;

namespace ChinookWithNugets.Infrastructure.Installers
{
    public class DaoInstaller : IWindsorInstaller
    {
        public void Install(IWindsorContainer container, IConfigurationStore store)
        {
            container.Register(Component.For(typeof (IDao<>))
                                        .Forward(typeof (IDaoReadOnly<>))
                                        .ImplementedBy(typeof (Dao<>)));
        }
    }
}

4-Create an installer for NHibernate:

using System.Collections.Generic;
using System.Web;
using Castle.Facilities.TypedFactory;
using Castle.MicroKernel.Registration;
using Castle.MicroKernel.SubSystems.Configuration;
using Castle.Windsor;
using ChinookWithNugets.Infrastructure.SessionManagement;
using NHibernate;
using NHibernate.ByteCode.Castle;
using NHibernate.Cfg;
using NHibernate.Cfg.Loquacious;
using NHibernate.Dialect;

namespace ChinookWithNugets.Infrastructure.Installers
{
    public class NHibernateInstaller : IWindsorInstaller
    {
        public void Install(IWindsorContainer container, IConfigurationStore store)
        {
            container.Register(Component.For<ISessionFactory>()
                    .UsingFactoryMethod(k => BuildSessionFactory()));

            container.Register(Component.For<ISessionFactoryProvider>().AsFactory());

            container.Register(Component.For<IEnumerable<ISessionFactory>>()
                                        .UsingFactoryMethod(k => k.ResolveAll<ISessionFactory>()));

            HttpContext.Current.Application[SessionFactoryProvider.Key]
                            = container.Resolve<ISessionFactoryProvider>();
        }

        private ISessionFactory BuildSessionFactory()
        {
            var configuration = new Configuration();
            configuration.DataBaseIntegration(db =>
            {
                db.Dialect<MsSql2008Dialect>();
                db.ConnectionStringName = "Chinook";
            });
            configuration.Properties[Environment.CurrentSessionContextClass]
                            = typeof (LazySessionContext).AssemblyQualifiedName;

            configuration.Proxy(p => p.ProxyFactoryFactory<ProxyFactoryFactory>());

            configuration.AddAssembly(GetType().Assembly);

            return configuration.BuildSessionFactory();
        }
    }
}

5-Create the Album class in

namespace ChinookWithNugets.Domain
{
    public class Album
    {
        public string Title { get; set; } 
    }
}

6-Create a mapping for albums Album.hbm.xml in "Data\Mappings":

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
                   namespace="ChinookWithNugets.Domain"
                   assembly="ChinookWithNugets">
  <class name="Album">
    <id column="AlbumId">
      <generator class="identity" />
    </id>
    <property name="Title" />
  </class>
</hibernate-mapping>

7-Create a HomeController in the Controllers folder:

using System.Linq;
using System.Web.Mvc;
using ChinookWithNugets.Data;
using ChinookWithNugets.Domain;

namespace ChinookWithNugets.Controllers
{
    public class HomeController : Controller
    {
        private readonly IDao<Album> daoAlbums;

        public HomeController(IDao<Album> daoAlbums)
        {
            this.daoAlbums = daoAlbums;
        }

        public ActionResult Index()
        {
            var albums = daoAlbums.RetriveAll().ToList();
            return View(albums);
        }
   }
}

8-Create a Index view in Views\Home:

<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<List<ChinookWithNugets.Domain.Album>>" %>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <ul>
    <% foreach(var a in Model) { %>
        <li><%= a.Title %></li>
    <% } %>
    </ul>
</body>
</html>

9-Run! you have now a sample ASp.Net MVC application with NHibernate and Castle.Windsor fully integrated.

2011-03-07_1853

If you want to see the full code; it is here.

IMPORTANT NOTE: unfortunately now you have to do an extra step, regarding internals stuff of the NHibernate project. Install the NHibernate.Castle package…

| More

0 comentarios:

Publicar un comentario en la entrada