Ryan LanciauxNew Media Mercenary

Navigation



  Home
  Contact

  Subscribe to Feed
  Follow on Twitter




Disclaimer

The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

© Copyright 2008


Sign in

NHibernate Session Per Request

May 11, 2008 by ryan

A little earlier on, I had posted a simple example of NHibernate in an MVC application as well as some initial questions I had about NHibernate Session management. In response to my question, Matt Hinze mentioned that the session should be transparent to the controller and posted some links to various articles explaining how to achieve this. I finally had a chance to play around with this type of session management and spent most of my time looking through Billy McCafferty's NHibernate Best practices on CodeProject. As I've mentioned before, I'm very new to NHibernate so some of the things I'm doing may not be ideal.

HTTP Module

First off, I created an HTTP module; this is where the session will be opened and closed (by accessing the session manager class). You'll notice on the Init that event handlers have been added. I'm using the same session manager class that I was using in my last example, however, now it's being initialized / closed here (rather than in each controller action).

    public class SessionModule : IHttpModule

    {

        private ISession _session;

 

        public void Init(HttpApplication context)

        {

            context.BeginRequest += new EventHandler(OpenSession);

            context.EndRequest += new EventHandler(CloseSession);

        }

 

        private void OpenSession(object sender, EventArgs e)

        {

            _session = SessionManager.GetCurrentSession();

        }

 

        private void CloseSession(object sender, EventArgs e)

        {

            _session.Flush();

            _session.Close();

        }

 

        public void Dispose()

        {

            _session = null;

        }

    }


Next, I added this class to the HttpModules section of the web.config

<add name="SessionModule" type="ProductModel.Session.SessionModule"/>

Controller Code

Finally, since the NHibernate Session is being created / closed in the HTTP Module, I no longer have to use the using statement in every controller. Instead, I'm just setting a ISession = to the SessionManagers Current session.

   public ActionResult AddProduct(string ID)

   {

       ISession session = SessionManager.GetCurrentSession();

       return RenderView("AddProduct",

           new SimpleProductRepository(session).List());

   }

Wrapping Up

There's still a bit more I want to explore with this method of Session Management (maybe transactions). Also I would be interested to test out the threading / performance implications of going this route. I've updated the code on my assembla site. If you're interested, you can check it out here http://svn2.assembla.com/svn/NHibernateTest/ (keep in mind it's demo code -- not anything remotely resembling anything I would use in production). I would really appreciate any suggestions / feedback that you may have!

kick it on DotNetKicks.com  




New Theme for BlogEngine.NET

May 8, 2008 by ryan

