Welcome to Geeks Portal Sign in | Join | Help | Sign In Live ID
in
 
 

Coding for Health

Integrating ASP.NET MVC, Spring.NET and NHibernate

Ahamdulillah finally could write a blog at geeks Smile.

 

After vacuum on writing code with Spring.NET and NHibernate (my favorite framework and ORM on .NET world) for several months which makes me really miss them so much Sad , finally since several days ago I could write code using them Wink again. Although not using them in my current work, I am still happy with my current work because on the code I wrote for, need some mathematics which really makes me have nostalgia with mathematic Wink. Ok back to the topic.

 

ASP.Net MVC is the open source technology of web framework that makes me really interesting on it lately. And I have a wish to use Spring.NET and NHibernate with it. Let's take a look a project structure I work with.

 

 

The Steps needed are :

Library

The *.dll(s) needed to prepare are :

  1. antlr.runtime.dll

  2. Castle.DynamicProxy.dll
  3. Common.Logging.dll
  4. Iesi.Collections.dll
  5. log4net.dll
  6. Nhibernate.dll
  7. Spring.Core.dll
  8. Spring.Data.dll
  9. Spring.Data.NHibernate12.dll
  10. Spring.Web.dll

Add all the libraries to the ASP.Net MVC project reference.

Web Configuration (Web.config)  

  1. Define section configuration :
           

    1 <sectionGroup name="spring">

    2       <section name="context" type="Spring.Context.Support.WebContextHandler, Spring.Web"/>

    3       <section name="objects" type="Spring.Context.Support.DefaultSectionHandler, Spring.Core"/>

    4       <section name="parsers" type="Spring.Context.Support.NamespaceParsersSectionHandler, Spring.Core"/>     

    5     </sectionGroup>

    6     <section name="databaseSettings" type="System.Configuration.NameValueSectionHandler"/>

      2.  Define spring config definition and database setting configuration           

    

    1   <spring>

    2     <parsers>

    3       <parser namespace="http://www.springframework.net/database"

                     type="Spring.Data.Config.DatabaseNamespaceParser, Spring.Data"

                      schemaLocation="assembly://Spring.Data/Spring.Data.Config/spring-database-1.1.xsd"/>

    4     </parsers>

    5     <context>    

    6       <resource uri="assembly://My.Web/My.Web.Config/spring-hibernate.xml"/>

    7       <resource uri="assembly://My.Web/My.Web.Config/spring-dao.xml"/>

    8       <resource uri="assembly://My.Web/My.Web.Config/controller.xml"/>

    9     </context>

   10   </spring>

   11   <databaseSettings>

   12     <add key="db.datasource" value="kerapansapi\sqlexpress2005" />

   13     <add key="db.user" value="sa" />

   14     <add key="db.password" value="c_7un" />

   15     <add key="db.database" value="MyDB" />

   16   </databaseSettings>

 

      3.   Define HttpModule             

    1 <httpModules>

    2       <add name="Spring" type="Spring.Context.Support.WebSupportModule, Spring.Web"/>

    3       <add name="OpenSessionInView" type="Spring.Data.NHibernate.Support.OpenSessionInViewModule, Spring.Data.NHibernate12"/>

    4      .....

    5      .....

    6 

    7     </httpModules>

 

Spring-NHibernate configuration

Create spring-hibenate.xml in config folder.

 

    1 <?xml version="1.0" encoding="utf-8" ?>

    2 <objects xmlns='http://www.springframework.net'

    3          xmlns:db="http://www.springframework.net/database">

    4 

    5   

    6   <object name="appConfigPropertyHolder"

    7           type="Spring.Objects.Factory.Config.PropertyPlaceholderConfigurer, Spring.Core">

    8     <property name="configSections" value="databaseSettings"/>

    9   </object>

   10 

   11   <db:provider id="DbProvider"

   12                    provider="SqlServer-1.1"

   13                    connectionString="Integrated Security=false; Data Source=${db.datasource};Integrated Security=true;

                                  Database=${db.database};User ID=${db.user};Password=${db.password};"/>

   14 

   15 

   16   <object id="sessionFactory" type="Spring.Data.NHibernate.LocalSessionFactoryObject, Spring.Data.NHibernate12">

   17     <property name="DbProvider" ref="DbProvider"/>

   18     <property name="MappingAssemblies">

   19       <list>

   20         <value>My.Web</value>

   21       </list>

   22     </property>

   23     <property name="HibernateProperties">

   24       <dictionary>

   25 

   26         <entry key="hibernate.connection.provider"

   27                value="NHibernate.Connection.DriverConnectionProvider"/>

   28 

   29         <entry key="hibernate.dialect"

   30                value="NHibernate.Dialect.MsSql2000Dialect"/>

   31 

   32         <entry key="hibernate.connection.driver_class"

   33                value="NHibernate.Driver.SqlClientDriver"/>

   34 

   35       </dictionary>

   36     </property>

   37   </object>

   38 

   39 </objects>

 

