I have written some code that I believe does what you want assuming your custom collection inherits from an IList<T> . If that is too restrictive, it probably wouldn't be all that much more work.
I will be posting this on my BLOG at:
http://damon.agilefactor.com in about an hour so check then.
Here is a description of the solution (not 100% but basically):
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.
IPersistentCollection is the interface for this...
Solution (basic OO Knowledge really): Our primary wrapper concrete class has all the inherited items it requires (as I will show). Then only refer to this 'wrapper' class and use a combination of encapsulation and inheritence on a List<T>.
So there are 3 files:
1) internal class DomainPersistentGenericBag<T> : PersistentGenericBag<T>, IDomainList<T>
2) public interface IDomainList<T> : IList<T>, IPersistentCollection
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> or DomainList<T>
IList<T> or List<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
Thanks,
Damon Carr, CTO
agilefactor