I have changed the look and feel of this site with a new theme. There were too many other people using the indigo theme that came with BlogEngine (although it's a great design), so I decided to make my own. It's nothing too special but it works out for me. I was trying to enhance readability and use colors that didn't clash with my Visual Studio theme that most of my posts contain snippets of :)

Please let me know what you think.


Tags: , , , ,
Categories: Design
Actions: E-mail | Kick it! | Permalink | commentComments (1) | RSS comment feedComment RSS


Using NHibernate (years after I should have been)

April 30, 2008 by ryan

As mentioned in my last post, I've been starting to use NHibernate in some of my more recent projects. I checked it out years ago and I completely hated it (maybe becuase I was a newer developer -- not totally sure). More recently, however, I've realized some of the benefits of Domain Driven Design and thought its about time to give Hibernate another shot. I'm admittedly pretty new to Hibernate so any feedback would be appreciated!

Classes 

    public class ProductGroup

    {

        public virtual string ProductGroupID { get; set; }

        public virtual string Title{ get; set;}

        public virtual IList<SimpleProduct> Products { get; set; }

    } 

    public class SimpleProduct

    {

        private IList<SimpleProduct> _relatedProducts;

 

        public virtual string ID { get; set; }

        public virtual string Title { get; set; }

        public virtual string ImagePath { get; set; }

        public virtual string Description { get; set; }

        public virtual IList<SimpleProduct> RelatedProducts

        {

            get{ return _relatedProducts; }

            private set { _relatedProducts = value;  }

        }

 

        public virtual void AddRelatedProduct(SimpleProduct product)

        {

            if (_relatedProducts == null)

                _relatedProducts = new List<SimpleProduct>();

            _relatedProducts.Add(product);

        }

 

    }

We're going to start out with some very contrived classes (normally would start with tests but this is just for the hibernate concepts)... These classes should be pretty straight forward; they consist only of some basic properties and list methods.

Data Tables 

Next, we need to create our tables to hold the data coming from the Classes -- I've created a product table / product group table and a lookup table for both (there are many-to-many references in both SimpleProduct and ProductGroup). 

CREATE TABLE [dbo].[SimpleProducts](
    [ProductID] [char](32) NOT NULL,
    [Title] [nvarchar](50) NOT NULL,
    [ImagePath] [nvarchar](300) NULL,
    [Description] [nvarchar](500) NULL
)
   
CREATE TABLE [dbo].[RelatedProductsLookup](
    [ProductID] [char](32) NOT NULL,
    [RelatedProductID] [char](32) NOT NULL
)

CREATE TABLE [dbo].[ProductsProductGroupsLookup](
    [ProductGroupID] [char](32) NULL,
    [ProductID] [char](32) NULL
)

CREATE TABLE [dbo].[ProductGroups](
    [ProductGroupID] [char](32) NOT NULL,
    [Title] [nvarchar](50) NULL
)    

 You will want to set the Primary Key of the SimpleProduct and Product Groups table to be the ID. 

Hibernate Mappings

Next we're on to the Hibernate mapping files. These files link the columns in the database to the fields/properties in the domain classes. Please check the project documentation for more detailed information on the Hibernate Schemas.

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

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"

                  namespace="ProductModel" assembly="ProductModel" default-lazy="false">

  <class name="ProductGroup" table="ProductGroups">

    <id name="ProductGroupID">

      <column name="ProductGroupID" sql-type="char(32)" not-null="true" />

      <generator class="uuid.hex" />

    </id>   

    <property name="Title">

      <column name="Title" length="50" not-null="true" />

    </property>   

    <bag name="Products"  table="ProductsProductGroupsLookup" lazy="false">

      <key column="ProductGroupID" />

      <many-to-many class="SimpleProduct" column="ProductID" />     

    </bag>       

  </class

</hibernate-mapping>

Inside the hibernate mapping tag, we have an element called class where we're defining the relationship between the class and the table in the database. From there we're defining the properties -- Most of this should be pretty straight forward but there are a couple things I would like to focus on. 

    <id name="ProductGroupID">

      <column name="ProductGroupID" sql-type="char(32)" not-null="true" />

      <generator class="uuid.hex" />

    </id>   

 This node is defining the unique ID for the class -- the ID is being created for each item and looks a little something like this: 46abbefc08d14b49a5d15c8a4dd69ff2

    <bag name="Products"  table="ProductsProductGroupsLookup" lazy="false">

      <key column="ProductGroupID" />

      <many-to-many class="SimpleProduct" column="ProductID" />     

    </bag>       

  </class

Here we're defining a many-to-many relationship with Products -- this is bumping up against the lookup table we defined earlier to get all SimpleProducts associated with this class. currently the bag is defining a many-to-many relationship. We're going to assume that a product can exist under any number of product groups -- for instance if we have a video game system it could be under both the Home Entertainment and Electronics product group. See the project documentation for other types of relationships (one-to-many, etc).

SimpleProduct Mapping:

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

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"

                  namespace="ProductModel" assembly="ProductModel" default-lazy="false">

  <class name="SimpleProduct" table="SimpleProducts">

    <id name="ID">

      <column name="ProductID" sql-type="char(32)" not-null="true" />

      <generator class="uuid.hex" />

    </id>   

    <property name="Title">

      <column name="Title" length="50" not-null="true" />

    </property>   

    <property name="ImagePath">

      <column name="ImagePath" length="300" not-null="false" />

    </property>   

    <property name="Description">

      <column name="Description" length="500" not-null="false" />

    </property>       

    <bag name="RelatedProducts"  table="RelatedProductsLookup" lazy="false">

      <key column="ProductID" />

      <many-to-many class="SimpleProduct" column="RelatedProductID" />     

    </bag>       

  </class

</hibernate-mapping>
 

 

Accessing The Data

Now that we've defined all of our mappings its time to create some methods to access our data.

    public class ProductGroupRepository

    {

        private ISession _session;

 

        public ProductGroupRepository(ISession session)

        {

            _session = session;

        }

 

        public ProductGroup GetByTitle(string Title)

        {

                return _session.CreateCriteria(typeof(ProductGroup))

                    .Add(Expression.Eq("Title", Title))

                    .UniqueResult<ProductGroup>();

        }

 

        public IList<ProductGroup> List()

        {

                return _session.CreateCriteria(typeof(ProductGroup))

                    .List<ProductGroup>();

 

        }

    }

 

The ISession is the Hibernate object to use when accessing the data -- from what it looks like, these should pretty much line up with a unit of work (More on that here).

In the other methods of the class, we first need to define what type of object we're looking for. In case it's not obvious, we're specifying that in the CreateCriteria section. In the List() method, we're returning a list (of ProductGroups) -- there are no filters or other criteria defined for this operation. In the GetByTitle() method, however,  we're stating that the Title for the product must match the Parameter 'Title'.

Demo Application

I've created a quick demo application using MVC and NHibernate. As I said, I'm still very new to hibernate so there's a lot I'm trying to learn (for instance where the ISession should initially be created and closed in an MVC application). Please let me know of any way that this could be better -- generally I'm writing this to help solidfy my thoughts on the technology, help others (hopefully) and also improve from others feedback. 

If you have tortoise or some other svn client, you can grab the code from http://svn2.assembla.com/svn/NHibernateTest/ -- You will need to change the database connection to whatever your db is. Again I would like to reiterate, it's demo code -- not even close to anything that I would ever use in production but worked out okay for testing. 

kick it on DotNetKicks.com

 

Disclaimer: Use this code at your own risk. 




NHibernate in an ASP.NET MVC application

April 29, 2008 by ryan

I've recently become interested in using NHibernate for some of my data access. For the past year or so I have been using SubSonic for that, however, I'm trying to take a bit more of a domain driven approach on the project I'm currently messing around on. Although I've only been looking at it for a couple of days, one thing I'm having a little bit of trouble figuring out is where my ISession should be opened / closed in an ASP.NET MVC application. Currently, I'm doing this in the Controller but I'm not totally sure that is the right way to go...

        public ActionResult ViewProduct(string ID)

        {

            using (ISession session = SessionManager.GetCurrentSession())

            {

                SimpleProductRepository repo = new SimpleProductRepository(session);

 

                return RenderView("ViewProduct",

                    new SimpleProductRepository(session).GetByTitle(ID));

            }

        } 


What is the best way to go about this? Also, should I be looking more at using a Unit of Work pattern to achieve this?
Tags:
Categories: Development
Actions: E-mail | Kick it! | Permalink | commentComments (2) | RSS comment feedComment RSS


Blog Engine.NET Security Patch Available

April 14, 2008 by ryan
If you have not seen one of the other 5 million postings on this, there is now a security patch available for BlogEngine.NET. This weekend an issue was reported where an attacker could obtain the username and password of the site. Thanks BlogEngine.NET team for the quick fix on this!
Tags: , ,
Categories: General
Actions: E-mail | Kick it! | Permalink | commentComments (0) | RSS comment feedComment RSS


IE8 vs Firefox 3.0b5 : JavaScript Part 1

April 12, 2008 by ryan

Last time I posted on the latest browser from Microsoft vs. Mozilla's latest I had compared page download times between the two browsers. This time, I would like to take a brief look at how they stack up in regard to JavaScript.

John Resig (of jQuery / Mozilla fame) announced the Dromaeo: Javascript Performance Testing suite yesterday. The suite runs some of the same tests as the WebKit team's SunSpider, however, there are some improved methodolgies (see the suite's wiki for more info on this). I don't know how often I feel like doing DNA Sequence Alignment in JavaScript but I think it would be a good way to quickly get some metrics of how both FireFox and IE8 handle the code.