NHibernate Domain Mapping

In this sample just use a simple mapping table which located in Modes/hbm and its POCO in Models/src. I think its not a good idea to locate this Nhibernate mapping and its POCO in presentation layer. It is better to located in a separate project, so we could reuse it if we decide to change our presentation layer.

 

Mapping 

    1 <?xml version="1.0" encoding="utf-8" ?>

    2 <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="My.Web" namespace="My.Web.Models">

    3   <class name="Product" table="Product" >

    4     <id name="ID" type="System.Int32" column="ID">

    5       <generator class="assigned"/>

    6     </id>

    7     <property name="Name" column="Name" type="System.String" length="25"/>

    8     <property name="Price" column="Price" type="System.Decimal"/>

    9 

   10   </class>

   11 </hibernate-mapping>

POCO :

 

    1 [Serializable]

    2     public class Product : DomainObject<int>

    3     {

    4         private string _name;

    5 

    6         public virtual string Name

    7         {

    8             get { return _name; }

    9             set { _name = value; }

   10         }

   11         private decimal? _price;

   12 

   13         public virtual decimal? Price

   14         {

   15             get { return _price; }

   16             set { _price = value; }

   17         }

   18     }

 

DomainObject

 


Domain Repository

    1 public interface IRepository<T>

    2     {

    3         void Save(T entity);

    4         void Save(List<T> list);

    5         void Delete(T entity);

    6         void Update(T entity);

    7         IList<T> Load();

    8         T GetById<TId>(TId id);

    9         IList<T> GetByCriteria(ICriteria criteria);

   10     }

As well as Nhibernate Domain mapping, the Repository/DAO should placed in seperate library. Either in the same place as POCO/mapping on not.

   

NHibernateRepository :

    1 public class NHibernateRepository<T> : HibernateDaoSupport, IRepository<T>

    2     {

    3         #region IRepository<T> Members

    4 

    5         public void Save(T entity)

    6         {

    7 

    8             using (ISession session = SessionFactory.OpenSession())

    9             {

   10                 session.Save(entity);

   11                 session.FlushMode = FlushMode.Auto;

   12                 session.Flush();

   13             }

   14         }

   15 

   16         public void Save(List<T> list)

   17         {

   18             using (ISession session = SessionFactory.OpenSession())

   19             {

   20                 ITransaction tx = session.BeginTransaction();

   21                 try

   22                 {

   23                     foreach (T entity in list)

   24                     {

   25                         session.Save(entity);

   26                     }

   27 

   28                     tx.Commit();

   29                 }

   30                 catch (Exception ex)

   31                 {

   32                     tx.Rollback();

   33                     throw ex;

   34                 }

   35                 finally

   36                 {

   37                     tx.Dispose();

   38                 }

   39             }

   40         }

   41 

   42         public void Delete(T entity)

   43         {

   44             using (ISession session = SessionFactory.OpenSession())

   45             {

   46                 session.Delete(entity);

   47                 session.Flush();

   48             }

   49 

   50         }

   51 

   52         public void Update(T entity)

   53         {

   54             using (ISession session = SessionFactory.OpenSession())

   55             {

   56                 session.Update(entity);

   57                 session.Flush();

   58             }

   59         }

   60 

   61         public IList<T> Load()

   62         {

   63             using (ISession session = SessionFactory.OpenSession())

   64             {

   65                 return session.CreateCriteria(typeof(T)).List<T>();

   66             }

   67         }

   68 

   69         public T GetById<TId>(TId id)

   70         {

   71             using (ISession session = SessionFactory.OpenSession())

   72             {

   73                 return session.Get<T>(id);

   74             }

   75         }

   76 

   77         public IList<T> GetByCriteria(ICriteria criteria)

   78         {

   79             using (ISession session = SessionFactory.OpenSession())

   80             {

   81                 return criteria.List<T>();

   82             }

   83         }

   84 

   85         #endregion

   86     }


SpringControllerFactory

