Geeks With Blogs
Billy McCafferty whatever (but really just .NET)

I finally got around to it... the whole shebang of NHibernate best practices with ASP.NET and Generics.  The article, along with the related source, can be found at http://www.codeproject.com/useritems/NHibernateBestPractices.asp.  Your review, feedback and suggestions would be much appreciated!


3/3/06 UPDATE

I've updated the article on Code Project to include a unit testing project to show how to simulate the web context and how to create “mock” DAO objects within your unit tests.

Posted on Saturday, March 11, 2006 10:22 PM ASP.NET , C# , NHibernate , Architecture | Back to top


Comments on this post: NHibernate Best Practices with ASP.NET, Generics & Unit Tests

# re: NHibernate Best Practices with ASP.NET and Generics
Requesting Gravatar...
Great article. Not sure I'll introduce generics into my projects until nHibernate has native support for it though. Also, I'd like to see this example extended through the use of reflection and configuration rather than use inline concrete DAO implementations. Strangely enough, hibernate says "If we use public static nested classes, we can centralize all of them (dao implementations) in one source file." This just doesn't feel right...
Left by Jon on Mar 13, 2006 9:52 AM

# re: NHibernate Best Practices with ASP.NET, Generics & Unit Tests
Requesting Gravatar...
I don't blame you for waiting; albeit, the sample project I put together will almost seamlessly port once NHibernate supports Generics natively. (I should say "should" instead of "will"...we'll see.)

I like your reflection/configuration idea...if you wanted to extend any of the DAOs, you could then implement a partial class to add methods that are too specialized to be part of the generic DAO. Do you have any suggestions for implementing your idea? Thanks!

Left by Billy on Mar 13, 2006 6:13 PM

# re: NHibernate Best Practices with ASP.NET, Generics & Unit Tests
Requesting Gravatar...
Billy - I have an abstract factory pattern I use to instantiate my DAO - I use "Repository" instead of "DAO". The code has not been updated yet to extend .NET 2.0 features like generics and partial classes. Ihe .NET 1.1 code uses configuration to load the assemblies. All objects have to be created from the abstract factory. If you are interested, I can email it. Hit me up at cis_jcean@msn.com.nospam
Left by Jon on Mar 14, 2006 5:00 AM

# re: NHibernate Best Practices with ASP.NET, Generics & Unit Tests
Requesting Gravatar...
Great articl, Billy.
Just wondering if it is a good idea to have another layer between DAOs and ASP.NET Pages, which will talk to DAOs and Domain objects, so that ASP.NET pages can talk to this layer and doesn't have to access DAOs directly?
Left by Chris on Apr 09, 2006 10:37 PM

# re: NHibernate Best Practices with ASP.NET, Generics & Unit Tests
Requesting Gravatar...
Hi Billy... great article!

I'm just getting in to code OO practices and I've found the article excellent in showing the benefits of "code to an interface".

However, I've noticed that your concrete dao classes(e.g. CustomerDaoNHibernate) implement the IGenericDao interface twice, once via GenericNHibernateDao<Customer, string> and secondly via ICustomerDao. Is this good practice to do this?

Please do not take this as a criticism in any way as I said I'm just trying to learn what is good OO design practice.
Left by Gary on May 30, 2006 4:02 AM

# re: NHibernate Best Practices with ASP.NET, Generics & Unit Tests
Requesting Gravatar...
You could use GenericNHibernateDao without having it implement IGenericDao, but having both GenericNHibernateDao and ICustomerDao implement this interface emphasizes the "contractual relationship" between these classes. So if you modify the signature of IGenericDao, you'll be forced to modify GenericNHibernateDao so that it'll remain in a consistent relationship with ICustomerDao.

Billy
Left by Billy on May 30, 2006 6:19 AM

# re: NHibernate Best Practices with ASP.NET, Generics & Unit Tests
Requesting Gravatar...
That's correct behavior that you're seeing. Whatever items that are retrieved from the DB within an NHibernate session are all saved back to the DB, if there are any changes, when the session's transaction gets committed. As you mentioned, there are times when you'd want to make a change to an object without persisting it back to the DB immediately. An example would be a wizard in which you don't want anything committed until after the last step. What you can do is "Evict" the object(s) that you don't want committed back to the DB when the transaction gets committed. The code to be used is "session.Evict(objectToEvict)." Evict disassociates an object with the session. When you're ready to commit the object that's been evicted, simply call "session.SaveOrUpdate(objectToBeCommitted)."

Billy
Left by Billy on Jun 13, 2006 7:40 PM

# re: NHibernate Best Practices with ASP.NET, Generics & Unit Tests
Requesting Gravatar...
I've gotten some great mileage out of this post, with some minor modifications to fit my application.

I'd like to make one small improvement, but I can't seem to find a way.

I'd like to hide the IdT from the the declaration of IGenericDao, since the IdT could (theoretically) be determined by T's IdT.

Clearly, my proposed implementation doesn't work.

Any suggestions?

<code>
public interface IDomainObject
{
Type IdType();
}

public abstract class DomainObject<IdT> : IDomainObject
{
// same as before ...

public Type IdType()
{
return typeof(IdT);
}
}

public interface IGenericDao<T> where T : IDomainObject
{
T GetByID(T.IdType() id);
}
</code>
Left by Rick on Dec 27, 2006 5:23 PM

# re: NHibernate Best Practices with ASP.NET, Generics & Unit Tests
Requesting Gravatar...
That is certainly food-for-thought because if you could simplify this then you could reduce some duplicated ID-data-type declarations. I'm going to give this a try and post another comment if I find a solution...thanks for the idea!
Left by Billy on Jan 03, 2007 2:22 PM

# re: NHibernate Best Practices with ASP.NET, Generics & Unit Tests
Requesting Gravatar...
After looking at it a bit further, the only solution I can think of is to use reflection to get the object's "ID" property and then to examine what type that property is. The major drawback to this is that then the data layer becomes tied to how the domain model is defined and becomes a bit more fragile. Assume someone changes "ID" to "PersistentID" in the domain object class. The data layer would then have to be altered to adjust to this new naming convention and would not be as reusable. I like the idea of inferring the type of the ID, but I like even more the idea of keeping the data layer completely independent from making assumptions about the domain layer. Let me know your thoughts on this or if you come up with a better solution.
Left by Billy on Jan 03, 2007 2:28 PM

# re: NHibernate Best Practices with ASP.NET, Generics & Unit Tests
Requesting Gravatar...
The way you could do this is to put the abstract DomainObject (or PersistentObject) base class into the data layer as well. In this way, it wouldn't be problematic having other classes within the data layer making assumptions about this base class. Having the base object anywhere other than the data layer would be a problem as you described.
Left by Billy McCafferty on Nov 15, 2007 10:37 AM

# re: NHibernate Best Practices with ASP.NET, Generics & Unit Tests
Requesting Gravatar...
Hi, I just wanted to look at ur article "http://www.codeproject.com/useritems/NHibernateBestPractices.aspx"

but page is not found .
Left by Hi , Page Not found on Jun 08, 2008 4:26 AM

Your comment:
 (will show your gravatar)


Copyright © Billy McCafferty | Powered by: GeeksWithBlogs.net