Who is Ali Özgür?

RecentComments

Comment RSS

In previous CodeProject.com article NHibernate Best Practices with ASP .NET, Generics and Unit Tests by Bill McCafferty
Core project contains DAO interfaces and domain objects while Data project contains implemetation of DAO interfaces.
For performance reasons, since we do not want to iterate over collections to find a matching object, we use DAO and thus
NHibernate to query for objects we are interested.Data project contains reference to Core project that is why we can not add
Data project as reference to core project, this will cause circular reference and .NET does not allow us to use
cricular references. As a side effect or result of this restriction

  • We explicitly have to pass DAO instances to our domain objects during construction or
  • Set DAO property of our domain object with an instance of DAO object which has to be created explicitly

This two methods causes presentation layer developers (WinForm or Web) to write somet repetative code like this one

 


public void DoSomething()

{

  // DaoFactory can be stored as variable in session (Web) or as a static variable (WinForm)

  IDaoFactory daoFactory = new DaoFactory();

  

  // This can also be stored as variable in session (Web) or as a static variable (WinForm)

  ISomeDomainObjectDao dao = daoFactory.GetSomeDomainObjectDao();

  

  //Method-1: Pass dao instance as a parameter in constructor

  SomeDomainObject domObj = new SomeDomainObject(dao); 


  //Method-2: Set DAO property of the domain object with an instance of the DAO

  SomeDomainObject domObj = new SomeDomainObject();

  domObj.SomeDomainObjectDao = dao;

} 



We can do a favour to presentation layer developers by automatically initializing internal DAO objects.
Below is described how we can achieve this.

Castle MikroKernel/Windsor

Castle MikroKernel is inversion of control container that provides us with very rich set of extensibility.
You can find out more information about Castle/MikroKernel here
In order to work with Castle MikroKernel

1) We need three assemblies from Castel Project

  • Castle.
  • Castle.Windsor
  • Castle.MikroKernel

2) We have to specify IoC components in our App/Web.config like the example provided below

 


<configSections>

  <section name="nhibernate" type="System.Configuration.NameValueSectionHandler, System, Version=1.0.1.0,Culture=neutral, PublicKeyToken=b77a5c561934e089" />

  <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net, Version=1.2.9.0, Culture=neutral, PublicKeyToken=b32731d11ce58905" />

  <section name="castle" type="Castle.Windsor.Configuration.AppDomain.CastleSectionHandler, Castle.Windsor" />

</configSections> 




<castle>

    <components>

      <component

        id="SampleDaoFactory"

        service="Fully qualified namespace where IDaoFactory interface resides"

        type="Fully qualified namespace where IDaoFactory implementation resides">

      </component>

      <component

        id="AnotherSampleDaoFactory"

        service="Fully qualified namespace where IDaoFactory interface resides"

        type="Fully qualified namespace where IDaoFactory implementation resides">

      </component>

    </components>

</castle> 


DaoFactoryExposer Class Hierarchy

As you can see in the simplified model below we work with 3 classes and 1 interface in this sample implementation.
  • DomainObject: This is our domain object that needs a DAO instance to query the database
  • IDaoFactory:Specifies which supported DAO objects by the factory
  • DaoFactory: Implements IDaoFactory interface. Creates Dao instances on request
  • DaoFactoryExposer:Exposes a DaoFactory instance by using Castle/MikroKernel IoC

As soon as we get a DaoFactory instance we will also be able to get any needed Dao instance as specified
by IDaoFactory interface

DaoFactoryExposer

 


/******************************************************************************

  File  : DaoFactoryExposer.cs

  Class : DaoFactoryExposer

  Description: 


  Created By: Ali Özgür

  Created On: 31/01/2007 14:55:24

  Contact   : ali_ozgur@hotmail.com 


  Revisions:

*******************************************************************************/ 


using System;

using System.Collections.Generic;

using System.Text; 


using Castle.Windsor;

using Castle.Windsor.Configuration.Interpreters; 




namespace Bilgi.SampleProject.Core

{

  /// 

  /// This class exposes dao factory using Castle.Windsoe IoC 

  /// container.

  /// 

  public class DaoFactoryExposer

  {

    private IDaoFactory _daoFactory = null; 


    public DaoFactoryExposer( )

    {

    } 


    public IDaoFactory DaoFactory

    {

      get

      {

        if (_daoFactory != null)

        {

          return _daoFactory;

        }

        else

        {

          IWindsorContainer container = new WindsorContainer(new XmlInterpreter());

          _daoFactory = container["SampleDaoFactory"] as IDaoFactory; 


          if (_daoFactory == null)

          {

            throw new TypeLoadException("Can not load dao factory from container!");

          } 


          return _daoFactory;

        }

      }

    }

  }

}  


IDaoFactory Interface

 


using System;

using System.Collections.Generic;

using System.Text; 


namespace Bilgi.SampleProject.Core

{

  public interface IDaoFactory

  {

    ISomeNeededDao GetSomeNeededDao( );    

  }

} 


IDaoFactory Implementation (DaoFactory)

 


using System;

using System.Collections.Generic;

using System.Text; 


namespace Bilgi.SampleProject.Data

{

  public class DaoFactory:IDaoFactory

  {

    ISomeNeededDao _someNeededDao = null;

    

    #region IDaoFactory Members 


    public ISomeNeededDao GetSomeNeededDao( )

    {

      if (_someNeededDao == null)

      {

        _someNeededDao = new SomeNeededDao();

      }

      return _someNeededDao;

    }

    

    #endregion

  }

} 


DomainObject

 


using System;

using System.Collections.Generic;

using System.Text; 


namespace Bilgi.SampleProject.Core

{

  public class DomainObject

  {

    #region Dao related

    

    private DaoFactoryExposer _daoFactoryExposer = new DaoFactoryExposer(); 


    IDaoFactory _daoFactory = null;

    public IDaoFactory DaoFactory

    {

      get

      {

        if (_daoFactory == null)

        {

          return _daoFactoryExposer.DaoFactory;

        }

        else

        {

          return _daoFactory;

        }

      }

      set

      {

        _daoFactory = value;

      }

    } 


    ISomeNeededDao _someNeededDao = null;

    public ISomeNeededDao SomeNeededDao

    {

      get

      {

        if (_someNeededDao == null)

        {

          return DaoFactory.GetSomeNeededDao();

        }

        else

        {

          return _someNeededDao;

        }

      }

      set { _someNeededDao = value; }

    } 


    #endregion //Dao related

   

    //Some method that needs SomeNeededDao instance

    public void AddOrder(Customer customer, Product product)

    {

      // Here SomeNeededDao instance is created automatically by using DaoFactoryExposer

      decimal customerBalance = SomeNeededDao.QueryCustomerBalance(customer);

      if(customerBalance <= 0 )

      {

        throw new Exception("Not enough balance!");

      }

    }

    

  }

} 



Posted in: .NET Development , CodeProject , NHibernate  Tags:
Comments are closed