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: | | | |
 
 
Powered by Community Server (Commercial Edition), by Telligent Systems
Copyright © INDC, 2006. All rights reserved.