The Comparison:

I ran the tests in groups because there were certain ones that were not finishing under IE8. To be quite honest, I'm not 100% sure if this is an Internet Explorer issue, or an issue with the tests. Both are a work in progress so I would rather not make assumptions at this point. Anyways, the results of the tests are listed below:

Test Name
Firefox 3.0 beta 5 Internet Explorer 8
Fannkuch v122 802.80ms 1032.20ms
Base 64 Encoding and Decoding v122: 2942.00ms Would not finish
DNA Sequence Alignment v116: 420.00ms Would not finish
N-Body Rotation and Gravity v122: 270ms 529.40ms
Prime Number Computation (2) v122: 305.80ms 518.20ms
Recursive Number Calculation v122: 184.40ms 417.80ms
Traversing Binary Trees v122: 156.80ms 422.20ms

The Results

The initial results look like Firefox is performing the more advanced Javascript operations faster than Internet Explorer. That being said, Dromaeo, IE8 and Firefox 3.0b5 are still being developed so a lot could change before the release. For more metrics view a comparison on the Dromaeo site of Safari 3.1, Firefox 3.0b5, Opera 9.5 and IE8b1. Let me know what you think or if you've encountered different results.

kick it on DotNetKicks.com

Tags:
Categories:
Actions: E-mail | Kick it! | Permalink | commentComments (8) | RSS comment feedComment RSS