SpringControllerFactory is adapted from MVCContrib. And made a few modification on it because in this case I want use convention on naming id controller at Spring IoC/DI configuration. The modification applied on CreateController method.

    1 public IController CreateController(RequestContext context, string controllerName)

    2         {

    3             if (string.IsNullOrEmpty(controllerName))

    4                 throw new ArgumentNullException("controllerName");

    5 

    6             //make convention on spring naming controller in spring IoC/DI definition

    7             //xxxx.controller (all in lowecase)

    8             controllerName = controllerName.ToLower() + ".controller";

    9 

   10             if (_objectFactory == null)

   11             {

   12                 throw new ArgumentException("CreateController has been called before Configure.");

   13             }

   14 

   15             try

   16             {

   17                 return (IController)_objectFactory.GetObject(controllerName);

   18             }

   19             catch (Exception e)

   20             {

   21                 throw new InvalidOperationException("Failed creating instance of: " +

   22                                             controllerName + " using spring.net object factory", e);

   23             }

   24         }


Global.asax

The next thing that we need to do is get spring context there and configure SpringControllerFactory.

    1 public class MvcApplication : System.Web.HttpApplication

    2     {

    3         public static void RegisterRoutes(RouteCollection routes)

    4         {

    5             routes.IgnoreRoute("{resource}.axd/{*pathInfo}");           

    6             routes.IgnoreRoute("favicon.ico");

    7 

    8 

    9             routes.MapRoute(

   10                 "Default",                                              // Route name

   11                 "{controller}/{action}/{id}",                           // URL with parameters

   12                 new { controller = "Home", action = "Index", id = ""// Parameter defaults

   13             );

   14 

   15         }

   16 

   17         protected void Application_Start()

   18         {

   19             ConfigureController();

   20             RegisterRoutes(RouteTable.Routes);

   21         }

   22 

   23 

   24         private void ConfigureController()

   25         {

   26             //This example just sets the default context for use with the Spring.net Controller

   27             //Factory.  An IObjectFactory instance is also supported, if greater control over

   28             //Spring.net is desired.

   29 

   30             WebApplicationContext ctx = ContextRegistry.GetContext() as WebApplicationContext;

   31             SpringControllerFactory.Configure(ctx);

   32 

   33             ControllerBuilder.Current.SetControllerFactory(typeof(SpringControllerFactory));          

   34         }

   35     }

Controller

We could add Repository property for the model (product) in the controller, and provide method that would be invoked on HttpRequest which the repository object would be called in.

 

    1     [HandleError]

    2     public class HomeController : Controller

    3     {

    4         private IRepository<Product> _productRepository;

    5 

    6         public IRepository<Product> ProductRepository

    7         {

    8             get { return _productRepository; }

    9             set { _productRepository = value; }

   10         }

   11 

   12         public ActionResult DynamicGridData(string sidx, string sord, int page, int rows)

   13         {

   14             int pageIndex = Convert.ToInt32(page) - 1;

   15             int pageSize = rows;

   16             int totalRecords = 0;

   17             int totalPages = (int)Math.Ceiling((float)totalRecords / (float)pageSize);

   18 

   19             //ideally do real paging not load all data like this.

   20             IList<Product> context = ProductRepository.Load();

   21             totalRecords = context.Count;

   22             var products = context.Skip<Product>(pageIndex * pageSize).Take<Product>(pageSize);

   23 

   24             CultureInfo ci = new CultureInfo("id-ID");

   25 

   26             var jsonData = new

   27             {

   28                 total = totalPages,

   29                 page = page,

   30                 records = totalRecords,

   31                 rows = (

   32                     from prod in products

   33                     select new

   34                     {

   35                         i = prod.ID,

   36                         cell = new string[] { prod.ID.ToString(), prod.Name,prod.Price.GetValueOrDefault().ToString("C",ci) }

   37                     }).ToArray()

   38             };

   39             return Json(jsonData);

   40         }

 

   41         ....

   42         ....

             

   43     }


I use jQuery (jGrid) to view display the data. Let take a look later on View section. The Spring configuration for the Controller is :

 

    1 <?xml version="1.0" encoding="utf-8" ?>

    2 <objects xmlns="http://www.springframework.net">

    3   <description>

    4     MVC Controller declarations.

    5   </description>

    6 

    7   <object id="home.controller" type="My.Web.Controllers.HomeController,My.Web" singleton="false">

    8     <property name="ProductRepository" ref="repository.product"/>

    9   </object>

   10   <object id="account.controller" type="My.Web.Controllers.AccountController,My.Web" singleton="false"/>

   11 

   12 </objects>


Spring DAO / Repository configuration.

 

    1 <?xml version="1.0" encoding="utf-8" ?>

    2 <objects xmlns="http://www.springframework.net">

    3   <description>

    4     Spring DAO / Repository

    5   </description>

    6   <object id="repository.product" type="My.Web.Repository.NHibernateRepository&lt;My.Web.Models.Product&gt;,My.Web" singleton="false">

    7     <property name="SessionFactory" ref="sessionFactory"/>

    8   </object>

    9 

   10 </objects>


View

The index.aspx is:


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

<link rel="stylesheet" type="text/css" href="/scripts/themes/coffee/grid.css" title="coffee" media="screen" />

<script src="/Scripts/jquery-1.3.2.js" type="text/javascript"></script>

<script src="/Scripts/jquery.jqGrid.js" type="text/javascript"></script>

<script src="/Scripts/js/jqModal.js" type="text/javascript"></script>

<script src="/Scripts/js/jqDnR.js" type="text/javascript"></script>

<h2><%= Html.Encode(ViewData["Message"]) %></h2>

<br />

<script type="text/javascript">

jQuery(document).ready(function() {

jQuery("#list").jqGrid({

url: '/Home/DynamicGridData/',

datatype: 'json',

mtype: 'GET',

colNames: ['ID', 'Name', 'Price'],

colModel: [

{ name: 'ID', index: 'ID', width: 40, align: 'left' },

{ name: 'Name', index: 'Name', width: 200, align: 'left' },

{ name: 'Price', index: 'Price', width: 100, align: 'left'}],

pager: jQuery('#pager'),

rowNum: 10,

rowList: [5, 10, 20, 50],

sortname: 'ID',

sortorder: "desc",

viewrecords: true,

imgpath: '/scripts/themes/coffee/images',

caption: 'Product List'

});

});

</script>

<table id="list" class="scroll" cellpadding="0" cellspacing="0"></table>

<div id="pager" class="scroll" style="text-align:center;"></div>


</asp:Content>


Finally let's test by compile and running it.



 

Cool, we success use Spring.NET framework and NHibernate ORM in our ASP.MVC application.

Btw thanks for reading...and have a nice day Big Smile




Share this post: | | | |

Comments

 

junaidi said:

Sorry...for not well formatted on snipped code especially on *.aspx code.

Any idea to make it better ???

May 22, 2009 7:03 AM
 

neonerdy said:

jun di product list ga ada kuda seharga 3 milyar?

May 22, 2009 8:15 AM
 

junaidi said:

Haha....harga kuda lagi turun derastis euy... :D

May 22, 2009 9:29 AM
 

Maximilian Haru Raditya said:

Have you tried Windows Live Writer?

You could then install its CodeSnippet plugin obtained from here (wlwplugincollection.codeplex.com).

May 22, 2009 5:22 PM
 

reyza said:

akhirnya Om Junaidi nge-blog juga...ditunggu cerita Spring & MVC yang lain Om.

May 23, 2009 5:46 AM
 

junaidi said:

@Maximilian Haru Raditya : Thanks for info :)

