Loading...

nhibernate-development@lists.sourceforge.net

[Prev] Thread [Next]  |  [Prev] Date [Next]

Re: [NHibernate-development] Code for Persisted Lazy Collectionswith Full Customization and Generics - No Casting Errors! Adam Tybor Wed Jul 25 06:05:22 2007

What is the point of an empty IDomainList interface?  Why would you need a 
custom collection when NHibernate can already return a generic IList<T>?

 

From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Damon Carr
Sent: Monday, July 23, 2007 10:20 AM
To: the NHibernate development list
Subject: Re: [NHibernate-development] Code for Persisted Lazy Collectionswith 
Full Customization and Generics - No Casting Errors!

 

 

This is now up here:

 

http://damon.agilefactor.com/2007/07/nhibernate-custom-collections.html

 

I corrected my mistatement onissue of DomainPersistentGenericBag<T>  not having 
an Interface. Indeed it does...  IPersistentCollection. the code is simpler and 
shoudl provide a great foundation for those wanting custom collections with 
Lazy Load functionality and seamless casting. 

This only supports IList<T> derived custom collections at the moment but I will 
look into supporting Dictionary<K,V>.

 

Thanks,

Damon

 


 

On 7/22/07, Damon Carr <[EMAIL PROTECTED]> wrote: 

All,

 

I finally got this working and passing my unit tests after many 'interesting' 
side-turns.

 

Code will be up on my BLOG: http://damon.agilefactor.com 
<http://damon.agilefactor.com/>  in a bit. 

 

I just want to make sure I am not missing anything (as it appears to work 100%).

 

First the overview (this is for a general audience as well so pardon the 
explicit explanations as I realize most of you are gurus here):

 

As I think many on this list know to have any kind of custom persistable 
collection you must inherit from PersistentGenericBag<T> which has no empty 
constructors (therefore you cannot use this to inherit on your main collection 
(!) as you MUST have an empty constructor for NHibernate to use). 

 

We want our main custom collection to inherit from the concrete List<T> to use 
its core services as our base so you have already used your 1 concrete parent. 
(if we had multiple inheritance we could inherit from both, problem solved - 
kind of - almost - well another day.....). 

 

Our interface must inherit from multiple sources for casting to work as we need 
it to:

 

a) It must inherit from IList<T> as that is our baseline 'lowest common 
denominator' collection type

 

b) ALSO....(I see people report this as an error fairly often) for casting 
purposes, we need to be able to cast our item to PersistentGenericBag<T> so we 
must also inherit from the same interface. This crashes for people all the time 
who diligently create custom collections. Once you get Lazy, BAM1 Casting 
Exception. This solves that problem. 

 

What is so tricky?  PersistentGenericBag<T> HAS NO INTERFACE we can use!

 

 

Solution (basic OO Knowledge really): Extract the interface (I live and die by 
ReSharper)...Fake out the system by using a concrete class of your own instead 
of  PersistentGenericBag<T>  which both inherits from PersistentGenericBag<T> 
and implements the extracted interface. Then only refer to our 'wrapper' class. 

 

So there are 3 files:

 

1)     internal class DomainPersistentGenericBag<T> : PersistentGenericBag<T>, 
IDomainList<T>

 

 

2)     public interface IDomainList<T> : IList<T>

 

 

NOTE: This interface contains our extracted  interface which has every single 
public item  from DomainPersistentGenericBag<T> and a 'new' prefix on items 
where we override the IList<T>'s method. 

 

NOTE2: I started by calling this IDomainPersistentGenericBag. This is perhaps 
more 'correct' but not as easy for the developers to sync the Interface and the 
concrete class as they do with IList and List (you'll see). 

 

 

3) Finally our main Collection class, which we use all over the place quite 
easily:

 

    public class DomainList<T> : List<T>, IUserCollectionType, IDomainList<T>

 

 

All the code is downloable from the blog below....

 

 

To use this simply:

 

1) In your Domain Class (I never use mapping files now, only attributes FYI):

 

public class MyDomainClass() {

 

...

 

 

private IDomainList<ArticleZones> _Zones;

 

 

[Bag(0, Inverse = true, CollectionTypeType = typeof(DomainList<ArticleZones>), 
Lazy = true, Generic = true, BatchSize = 10)]

[Key(1, Column = "articleid")]

[OneToMany(2, Class = "PMSiteDomainModel.ArticleZones, PMSiteDomainModel")]

public virtual IDomainList<ArticleZones> Zones

  {

            get { return _Zones; }

            protected set { _Zones = value; }

       

   }

 

 

Works like a charm!

 

You can refer to this collection as:

 

IDomainList<T>

ISet<T>

DomainList<T> 

 

All work and you get full customization!

 

To download the FULL code, this will shortly be up on my blog as well as more 
details here:

 

http://damon.agilefactor.com <http://damon.agilefactor.com/> 

 

 

 

Thanks,

Damon Carr, CTO

agilefactor

 


-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop. 
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >>   http://get.splunk.com/ 
<http://get.splunk.com/> 
_______________________________________________
Nhibernate-development mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/nhibernate-development 

 

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >>  http://get.splunk.com/
_______________________________________________
Nhibernate-development mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/nhibernate-development