Gravatar, please bring back PNG files!

April 10, 2008 by ryan
Gravatar recently made some big changes when migrating the site from Ruby on Rails to PHP. While most of these changes are a real benefit, there is one big feature that has been removed -- PNG files are no longer supported! Initially, I was sure it had to be a fluke -- why would someone want to remove PNG files for something like this? However, upon contacting support, my fears were confirmed (email pasted below):

"Gravatar.com has been redesigned to use JPEG images only.  There are certain (still in widespread use) web browsers which do not support PNG files (which would allow for transparent backgrounds.)  I would suggest Adding a background color to your image, and re uploading it."

First off I want to emphasize I really appreciate this service that Gravatar is providing; it has always worked well and come on, it's free! That being said, it is somewhat concerning that the support for PNG files has been dropped for legacy browsers.

While PNG files may not look pretty on IE6, its not an issue that will prevent IE6 (or other legacy browser) users from viewing the site. Moving web standards forward is important! As web developers, I believe its our responsibility to let the end-user know that their overall experience may be better with a newer (standards-compliant) browser. Furthermore, removing the ability to use PNG files for legacy browser support is somewhat harmful! Imagine if iTunes stopped selling MP3s because people on Walkman's couldn't listen to them -- no real technological advancement would be made for fear of alienating some users.

Ultimately, the decision to support PNG files is up to Automattic (the creators of Gravatar). My hope, is that they would allow the Gravatar users to pick the image format of choice while educating their users that PNG files may not show up as expected for some people.


kick it on DotNetKicks.com
What do you think should be done? Should PNG files be supported by Gravatar? Please leave a comment below -- or continue this discussion on your site... this is an important issue for Web Standards.



Browser Beta Battle : IE8 vs Firefox 3.0b5

April 2, 2008 by ryan

After reading Steve Souders' article on IE8 speed enhancements, I became curious about how page download times in IE8 stacked up against the latest beta of Firefox (3.0b5). I realize that both of these browsers are in beta so the release product may be signficantly different. Also, please keep in mind these results are not very scientific (obviously). To obtain download times, I used Fiddler for Internet Explorer and Firebug for Firefox.

