Please excuse me if I am missing something obvious but I am new to NHibernate. I came across an issue with NHibernate and was looking for some advice as to whether I am doing something wrong.
We are building an N-Tiered, SOA based, system in .NET 2.0 and have decided to investigate using NHibernate for our persistence layer. We are using NHibernate-1.2.0.Alpha1 for our investigations.
Our architecture is as follows (from top to bottom):
- UI
- UI Controllers
- Service Façade
- Service Layer (web Services)
- Business Process Managers
- Domain Object Managers
- Domain Objects (DTOs)
- Persistence Layer
- Data Store.
The problem is one of encapsulation;
We would like to have the NHibernate code exist only in the Persistence Layer, so the Persistence layer contains all of the mapping files for mapping the Domain Objects to the data store etc. This means that our Domain Objects should not contain NHibernate specific types. All our collections, therefore, are defined as IList<T>s, rather than NHibernate.Collection.Generic.PersistentGenericBag<T>s.
This works fine until we reach the Service layer. Unfortunately, the .NET Xml Serializer cannot serialize Interfaces (as they are not concrete types) meaning that the Domain Objects cannot be exposed by the Web Services. As the IList<T> collections returned from NHibernate at run time (of type NHibernate.Collection.Generic.PersistentGenericBag<T>) cannot be cast to any concrete .NET type (e.g. List<T>, Collection<T>) this presents a bit of a problem…….
The work around we have come up with is to have two properties on the Domain Objects for each collection – one of type IList<T>, and another of type List<T> which uses the underlying variable of the List<T> property to construct the List<T> on first use, like this:
/// <summary>
/// Get/Set the Underlying Policy Collection Interface.
/// </summary>
private IList<PolicyDTO> PoliciesInterface
{
get
{
if (_policies != null)
return _policies;
else
return _policiesInterface;
}
set { _policiesInterface = value; }
}
/// <summary>
/// Get/Set the Policy Collection.
/// </summary>
public List<PolicyDTO> Policies
{
get
{
if (_policies == null)
_policies = new List<PolicyDTO>(_policiesInterface);
return _policies;
}
set { _policies = value; }
}
The PoliciesInterface property is defined as private and is therefore not picked up by the XML Serializer, but can still be used by NHibernate.
The other way of doing it seems to be to have two duplicate sets of Domain Objects, one utilising IList<T> and one utilising a concrete collection type like List<T> for their collections. The Domain Objects would then be mapped from one type to the other at either the Service or Persistence Layer level.
Both of these methods are pretty messy.
Other than that, the only solution seems to be to introduce the NHibernate namespaces to our Domain Objects, and use the NHibernate.Collection.Generic.PersistentGenericBag<T> concrete type throughout our code….
Am I missing something stupid? I can’t seem to find a clean way around this but I’m surprised I can’t find any existing posts about it……
Thanks in advance for your help,
Alex
|