-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 9 posts ] 
Author Message
 Post subject: Mapping for delegates/events - recommendations?
PostPosted: Thu May 04, 2006 4:58 am 
Newbie

Joined: Thu May 04, 2006 4:23 am
Posts: 16
Location: Germany
Hi,

My question:
Has anybody succeeded to write NHibernate mappings for events/delegates that work? Are there best practices?

Background:

We are rebuilding a C++ system (Win32) with direct SQL data base access.
The goal is to build very fast a lean, flexible system.
We hope to achieve this goal by using C# in combination with NHibernate.

I plan to use the events/delegates mechanism to establish notification lines from "master" objects to dependent objets (a la Observer Pattern).
This means that dependent objets register delegates (receiver object + method) on events of the "master" object.

The advantage of this approach is that we don't have to write a lot of wrapper classes and to create a lot of wrapper instances at runtime.

Wrapper classes would be nessecary for the traditional approach: where dependent objects are referenced themselfes in a regular association with the master object.
In order to send the notification to the dependent objects, they must implement the same interface or must inherit from the same superclass.


Thank you in advance,
Michael


Top
 Profile  
 
 Post subject:
PostPosted: Thu May 04, 2006 5:28 am 
Senior
Senior

Joined: Thu Aug 25, 2005 3:35 am
Posts: 160
I fail to see what it has to do with NH. Are you looking for a way to have the dependent objects notify the master objects and register it's delegate?

More information please, but I'm interested.


Top
 Profile  
 
 Post subject:
PostPosted: Thu May 04, 2006 6:48 am 
Newbie

Joined: Thu May 04, 2006 5:51 am
Posts: 7
So the problem is, that the Slave object needs to do this

masterObject.BigScaryEvent += new SlaveEventHandler(this.HandleIt);

If the Slave object knows the Master object it is supposed to catch events from, then it can add the event handler itself? So perhaps the Slave object needs a navigable relationship to it's Master ; make the Master a field of the Slave object and persist it in the usual way, then make the Slave attach the event after it is retreived from persistence?


Top
 Profile  
 
 Post subject:
PostPosted: Thu May 04, 2006 7:23 am 
Senior
Senior

Joined: Thu Aug 25, 2005 3:35 am
Posts: 160
yes, that is what I do.


Top
 Profile  
 
 Post subject:
PostPosted: Thu May 04, 2006 7:29 am 
Expert
Expert

Joined: Thu Jan 19, 2006 4:29 pm
Posts: 348
awilkins wrote:
So the problem is, that the Slave object needs to do this

masterObject.BigScaryEvent += new SlaveEventHandler(this.HandleIt);

If the Slave object knows the Master object it is supposed to catch events from, then it can add the event handler itself? So perhaps the Slave object needs a navigable relationship to it's Master ; make the Master a field of the Slave object and persist it in the usual way, then make the Slave attach the event after it is retreived from persistence?


And this means that before master can dispatch an event, it must ensure that all objects where (child.Master == this) must be loaded? Quite inconvient if the number of child class types grows...

Gert


Top
 Profile  
 
 Post subject:
PostPosted: Thu May 04, 2006 7:37 am 
Newbie

Joined: Thu May 04, 2006 4:23 am
Posts: 16
Location: Germany
Thank you for your replies.

The remaining problem is that for my purposes:
P1. the slaves may be of different classes
(i.e. the name of the method to be used in the delegate may be different for the possible slave classes),
P2. the masters to which a slave may be "devoted" may be of different classes
(i.e. the name of the event to be used in the "+=" may be different for the possible master classes),.

Possible solution: a builder class may be used:
S1. to build the delegate from that method of the slave that is the right one for the special slave class
S2. to access the appropriate event

In many cases classes can not be extended (e.g. system classes or 3rd party code).
Hence the relation between master and slave has to be stored external of both parties with minimal assumptions about the type of the connected objects, e.g. type Object.
The builder has to use a little of reflection programming in order to know the actual type of the participants.