First off, I loaded a several higher volume websites to compare page download times. Each page was loaded three times (for extreme statistical accuracy :P) and the average load time was calculated.

Google News

http://news.google.com

0 Javascript Requests - 0 CSS Requests - 32 Images
Firefox: 1.08 Seconds
IE8: 2.43 Seconds


Amazon

http://www.amazon.com

12 Javascript Requests - 2 CSS Requests - 96 Images
Firefox: 5.59 Seconds
IE8: 4.86 Seconds


Mac.com

http://www.mac.com

15 Javascript Requests - 6 CSS Requests - 44 Images
Firefox: 5.74 Seconds
IE8: 4.52 Seconds


Finally, I ran Steve Souders' Parellel downloads test; the results were almost identical.

Firefox

Internet Explorer


It was really odd to me that Google News loaded almost two times as fast on Firefox while all the other sites loaded close to the same speed or slightly faster on Internet Explorer. The only difference I notice off the bat is the number of JS/CSS files; maybe its something to do with that? It would be very interesting to see how the browsers compare when rendering pages. Have you found results similar to this or know of a good way to test render time? Let me know what you think.

kick it on DotNetKicks.com





Real Ultimate Power : Dependency Injection with Ninject

March 26, 2008 by ryan
Ninja
UPDATE: Nate Kohari (the author of Ninject) posted some excellent information in the comments (enough info that it could probably be a post on its own).

Recently Scott Hanselman compiled a list of Dependency Injection frameworks for .NET. I really didn't plan on trying anything new but Ninject really jumped out at me (honestly, it was more the reference to ninjas than anything). After seeing a couple examples, I thought I would check it out in a bit more detail.

Disclaimer: I've been playing around with Ninject for all of about 3 hours now ... it's very possible there's a better way to do some of this stuff :) So I would really appreciate any feedback.

On to the code

Okay, for this very contrived example we're going to be building car objects out of just an engine and a drive type (extremely accurate I know). Just like in my StructureMap example, I'm going to start by creating the interfaces followed by a default class that we're going to use as our skeleton car ... the interfaces are pretty basic so no need to spend too much time on them.

    public interface IDriveType

    {

        string DriveType{ get;}

    }

 

    public interface IEngine

    {

        string EngineType { get; }

    }



Both of the interfaces have only one string property that will be used for output. A little on the basic side but hey, we're looking at IoC not an accurate car construction. Next we're going to add all our implementations of the Engine

    class FourCylinder : IEngine

    {

        public string EngineType

        {

            get { return "4-Cylinder"; }

        }

    }

 

    class Rotary : IEngine

    {

        public string EngineType

        {

            get { return "Rotary"; }

        }

    }

 

    class SixCylinder : IEngine

    {

        public string EngineType

        {

            get { return "6-Cylinder"; }

        }

    }



And the drive type implementations...

    public class RWD : IDriveType

    {

        public string DriveType

        {

            get { return "Rear Wheel Drive"; }

        }

    }

 

    class FourWD : IDriveType

    {

        public string DriveType

        {

            get { return "Four Wheel Drive"; }

        }

    }

 

    class FWD : IDriveType

    {

        public string DriveType

        {

            get { return "Front wheel drive"; }

        }

    }



And finally the class we're going to use as our base car.

    public class BaseAuto

    {

        private IDriveType _driveType;

        private IEngine _engine;

 

        public string DriveType

        {

            get { return _driveType.DriveType; }

        }

 

        public string Engine

        {

            get { return _engine.EngineType; }

        }

 

        [Inject]

        public BaseAuto(IDriveType drive, IEngine engine)

        {

            _driveType = drive;

            _engine = engine;

        }

    }



You'll notice the [Inject] attribute above our constructor. This is basically telling Ninject to toss in an implementation of the IDriveType and IEngine interfaces to this constructor (more on  Constructor Injection over here).

