I've already developed some projects with NHibernate and I can say that NHibernate is a real time saver. But I must admit that it takes some time to get used to NHibernate. As an ORM NHibernate has fantastic features but if you want to develop successfull projects with NHibernate you must know that NHibernate is only one part (ORM) of a successfull layered architecture. In the attached solution I tried to give you the basic idea of a layered architecture and how NHibernate can be used within such an architecture

Attached solution includes the following projects

  • Core: Our domain objects (entities) reside in this layer. Also DAO (Data Access Objects) interfaces are defined in this layer.
  • DAL (Data Access Layer): Default implementation of DAO interfaces reside in this layer.
  • BLL (Business Logic Layer): Business logic code resides in this layer.
  • Common: Some utility calsses reside in this project
  • Tests.Disconnected: Includes unit tests for domain objects and business logic. Notice that unit tests in this project do not require domain objects to be persisted (NHibernate behaviour will not be tested), so the need for a database connection is eliminated which in turn makes our unit tests fast. Notice how we replaced our default DAL with mocked one.
  • Tests.Connected: This project includes unit tests too, but this time we want to test how our domain objects and bussiness logic perform NHibernate. NHibernate provides very cool features like native sql, lazy loading and cascading and we will likely want to test how our domain objects behave when armored with these cool features of NHibernate. It is also very likely that we will have some mapping errors (typos likely) in our Core, these tests will help us catch these errors. Performance bottlenecks possibly caused by our NHibernate mappings (for example we may discover that we need to make a child collection to be lazy loaded) can also be identified with help of these tests.

In the sample solution you can also find a simple usage of Castle Windsor Inversion of Control (IoC) container. We use IoC to be able to load different implementations of our DAL (DAO implementations). 

Another very important point you need to understand really well is session management of NHibernate when used in web applications. Thanks to Burrow contribution project this task is made very simple, you do not even need to write single line of NHibernate session management code. You only need to inherit your DAO implementation classes from GenericDao<T> class and you are ready to go. 

Additional Notes

  • Database script is included in Tests.Connected project under DBScript folder. 
  • Sample project uses NHibernate  2.0 Aplha1 and NHibernate.Burrow is also Alpha1.
  • ASP .NET MVC Preview 3 to run Sales.MVC sample
  • TestDriven .NET to run NUnt tests

Suggested Readings

Downloads

Update History

  • 09 June 2008
    • Castle files under Libs folder updated to Castle RC3
    • SQLite references removed
    • TestFixtureTearDown override of CustomTestBase class in Sales.Tests.Connected assembly commented out

Posted in: NHibernate  Tags:

GoF book says that "Observer pattern should defina a one-to-many dependency between objects so that when one object changes state, all its dependenst are notified and updated automatically". Subscribing to RSS feeds is a nice analogy.  You subscribe to RSS feeds to show interest and you become an observer who demand for notification and RSS feeds become the subject and are responsable for providing information to all subscribers. I think this bit of information describing the pattern is enough, now lets see how we implement observer pattern.
More...


Posted in: C# , GoF Patterns  Tags:

I believe Factory Pattern is one of the most known pattern in development community. Simply Factory Pattern states that we have a factory object which is used to create other objects. But GoF specification for the Factory Pattern is a little bit different. GoF book says that "We should define an interface for creating an object, but let subclasses decide which class to instantiate."
More...


Posted in: C# , GoF Patterns  Tags:

BlogEngine .NET 1.3 uses www.gravatar.com/avatar.php?gravatar_id=[MD5 Hash] to retreive Gravatar images for the comments. But this url is not supported by Gravatar anymore as far as I understand. We have to replace this url with this one http://en.gravatar.com/avatar/.

In order correct this url open CommentView.ascx.cs file found in "User controls" folder and replace the source code of the Gravatar method with this one

001  protected string Gravatar(string email, string name, int size)
002
003  {
004
005    if (email.Contains("://"))
006
007      return
008
009          string.Format(
010
011              "<img class=\"thumb\" src=\"http://images.websnapr.com/?url={0}&amp;size=t\" alt=\"{1}\" />", name,
012
013              email);
014
015    //http://www.artviper.net/screenshots/screener.php?&url={0}&h={1}&w={1}
016
017    MD5 md5 = new MD5CryptoServiceProvider();
018
019    byte[] result = md5.ComputeHash(Encoding.ASCII.GetBytes(email));
020
021
022
023    StringBuilder hash = new StringBuilder();
024
025    for (int i = 0; i < result.Length; i++)
026
027      hash.Append(result[i].ToString("x2"));
028
029
030
031    StringBuilder image = new StringBuilder();
032
033    image.Append("<img src=\"");
034
035        
036
037    //Change the url
038
039    image.Append("http://en.gravatar.com/avatar/");
040
041        
042
043    //Change the MD5 hash appending code
044
045    image.Append(hash.ToString());
046
047    
048
049    image.Append("&amp;rating=G");
050
051    image.Append("&amp;size=" + size);
052
053    image.Append("&amp;default=");
054
055    image.Append(Server.UrlEncode(Utils.AbsoluteWebRoot + "themes/" + BlogSettings.Instance.Theme + "/noavatar.jpg"));
056
057    image.Append("\" alt=\"\" />");
058
059    return image.ToString();
060
061  }

After changing the url in source code you do not nedd to build/recompile BE you simply replace the old file with the modified one. 


Posted in: BlogEngine.NET  Tags:

Download Source(23,52 kb)

We have different kind of vehicle implementations inherited from an abstract Vehicle class. Our code looks like this

001    //Abstract Vehicle class
002
003    public abstract class Vehicle
004
005    {
006
007        public abstract string Description { get; }
008
009
010
011    }
012
013    
014
015    //Concrete implementation
016
017    public sealed class Car : Vehicle
018
019    {
020
021        public override string Description
022
023        {
024
025            get { return "Car"; }
026
027        }
028
029    }
030
031
032
033    //Concrete implementation
034
035    public sealed class Helicopter : Vehicle
036
037    {
038
039        public override string Description
040
041        {
042
043            get { return "Helicopter"; }
044
045        }
046
047    }
048
049
050
051    //Concrete implementation
052
053    public sealed class Jet : Vehicle
054
055    {
056
057        public override string Description
058
059        {
060
061            get { return "Jet"; }
062
063        }
064
065    }

Suppose that our client wants to rent these different kind of vehicles and print vehicle information plus rental specific info such as FromDate, ToDate and the customer's name. We could implement this requirement by adding those new properties to our base Vehicle class in order to meet our customer's need. We also have to modify our concrete Vehicle classes so thet they can provide rental information through their Description property.

Here is our modified Vehicle class More...


Posted in: C# , GoF Patterns  Tags:

I'm sure that you have already heard at least one of the following common design/development tips

  • Seperate out parts of code that will be subject to change over time from the rest of your code
  • Use has-a relationship instead of is-a relationship where possible, that is prefer composition over inheritance

Strategy pattern helps us to realize these tips in our designs. By applying the Strategy Pattern we move our algorithm implementations, which are possible source of maintainance issues, away from the more stable source code.

Download

GoF_Patterns_Strategy.rar (19,76 kb)

Recommended Reading 

Design Patterns For Dummies by Steve Holzner 

Example Implementation 

In our sample scenario we have different kind of vechicles all supporting some kind of Go behaviour. More...


Posted in: C# , GoF Patterns  Tags: