...unless you use an IUserCollectionType perhaps?  Then you could return a
custom type that is based on a PersistentGenericBag<T> but also implements
the observable events.  Use the custom collection type in your mappings and
lazy loading should be supported.

Not sure how to do this mind, but I seem to remember something being written
about it in the past...

Symon Rottem
http://blog.symbiotic-development.com


On Mon, Dec 22, 2008 at 6:24 PM, MAMMON <[email protected]> wrote:

>
> Any operation (Add, Clear, Remove, Insert, RemoveAt) that would modify
> the collection will throw a NotSupportedException.  Those members are
> present, because ReadOnlyCollection<T> implements ICollection<T> and
> IList<T>.  However, they are implemented using explicit interface
> implementation, so that when working with a ReadOnlyCollection<T>
> reference, the methods are not callable without an explicit cast to
> the interface type where the method is declared, like this:
>
>                        IList<int> ints = new List<int>();
>                        ReadOnlyCollection<int> roInts = new
> ReadOnlyCollection<int>(ints);
> // Explicit cast to make the call possible (will throw a
> NotSupportedException)
>                        ((IList<int>) roInts).Add(10);
>
>
> Additionally, my experience with lazy loading is that you DO lose
> certain abilities (such as a custom collection, or an observable
> collection), because the members in your class will be declared as
> (for instance) IList<int>.  Well, in your classes constructor, you
> could use this code:
>
>   _myInts = new ObservableCollection<int>();
>   _myInts.CollectionChanged += changedHandler;
>
> Now if you had lazy loading enabled, and ended up navigating to this
> collection of ints through a related object, like this:
>
>    parentObject.RelatedObject.Ints.Add(10);
>
> Then the handler for the ObservableCollection would not fire, because
> the _myInts wouldn't BE an ObservableCollection<T>.  It would be a
> PersistentGenericBag<int>.  The private member is declared only as
> IList<T>.  With lazy loading, YOUR constructor will fire first (it is
> the base class), creating the ObservableCollection<int> object, but
> when the dynamic proxy class' constructor runs, it's going to create a
> PersistentGenericBag<int> object and assign it to _myInts, and
> populate it, leaving the ObservableCollection<int> object for the
> Garbage Collector.  So now your changedHandler will never fire.  For
> these same reasons, you might lose functionality with custom
> collections when using lazy loading.  Your custom collection instances
> will be replaced with PersistentGenericBag<T> instances.
>
>
>
>
>
> On Dec 22, 6:34 am, epitka <[email protected]> wrote:
> > I don't it is the same, as read only still has Add/Remove etc.
> > methods, so your API is not quite clear (even though it would I think
> > raise exception), plus you have extra "new" in there.
> >
> > On Dec 21, 11:56 am, MAMMON <[email protected]> wrote:
> >
> > > You can do this:
> >
> > > using System.Collections.ObjectModel;
> > > using System.Collections.Generic;
> >
> > > public class MyEntity
> > > {
> > >     private IList<int> _numbers;
> >
> > >     public ReadOnlyCollection<int> Numbers
> > >     {
> > >         get
> > >         {
> > >             return new ReadOnlyCollection<int>(_numbers);
> > >         }
> > >     }
> >
> > > }
> >
> > > List<T> has a method named AsReadOnly() that returns a
> > > ReadOnlyCollection<T>, but from what little I know, when using lists
> > > for your collections, the members you map to have to be declared as
> > > IList<T> objects, not List<T> objects.  It's not really a big deal
> > > though, because in Reflector, the implementation of AsReadOnly() is:
> >
> > > public ReadOnlyCollection<T> AsReadOnly()
> > > {
> > >     return new ReadOnlyCollection<T>(this);
> >
> > > }
> >
> > > So it's the same either way.
> >
> > > On Dec 21, 2:59 am, s_tristan <[email protected]> wrote:
> >
> > > > You can create a custom collection without IUserCollection as was
> > > > written this:http://blog.benday.com/archive/2007/10/22/23164.aspx
> >
> > > > On 19 дек, 19:42, epitka <[email protected]> wrote:
> >
> > > > > I do like this better. Had to make small change to interceptor.
> >
> > > > >     private IBag<Package> _packages;
> > > > >    [Relationship("packages", RelationshipType.Aggregation,
> > > > > Cardinality.OneOrMore, inverseProperty = "project")]
> > > > >         public virtual IEnumerable<Package> packages
> > > > >         {
> > > > >                 get
> > > > >                 {
> > > > >                         return _packages;
> > > > >                 }
> > > > >         }
> >
> > > > >         public virtual bool AddPackage(Package package, out
> List<string>
> > > > > brokenRules)
> > > > >         {
> > > > >            PrePackageAdd(package, out brokenRules);
> >
> > > > >                 if (brokenRules.Count>0)
> > > > >                 {
> > > > >                          return false;
> > > > >                 }
> >
> > > > >                 _packages.Add(package);
> >
> > > > >                 PostPackageAdd(package);
> >
> > > > >                 return true;
> > > > >         }
> >
> > > > > On Dec 19, 8:33 am, Daniel Fernandes <[email protected]>
> > > > > wrote:
> >
> > > > > > How long is a piece of string ?
> > > > > > If your project really needs you to develop such a collection and
> your
> > > > > > consumers are aware of what's going on then I think it's fine.
> > > > > > But as you said it, fully exposing a collection brings risks and
> it
> > > > > > might be better to just revert to public AddXXX/RemoveXXX
> methods.
> > > > > > I tend now to use IEnumerable because it's by its definition the
> items
> > > > > > references are read-only.
> >
> > > > > > On Dec 19, 2:15 pm, epitka <[email protected]> wrote:
> >
> > > > > > > Well, I have developed one that does all of the houskeeping,
> > > > > > > synchronize, raise events etc., but now looking at it, I am not
> sure
> > > > > > > that is the best way, since the API is not really revealing
> what is
> > > > > > > happening. I had to do this for the company I work(ed) for as
> they had
> > > > > > > a system that had it's own higher level language that allowed
> direct
> > > > > > > manipulation of collections. Now for example if you set a value
> in
> > > > > > > collection through indexer and there is already item on that
> index, it
> > > > > > > would remove item from the collection, synchronize if
> bi-directions,
> > > > > > > raise remove events, that insert item and the same index,
> synch, and
> > > > > > > raise add. That is a lot of work that happens that one might
> not be
> > > > > > > aware of.  Only piece that was not in place was vetoing change.
> >
> > > > > > > On Dec 19, 8:04 am, Daniel Fernandes <
> [email protected]>
> > > > > > > wrote:
> >
> > > > > > > > Typical pattern is :
> >
> > > > > > > > IEnumerable<Foo> Foos {
> > > > > > > > get  { return _foos; }}
> >
> > > > > > > > bool AddFoo(Foo foo) {
> > > > > > > > // business rules here and references management
> (bi-directional
> > > > > > > > association, orphan children, multiplicity etc..)}
> >
> > > > > > > > bool RemoveFoo(Foo foo) {
> > > > > > > > // business rules here and  references management
> (bi-directional,
> > > > > > > > orphan children, multiplicity, etc..)
> >
> > > > > > > > }
> >
> > > > > > > > There must be around some good IList`1 implementations giving
> you
> > > > > > > > callbacks for when an object is added/removed as in Linq2Sql
> (can't
> > > > > > > > remember the class name).
> >
> > > > > > > > Daniel
> >
> > > > > > > > On Dec 19, 1:06 pm, epitka <[email protected]> wrote:
> >
> > > > > > > > > That is what I was after, as I've seen people providing
> Add/Remove
> > > > > > > > > methods and also exposing it as IList. I guess this post
> nails it down
> > > > > > > > > why.
> >
> > > > > > > > >
> http://tomas.oo-systemutvecklare.se/articles/encapsulation.php
> >
> > > > > > > > > On Dec 18, 11:12 pm, "Greg Young" <[email protected]>
> wrote:
> >
> > > > > > > > > > I don't even expose it as a collection only as an
> IEnumerable
> >
> > > > > > > > > > Why do you as a client care how I store it internally?
> >
> > > > > > > > > > Cheers,
> >
> > > > > > > > > > Greg
> >
> > > > > > > > > > On Thu, Dec 18, 2008 at 7:49 PM, epitka <
> [email protected]> wrote:
> >
> > > > > > > > > > > But how do you protect your collection from being
> changed; exposing it
> > > > > > > > > > > as read-only? But that is not intuitive, if client does
> not know that
> > > > > > > > > > > AddPerson is to be used you would get exception.
> > > > > > > > > > > Why is #2 not viable?
> >
> > > > > > > > > > > On Dec 18, 9:29 pm, "Greg Young" <
> [email protected]> wrote:
> > > > > > > > > > >> 1. don't let collection be modified directly but use
> Add/remove and
> > > > > > > > > > >> enforce rule there
> >
> > > > > > > > > > >> Have the aggregate root enforce the validation.
> >
> > > > > > > > > > >> Cheers,
> >
> > > > > > > > > > >> Greg
> >
> > > > > > > > > > >> On Thu, Dec 18, 2008 at 7:25 PM, epitka <
> [email protected]> wrote:
> >
> > > > > > > > > > >> > This is probably more a DDD question then NH. Let
> say you have
> > > > > > > > > > >> > observable collections that raise events before
> collection gets
> > > > > > > > > > >> > changed and after. Let's say you have a rule that
> only person's over
> > > > > > > > > > >> > 21 can be added to the collection. How would you
> handle this rule:
> > > > > > > > > > >> > 1. don't let collection be modified directly but use
> Add/remove and
> > > > > > > > > > >> > enforce rule there
> > > > > > > > > > >> > 2. create delegate that will check rule in
> OnChanging step and veto
> > > > > > > > > > >> > change
> > > > > > > > > > >> > 3. allow person to be added and run validate before
> persisting entity
> > > > > > > > > > >> > using NH events, basically allow entity to get into
> invalid state
> > > > > > > > > > >> > 4. manually invoke validation before commiting
> changes.
> > > > > > > > > > >> > 5. something else ?
> >
> > > > > > > > > > >> --
> > > > > > > > > > >> It is the mark of an educated mind to be able to
> entertain a thought
> > > > > > > > > > >> without accepting it.
> >
> > > > > > > > > > --
> > > > > > > > > > It is the mark of an educated mind to be able to
> entertain a thought
> > > > > > > > > > without accepting it.- Скрыть цитируемый текст -
> >
> > > > > - Показать цитируемый текст -
> >
>

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"nhusers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/nhusers?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to