Καλώς ορίσατε στο dotNETZone.gr - Σύνδεση | Εγγραφή | Βοήθεια
σε

 

Αρχική σελίδα Ιστολόγια Συζητήσεις Εκθέσεις Φωτογραφιών Αρχειοθήκες

Deserialized objects "ξεχνάνε" τα event handler τους (VB.NET)

Îåêßíçóå áðü ôï ìÝëïò Sunburn. Τελευταία δημοσίευση από το μέλος Sunburn στις 17-04-2008, 13:26. Υπάρχουν 4 απαντήσεις.
Ταξινόμηση Δημοσιεύσεων: Προηγούμενο Επόμενο
  •  16-04-2008, 21:00 41566

    Deserialized objects "ξεχνάνε" τα event handler τους (VB.NET)

    Ενα πρόβλημα για το οποίο είμαι σίγουρος οτι υπάρχει κάποιο τρικ, αλλα δεν το έχω βρει ακόμα...

    Έχω μια class "Class-A", που θέλω να ακούει για (και να αντιδρά σε) ένα συγκεκριμένο event σε όλα τα (dynamically δημιουργημένα) objects μιας άλλης "Class-B".

    Επειδή δεν μπορώ να έχω εκ των προτέρων reference στα objects της "Class-B", συνεπώς δεν μπορώ να χρησιμοποιήσω "Public WithEvents myObjectB as Class-B" και "[SomeReactionMethod] Handles myObjectB.SomeEvent".
    Άρα αναγκαστικά χρησιμοποιώ "AddHandler ClassB.SomeEvent, AddressOf SomeReactionMethod", και το τοποθετώ στον constructor της Class-A, ώστε κάθε καινούργιο instance της αυτομάτως να "στήνει αυτί".

    Δημιουργώ λοιπόν ένα Class-A object, και στη συνέχεια ένα Class-B object. To πρώτο 'ακούει' το event του δευτέρου μια χαρά, όλα ωραία και καλά.

    Το πρόβλημα εμφανίζεται όταν τα κάνω και τα δυο serialize (binary, αν έχει σημασία) και στη συνέχεια τα επαναφέρω με deserialization. Τώρα το Object-A για κάποιο λόγο έχει ξεχάσει εντελώς οτι του έχω αναθέσει να ακούει για το event του Object-B.

    Γιατί συμβαίνει αυτό; Πώς μπορώ να το αντιμετωπίσω;

    Υποθέτω πως μια λύση θα ήταν να επέμβω στην διαδικασία του deserialization και να προσθέσω ένα εξτρα βήμα που προληπτικά επαναπροσθέτει το event handler (υποθέτωντας το χειρότερο δηλαδή). Φαντάζομαι όμως πως αυτή δεν είναι η καλύτερη λύση.





  •  17-04-2008, 06:05 41568 σε απάντηση της 41566

    Απ: Deserialized objects "ξεχνάνε" τα AddHandler τους (VB.NET)

    Υπάρχει ένα design – pattern που ονομάζετε Observer.

    while (!dead) learn();
  •  17-04-2008, 10:31 41576 σε απάντηση της 41566

    Απ: Deserialized objects "ξεχνάνε" τα event handler τους (VB.NET)

    Τα events - που στην πραγματικότητα είναι delegates - όταν γίνονται serialize/deserialize κάνουν serialize/deserialize και τους delegate subscribers, δηλαδή τους event handlers, ακόμη κι αν αυτοί είναι private members. Αυτό σημαίνει ότι θα πρέπει να είναι Serializable. Βέβαια, αν δεν κάνω λάθος, η τυπική συμπεριφορά είναι να πάρεις exception όταν δεν ικανοποιείται η συνθήκη. 

    Αυτό που μπορείς να κάνεις είναι να υλοποιήσεις το IDeserializationCallback interface που σου επιτρέπει να πιάσεις τη στιγμή που γίνεται το deserialization και να κάνεις inject τον initialization κώδικα (βλ. AddHandler) που θες.


    Vir prudens non contra ventum mingit
  •  17-04-2008, 10:49 41579 σε απάντηση της 41576

    Απ: Deserialized objects "ξεχνάνε" τα event handler τους (VB.NET)

    Ξέχασα να σου πω ότι για να παίξει το IDeserializationCallback σενάριο θα πρέπει να φροντίσεις να μην κάνει serialize τα events και τους handlers, μαρκάροντας με τα attributes[NonSerialized] τα Events που κάνεις declare και με [field:NonSerialized] τους αντίστοιχους EventHandlers


    Vir prudens non contra ventum mingit
  •  17-04-2008, 13:26 41587 σε απάντηση της 41579

    Απ: Deserialized objects "ξεχνάνε" τα event handler τους (VB.NET)

    KelMan:

    Τα events - που στην πραγματικότητα είναι delegates - όταν γίνονται serialize/deserialize κάνουν serialize/deserialize και τους delegate subscribers, δηλαδή τους event handlers, ακόμη κι αν αυτοί είναι private members. Αυτό σημαίνει ότι θα πρέπει να είναι Serializable. Βέβαια, αν δεν κάνω λάθος, η τυπική συμπεριφορά είναι να πάρεις exception όταν δεν ικανοποιείται η συνθήκη.

    Αυτό σκεφτόμουν κια εγώ. 'Αλλωστε αν ολόκληρη η class ειναι serializable (και η Α και η Β) τότε λογικά και ο event handler θα είναι το ίδιο.

    Στην VB.NET τουλάχιστον πάντως δεν σου επιτρέπει να ορίσεις explicitly τον handler ως serializable.

    KelMan:

    Αυτό που μπορείς να κάνεις είναι να υλοποιήσεις το IDeserializationCallback interface που σου επιτρέπει να πιάσεις τη στιγμή που γίνεται το deserialization και να κάνεις inject τον initialization κώδικα (βλ. AddHandler) που θες.

    Αυτό όντως δούλεψε! 'Ελπιζα να μην χρειαστεί να φτάσω σε αυτό το σημείο (γιατι ουσιαστικά ειναι θεραπεία παρά πρόληψη) αλλά είναι αρκετά εύκολο να πακετάρω όλα τα handler registrations της κλασης σε μια μέθοδο και να την καλώ είτε από τον constructor είτε από το OnDeserialization.

    Ευχαριστώ πολύ για τη συμβουλή.
Προβολή Τροφοδοσίας RSS με μορφή XML
Με χρήση του Community Server (Commercial Edition), από την Telligent Systems