Ah, OK. I was working against 2.0.1. Cheers,
Symon. Symon Rottem http://blog.symbiotic-development.com 2008/12/25 HappyNomad <[email protected]> > > Hi Symon. The solution currently available from my blog compiles > against NHibernate v2.1 (the current trunk). Since compiling the > trunk on my computer, I haven't tried compiling my solution against > any earlier NH version. Which version are you using? I suppose I > could make my pre-2.1 solution available from my blog as well. Would > that be helpful? > > Hi Epitka. It sounds like you took a reasonable approach. You just > have to worry about those terrorists casting the IEnumerable to a > mutable collection type! lol If you already implemented your own self- > synchronizing observable collection, though, I'm surprised you didn't > go one step further by implementing a PreviewCollectionChanged event > on it as well. I guess you took the easier approach, which is > certainly understandable. > > Adrian > > > On Dec 24, 12:18 pm, epitka <[email protected]> wrote: > > As I said, I already have an implementation of self-synchronizing > > observable collection that I created myself. I was just asking about > > approach on how to enforce rules on the collections and I picked the > > method that hides implementation of the collection and exposes it > > through only IEnumerable interface. > > > > On Dec 24, 2:24 am, "Symon Rottem" <[email protected]> wrote: > > > > > Actually, after my last post I re-found your work. It looks like a > nice > > > idea (although I'm doing my own dictionary implementation as it's an > > > additional type I need) but there seems to be a problem with the > download - > > > it doesn't compile. I'm going to take a stab at getting it working > today. > > > > > Symon Rottemhttp://blog.symbiotic-development.com > > > > > 2008/12/24 HappyNomad <[email protected]> > > > > > > I implemented an IUserCollectionType that returns an observable > > > > PersistentGenericBag<T>. You can download it from my blog: > > > > > > > http://happynomad121.blogspot.com/2007/12/collections-for-wpf-and-nhi... > > > > > > Back to your original question, I think option #2 is a great idea and > > > > would stay away from the rest. I'd create a PreviewCollectionChanged > > > > event on the custom collection, and give subscribers veto power via a > > > > property on the arguments object. > > > > > > In my architecture, I expose collection properties directly without > > > > having separate add/remove methods. It's not a matter of paranoia of > > > > terrorists attacking my code... it's just good old fashion > > > > encapsulation and creating meaningful interfaces imho. In order to > > > > update the other side of a bidirectional relationship, I created two > > > > utility classes called OneToManyAssocSync and ManyToManyAssocSync > > > > which use observability to accomplish their goal. The above blog > > > > entry's download includes these classes and a usage example. > > > > > > On Dec 22, 4:53 pm, "Symon Rottem" <[email protected]> wrote: > > > > > ...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 Rottemhttp://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 { > > > > ... > > > > read more >> > > > --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