Btw. my original idea was to persist the delegate object itself. But after thinking a while about the problems I discarded the idea.


Top
 Profile  
 
 Post subject:
PostPosted: Thu May 04, 2006 7:58 am 
Expert
Expert

Joined: Thu Jan 19, 2006 4:29 pm
Posts: 348
mhr wrote:
Btw. my original idea was to persist the delegate object itself. But after thinking a while about the problems I discarded the idea.


Well, thinking a little about the problem, the solution wopuld involve:

at the master side, you must:
1. Restore object from database
2. Recreate the delegate.

In order to restore object, You'll need object id (which might be composite id-s, if Your design allows them) and object (root)type.

To recreate the delegate, You'll also need to know the method... It should be trivial if You have method name (You can used reflection)

So, the only remaining issue is how to extract class name/object id and method name from the delegate in order to save required data..

Gert


Top
 Profile  
 
 Post subject: My thoughts about Delegate mapping
PostPosted: Thu May 04, 2006 8:56 am 
Newbie

Joined: Thu May 04, 2006 4:23 am
Posts: 16
Location: Germany
The questions/tasks/problems are:
How can I write a simple and robust mapping
1. to write a C# delegate object to data base columns,
2. to use the data fetched from the data base columns to re-establish a delegate object.

Multi) To complicate things, Delegate is an example of the composite pattern: it has the subclass MulticastDelegate, which can contain many Delegate objects.

Every delegate object knows
a) the receiver object,
b) the delegate type (i.e. the return type and the argument types of the allowed method) and
c) the method itself (method info)


Solution ideas:
a) -> can be mapped like an ordinary object reference
c) -> the name of the method can be stored in a string column
b) -> a discriminator field (with the name of the delegate type) could be used to map all instances of a certain delegate type to the same delegate subclass
Alternative: a separate table and mapping could be used for every delegate type.

Problem: "Protected constructor"
Unfortunately the constructor for class Delegate is protected, so that building objects from the data may be a problem for NHibernate.

protected Delegate (
Object target,
string method
)


NHibernate-1.0.2.0/doc/html_single/index.html#mapping-types-custom ("4.2.3 Custom value types") says :

"It is relatively easy for developers to create their own value types. ...
To implement a custom type, implement either NHibernate.IUserType or NHibernate.ICompositeUserType and declare

properties using the fully qualified name of the type. Check out NHibernate.DomainModel.DoubleStringType to see

the kind of things that are possible." (see NHibernate-1.0.2.0\src\NHibernate.DomainModel\DoubleStringType.cs).

-> Problem: Delegate is not a custom type.
So where to place the code for writing to the data base columns and the code for reading from the data base columns and creating the delegate object?

-------------------------
My conclusion:
Persiting delegates directly now seems to me to complicated and to error-prone. The use of regular associations seems to be easier and safer.

Another aspect: In future versions of C# things may change for such new things like delegates and events. As I mentioned in my first posting, we want to rebuild a serious software system. So the technical foundation has to be solid and not to much experimental.


Top
 Profile  
 
 Post subject:
PostPosted: Thu May 04, 2006 9:07 pm 
Regular
Regular

Joined: Mon May 16, 2005 1:35 am
Posts: 67
You could consider using an "Event Aggregator" (Fowler) to wire up the events across your entire object graph and have the aggregator raise appropriate/filtered events to interested clients. This way, NHibernate has already constructed your object graph without any event subscriptions and the aggregator then comes in afterwards and wires everything up.

If you need the parent objects to be notified of events in their children, then you will probably need to subscribe to the child objects' events in their repective setters on the parent object.

This would mean that you would need setters for all these object, including collections where the parent needs to subscribe to events on the child objects in the collections. This of course assumes NHibernate constructs the collection first before the collection is assigned to the parent object. Otherwise this approach would not work for collections.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 9 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
cron
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.