Now we're on to the fun stuff. Ninject does not use XML to configure injections. Instead we're going to use a class called Module to define all that. As the documentation says, this class should implement IModule but thankfully (at least for the sake of testing), there's a pre-defined base implementation called StandardModule that we can extend.

    public class BaseModule : StandardModule

    {

        public override void Load()

        {

            Bind<IEngine>().To<Rotary>();

            Bind<IDriveType>().To<RWD>();

        }

    }



In the module definition, we're basically saying when we request an object from the Kernel (more on that in a sec.) we want the Rotary class in place of IEngine and the RWD instead of IDriveType. Simple enough, now lets take a look at the Kernel definition / initial code (I'm using winforms for the sake of example but you can really go w/ whatever project type you'd like). A lot of thought went into the naming of the form.

    public partial class Form1 : Form

    {

        private BaseAuto _rx8;

 

        public Form1()

        {

            InitializeComponent();

 

            IKernel kernel = new StandardKernel(new BaseModule());

 

            _rx8 = new BaseAuto(

                kernel.Get<Auto.IDriveType>(),

                kernel.Get<Auto.IEngine>()

                );

 

            MessageBox.Show("RX8: \n Drive Type: " + _rx8.DriveType +

                "\n Engine:" + _rx8.Engine);

        }

    }



And when we run it...



Just what we expected! Lets make things a little more interesting ... Say we wanted to add some other cars to our application? We probably don't want everything to be a rear-wheel drive rotary (Unless you really like RX-8's -- in that case you can buy my RX8 *shameless plug*). Anyways, we're going to accomplish this by changing up our Module a bit to bind to a different IEngine / IDriveType implementation depending on the context.

    public class BaseModule : StandardModule

    {

        public override void Load()

        {

            Bind<IEngine>().To<Rotary>()

                .Only(When.Context.Variable("carType").EqualTo("RX8"));           

            Bind<IDriveType>().To<RWD>()

                .Only(When.Context.Variable("carType").EqualTo("RX8"));

 

            Bind<IEngine>().To<SixCylinder>()

                .Only(When.Context.Variable("carType").EqualTo("Jetta"));

            Bind<IDriveType>().To<FWD>()

                .Only(When.Context.Variable("carType").EqualTo("Jetta"));

 

            Bind<IEngine>().To<FourCylinder>()

                .Only(When.Context.Variable("carType").EqualTo("WRX"));

            Bind<IDriveType>().To<FourWD>()

                .Only(When.Context.Variable("carType").EqualTo("WRX"));

        }

    }



Not too bad right? I mean, just looking at the code we can pretty much tell what's going on due to the Fluent Interface goodness. We can perform more powerful comparisons on our context variable but for now, this will work. Next we need to set up our context in the core part of our application
(where we're instantiating and requesting classes from our Kernel).

        public Form1()

        {

            InitializeComponent();

 

 

            IKernel kernel = new StandardKernel(new BaseModule());

 

            _rx8 = new BaseAuto(

                    kernel.Get<Auto.IDriveType>(

                    With.Parameters.ContextVariable("carType", "RX8")

                ),

                kernel.Get<Auto.IEngine>(

                    With.Parameters.ContextVariable("carType", "RX8")

                )

            );

 

            _jetta = new BaseAuto(

                    kernel.Get<Auto.IDriveType>(

                    With.Parameters.ContextVariable("carType", "Jetta")

                ),

                kernel.Get<Auto.IEngine>(

                    With.Parameters.ContextVariable("carType", "Jetta")

                )

            );

 

 

            _wrx = new BaseAuto(

                    kernel.Get<Auto.IDriveType>(

                    With.Parameters.ContextVariable("carType", "WRX")

                ),

                kernel.Get<Auto.IEngine>(

                    With.Parameters.ContextVariable("carType", "WRX")

                )

            );

 

        }



I've added some buttons so we don't get spammed with message boxes on form load... if we fire this off and click on the various buttons, we see we're getting the expected results!

</