Hi sclough, thanks for showing us your ideas. The way I've organised things is somewhat similar to yours, up to a point.
I too have isolated the objects in my Business Logic Layer ("BLL") from NHibernate by using interfaces. The difference is that I have just carbon-copied the SessionFactory, Session and Transaction classes into abstract interfaces (ISessionFactory, ISession and ITransaction resp.)
I could have defined these in a separate assembly but instead I chose to define them inside the BLL assembly once I realised that the BLL and this interface assembly would be closely coupled anyway. As an added bonus my business objects can now easily fetch/store data themselves during the course of their calculations, should the need arise. I don't expect this to be a common occurrence but you never know.
So, although it defines the persistence interfaces, my business layer doesn't contain a single line of persistence code. Like you I have a wrapper assembly which uses NHibernate itself to provide an implementation for the 3 aforementioned interfaces. It is up to client code (UI typically) to link them together to get things working. E.g. a BLL client typically does this:
Code:
BLL.Persistence.SessionFactory = New NHibernatePersistence.SessionFactory(connectionString)
where BLL.Persistence can be thought of as a ISessionFactory singleton in the BLL assembly and NHibernatePersistence.SessionFactory is the wrapper class inside the NHibernatePersistence assembly which implements ISessionFactory with the help of NHibernate itself.
All business objects inside BLL and all other objects who have access to the BLL namespace can now use BLL.Persistence.SessionFactory.OpenSession() to acquire a BLL.ISession object and start fetching/storing objects from/to the database using its methods, which are almost the exact same as those of NHibernate's Session object.
Conceptually all of this is 3-layer but I'll admit that for now I'm only using it in a 2-tier configuration (UI local + BLL local; DB remote) or even 1-tier when the DB connection is a SQLEXPRESS local connection. I hope it will remain standing when we start using it in a more service oriented architecture (e.g. WPF smart client + webservice + DB)
My hopes are high, which is typical when experience is low :-)))
Anyway, to get back on-topic: I have decided to stay with IList<T> in my business objects' collection properties and make more use of BindingSource components at the UI level (inside VS2005) to upgrade my IList<T> collections to IBindingList<T>, which is known to be ideal for both design-time and run-time databinding. I bind the BindingSource objects themselves to a BLL
class at design-time and re-bind them to the actual BLL objects' collection properties at run-time to get what I want, so it's a slightly bigger hassle for the UI code but I think it's worth it.
Why? Because this way my BLL objects' properties remain unpolluted with fluff that's only needed because of UI idiosynchrasies (i.e. Winforms run-time and Visual Studio design-time databinding)
Sigh, I really need to learn to shorten my posts. Nobody's gonna read them...