Last Saturday, I posted the first part in a series about building an ASP.NET MVC application from the ground up using NHibernate and Ninject. It dealt with setting up the structure of your solution and referencing some 3rd party assemblies.
In part 2, we’re going to set up the persistence object model. The persistence object model is a set of objects that we use to persist (save) data to the database.
Warning: This is a sample application. There are widely varying opinions on the correct structure for these types of applications. As with most advanced subjects in the ALT.NET space, Ayende has some great information on the difference between a persistence object model and a domain model. For the purposes of this series, they’re the same thing.
First, we build the structure of our persistence model as plain old CLR objects (POCO). I like to do this in the Visual Studio class designer. It helps keep me focused on the high-level entities and relationships instead of wandering off to do detailed implementation code.
Here’s the model we’ll start with:
Let’s look at the relationships between courses and sections. We have a one to many relationship from a Course to it’s Sections represented by an ICollection(Of Section) property in Course. We also have a many-to-one relationship from each section back to it’s Course represented by the Course property on Section.
Public Class Course
Public Property Sections() As ICollection(Of Section)
Get
End Get
Set(ByVal value As ICollection(Of Section))
End Set
End Property
End Class
Public Class Section
Public Property Course() As Course
Get
End Get
Set(ByVal value As Course)
End Set
End Property
'Other properties here...
End Class
public class Course
{
public ICollection<Section> Sections {
get { }
set { }
}
}
public class Section
{
public Course Course {
get { }
set { }
}
//Other properties here...
}
Now that we have all of that built, there’s a couple of small requirements to use these classes with NHibernate.
- All properties and methods must be overridable. That’s virtual for your C# folks.
- Unless you’re using a dependency injection bytecode provider, you need a parameter-less constructor. If you don’t know what a bytecode provider is, don’t worry about it. We’ll get in to it later on in the series. If you don’t have any constructors, you’re fine. There’s an implied parameterless constructor. As soon as you add a constructor with parameters, you’ll need to create one without parameters, just for NHibernate.
- You need some sort of identity property for your database primary key. This can be inherited from a base class, which is exactly what we’re going to do. Edit: Not true. Thanks for the correction Ayende!
- In the case of readonly properties, you have some options. You can tell NHibernate your naming convention for backing fields. I don’t like this. I prefer to make my properties read/write and make the setter protected. If you’re new to NHibernate, you’ve probably never seen this before.
Public Class Course Inherits Entity Private m_Sections As ICollection(Of Section) = New HashSet(Of Section) Public Overridable Property Sections() As ICollection(Of Section) Get Return m_Sections End Get Protected Set(ByVal value As ICollection(Of Section)) m_Sections = value End Set End Property End Classpublic class Course : Entity { private ICollection<Section> m_Sections = new HashSet<Section>(); public virtual ICollection<Section> Sections { get { return m_Sections; } protected set { m_Sections = value; } } }This is how I set up all of my collection properties. You can manipulate the contents of the collection, but you can’t replace it with another instance without inheriting this class and overriding the property. If you were to make this property readonly, you’d have to configure NHibernate to write to m_Sections using reflection. It’s sort of a pain, and completely unnecessary. This is easier and accomplishes the same end result.
Also, notice that we’re inheriting from a class called Entity. More on that later.
Let’s talk about the database for a minute. Each of these entity classes will eventually become a database table. What will you use for your primary keys? Fabio Maulo has a great post on the different NHibernate primary key generators. He also has this post about why identity columns probably are not the best choice.
So what’s a good choice? Well, that’s a matter of opinion. Thanks to NHibernate, I don’t go spelunking through the database much anymore, so I like guids. You really can use what you like, or rather, what your DBA likes.
Now, where are you going to put these primary keys in your objects? In my opinion, this is really a persistence detail – meaning your objects shouldn’t really be dealing with it. That’s why we’re going to keep it hidden away in the base class. Remember, we’re inheriting from Entity.
Public MustInherit Class Entity
Private m_ID As Guid
Public Overridable Property ID() As Guid
Get
Return m_ID
End Get
Protected Set(ByVal value As Guid)
m_ID = value
End Set
End Property
End Class
public abstract class Entity
{
private Guid m_ID;
public virtual Guid ID {
get { return m_ID; }
protected set { m_ID = value; }
}
}
That’s it for today’s post. In part 3, we’ll configure NHibernate and set up our database. For homework, we’re going to flesh out the other properties in our persistence model. Check out the source code in Visual Basic.NET or C#.





#1 by Niclas Pehrsson on August 11th, 2009
It’s a free choice but please skip m_ prefixes.
Good post unless that
#2 by Noam Gal on August 12th, 2009
I always used to expose my collection as an unmodifiable collection to the outside, and added Add and Remove methods to the class, so I can make sure both sides of a bi-directional collection are set together at runtime.
If you expose the “real” collection, a user can get a course having two sections in its collection, while a 3rd sections still points to the course, for example.
#3 by Jason on August 12th, 2009
I’ve been thinking about how this could be handled in a less intrusive manner, but I’m coming up with a lot of dead ends. I think I’ll simply defer to someone a lot smarter than me. Off to twitter I go.
Pingback: Reflective Perspective - Chris Alcock » The Morning Brew #410
Pingback: Nhibernate Talk 8/12/09 - Travis.Net.Blog
Trackback: DotNetShoutout
#4 by Dave Hanna on August 13th, 2009
Can you provide details or a link to a tutorial on using Class Diagrams in VS? I have not yet succeeded in reproducing anything approaching your class diagram, and have not been successful in finding any reasonable tutorial.
#5 by Jason on August 13th, 2009
This may help get you started… It’s fairly intuitive, despite being a GUI developer tool.
http://msdn.microsoft.com/en-us/library/aa288743(VS.71).aspx
I believe the class diagram tool is only included in the higher-end versions of visual studio.
#6 by Dave Hanna on August 13th, 2009
Thanks, Jason.
Eagerly awaiting the next installment!
Pingback: How-To: Using the N* Stack, part 3 « BASICly everything
Pingback: How-To: Using the N* Stack, part 3 - NHibernate blog - NHibernate Forge
Pingback: How-To: Using the N* Stack, part 4 « BASICly everything
Pingback: ASP.NET MVC Archived Buzz, Page 1
#7 by Nick Clarke on August 18th, 2009
Have you been able to get the dependency injection working? as I’m having trouble with casting issues.
“Unable to cast object of type ‘INHibernateProxyProxy9fe900867c074225b4a86e884ded38d9′ to type ‘App.Models.Company’”
I’m using Castle IoC and when I debug the NH code it seems to error when trying to cast from a proxy object to my object.
I did read somewhere that you can’t cast when the objects are created in different generator, but this should not be my problem as I pass the container into the EnhancedBytecode (uNhAddIns).
Thanks in advance
#8 by Jason on August 18th, 2009
Yes. DI is working fine for me, although I’ve only used it a handful of places in the last two weeks.
I don’t use Castle Windsor or the Castle EBC provider, but I do use Castle DynamicProxy with my NinjectBytecodeProvider. Still, it’s almost certainly not a problem with Windsor or the EBC.
When you get the exception, drop in to the debugger and map out the inheritance of that proxy object. I’m guessing you’ll find your answer there.
Pingback: Part 5: Fixing the Broken Stuff « BASICly everything
Pingback: Part 5: Fixing the Broken Stuff - NHibernate blog - NHibernate Forge
Pingback: Part 7: NHibernate and Ninject for ASP.NET MVC - NHibernate blog - NHibernate Forge