@Reza : Hehee...baru belajar nge-blog nih bozz....and thanks da banyak ngajarin and jadi tempat nanya silverlight/WPF .... ;)

May 23, 2009 7:44 AM
 

Webmaster Crap » Blog Archive » Integrating ASP.NET MVC, Spring.NET and NHibernate - Coding for Health said:

Pingback from  Webmaster Crap  &raquo; Blog Archive   &raquo; Integrating ASP.NET MVC, Spring.NET and NHibernate - Coding for Health

May 24, 2009 2:07 AM
 

ukungx said:

nyari proyek lagi jun n implement teknologi ini sekalian belajar,, belajarnya lebih seru kalo ada duitnyah hehhe

May 25, 2009 4:17 PM
 

junaidi said:

@ukungx, hehehe...sama saya juga masih belajar.....

btw biasanya situ yg sering kebanjiran projekan ;)

May 26, 2009 10:50 AM
 

ASP.NET MVC Archived Blog Posts, Page 1 said:

Pingback from  ASP.NET MVC Archived Blog Posts, Page 1

May 26, 2009 11:37 AM
 

Rizki Gunawan said:

wah ini yg saya cari2, maklum baru pingin belajar ASP.NET dengan NHibernate, pemula banget neh ... scroll atas bawah mondar mandir, source code nya gak bisa di download ya, mau dong ......,

September 8, 2009 11:27 AM
 

daxsorbito said:

Nice article! where could we download the code for this? Thanks.

September 15, 2009 9:29 PM
 

leyegoph said:

Hi,

is it possible to have the project sample code at leyegora@yahoo.fr ?

I'm newly in C#.net and I cannot run it success ( by copy and paste the code )

Best regards

June 28, 2010 1:53 AM
 

AnduA said:

Can you provide the source-code for this project please? Thank you!

July 19, 2010 10:09 PM
 

AnduA said:

I thought the code you posted was incomplete but after I had examined it better I realized it was complete, so I managed to run it and understand how to integrate these technologies. You did a great job! Thank you very much!

July 20, 2010 8:20 AM
 
 
Powered by Community Server (Commercial Edition), by Telligent Systems
Copyright © INDC, 2006. All rights reserved.