Aug
09
2009
How-To: Using the N* Stack, part 2
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 Class
public 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.
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#.
blog comments powered by Disqus