# Wednesday, May 27, 2009

In part 2 of the NerdDinnerAdvanced code I replaced the LinqToSql DAL with a DAL that uses NHibernate.  NHibernate is an open sourced object relational mapper.  If you are not familiar with ORM and/or NHibernate I highly suggest you check them out.  Because of the way we architected our project in Part 1 implementing an NHibernate DAL had little to no impact on any code above the DAL.

To start I re-structured the project a little.  I created a NerdDinnerAdvanced.Data.LinqToSql project and moved the LinqToSql DinnerRepository and the NerdDinner.dbml file into the new project.  This left just the IDinnerRepository in the NerdDinnerAdvanced.Data project.  You could certainly move the IDinnerRepository class to the NerdDinnerAdvanced.Common project and remove the NerdDinnerAdvanced.Data project if you wish.

DataAndLinqToSql

Now it was time to create my NHibernate mappings.  If you are not familiar with how ORM’s work the basic concept is that the ORM framework maps data from a database to your entity/domain objects In order to accomplish this you need to tell the ORM what tables/columns map to what objects/fields and this is typically done via an XML file.  In this case we only have 2 objects to map, Dinner and Rsvp, so the mapping would not be complex.  Often, though, you are dealing with hundreds of objects with a lot of fields and the management of the XML mapping files can get very difficult.  For this reason, and because I wanted to have a chance to play with it, I decided to use Fluent NHibernate to do my mapping.  Fluent NHibernate allows you to do your mappings using strongly typed C# code.

In my NerdDinnerAdvanced.Domain project I created a new folder called Mappings and added two mapping classes, one for each of my two domain objects.

Mappings

 

Because this is not a Fluent NHibernate tutorial I am not going to go into detail on how you create the mappings…and for the most part it is fairly intuitive.

 /// <summary>
 /// Fluent NHibernate mapping for the Dinner class
 /// </summary>
 public class DinnerMap : ClassMap<Dinner> {
     
     public DinnerMap() {
         WithTable("Dinners");
         SetAttribute("lazy", "false");
         Id(x => x.DinnerId);
         Map(x => x.Title);
         Map(x => x.Description);
         Map(x => x.EventDate);
         Map(x => x.HostedBy);
         Map(x => x.Address);
         Map(x => x.Country);
         Map(x => x.ContactPhone);
         Map(x => x.Latitude);
         Map(x => x.Longitude);
         HasMany(x => x.Rsvps).Inverse().KeyColumnNames.Add("DinnerId").Cascade.All().SetAttribute("lazy", "false");
     }
 }

Next it was time to create the NHibernate DAL so I added a NerdDinnerAdvanced.Data.NHibernate project to the solution.  The first thing you have to do when using NHibernate, after creating your mapping files, is create your NHibernate Session class.  Session to NHibernate is like DataContext to Linq.   The Session for the most part contains connection string and mapping info and it is the mediator between you and your data.

    /// <summary>
    /// NHibernate session factory
    /// </summary>
    public class SessionFactory {

        public static ISessionFactory CreateSessionFactory() {
            return Fluently.Configure()
                .Database(MsSqlConfiguration.MsSql2005.ConnectionString(c => c.Is("Data Source=keith-166938fd4;Initial Catalog=NerdDinner;Integrated Security=True")))  
                .Mappings(m =>  m.FluentMappings.AddFromAssemblyOf<Dinner>())  
                .BuildSessionFactory();  
        }
        
    }

After creating the NHibernate Session class I can now implement my DinnerRepository using NHibernate.  Below is an example of the FindAllDinners method.

        /// <summary>
/// Returns a list of all dinners
/// </summary>
/// <returns>List of all dinners</returns>
public IQueryable<Dinner> FindAllDinners() {
var sessionFactory = SessionFactory.CreateSessionFactory();
using (var session = sessionFactory.OpenSession()) {
using (session.BeginTransaction()) {
return session.CreateCriteria(typeof(Dinner)).List<Dinner>().AsQueryable();
}
}
}

After completing the DinnerRepository we can tell our application to use the the new DAL by changing one line in our InversionOfControlHelper class.

        /// <summary>
        /// Initializes the inversion of control mappings
        /// </summary>
        public static void Initialize() {
StructureMapConfiguration.ResetAll();
//Tell Structure Map we are using Fluent mapping rather than onfiguration file based mapping! StructureMapConfiguration.UseDefaultStructureMapConfigFile = false;
//This is the only line of code outside of the DAL that needed to be modified to implement the NHibernate data access layer! //StructureMapConfiguration.BuildInstancesOf<IDinnerRepository>().TheDefaultIsConcreteType<Data.LinqToSql.DinnerRepository>();
StructureMapConfiguration.BuildInstancesOf<IDinnerRepository>().TheDefaultIsConcreteType<Data.NHibernate.DinnerRepository>();
StructureMapConfiguration.BuildInstancesOf<IDinnerServices>().TheDefaultIsConcreteType<DinnerServices>();
}

Once again the complete source can be downloaded here.  Stay tuned for Part 3!

posted on Wednesday, May 27, 2009 8:52:17 AM (Central Daylight Time, UTC-05:00)  #    Comments [13]
# Tuesday, May 26, 2009
I stumbled across this excellent NHibernate video series today.  Check it out!

Summer Of NHibernate

Also being a huge Seinfeld fan...I love the name!

posted on Tuesday, May 26, 2009 10:58:05 AM (Central Daylight Time, UTC-05:00)  #    Comments [1]