...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 -~----------~----~----~----~------~----~------~--~---
