2 // System.Runtime.Serialization.SerializationCallbacks.cs
5 // Robert Jordan (robertj@gmx.net)
7 // Copyright (C) 2006 Novell, Inc (http://www.novell.com)
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 using System
.Collections
;
31 using System
.Reflection
;
33 namespace System
.Runtime
.Serialization
{
35 internal sealed class SerializationCallbacks
37 public delegate void CallbackHandler (StreamingContext context
);
39 readonly ArrayList onSerializingList
;
40 readonly ArrayList onSerializedList
;
41 readonly ArrayList onDeserializingList
;
42 readonly ArrayList onDeserializedList
;
44 public bool HasSerializingCallbacks
{
45 get {return onSerializingList != null;}
48 public bool HasSerializedCallbacks
{
49 get {return onSerializedList != null;}
52 public bool HasDeserializingCallbacks
{
53 get {return onDeserializingList != null;}
56 public bool HasDeserializedCallbacks
{
57 get {return onDeserializedList != null;}
60 public SerializationCallbacks (Type type
)
62 onSerializingList
= GetMethodsByAttribute (type
, typeof (OnSerializingAttribute
));
63 onSerializedList
= GetMethodsByAttribute (type
, typeof (OnSerializedAttribute
));
64 onDeserializingList
= GetMethodsByAttribute (type
, typeof (OnDeserializingAttribute
));
65 onDeserializedList
= GetMethodsByAttribute (type
, typeof (OnDeserializedAttribute
));
68 const BindingFlags DefaultBindingFlags
= BindingFlags
.Public
| BindingFlags
.NonPublic
|
69 BindingFlags
.Instance
| BindingFlags
.DeclaredOnly
;
72 static ArrayList
GetMethodsByAttribute (Type type
, Type attr
)
74 ArrayList list
= new ArrayList ();
77 while (t
!= typeof (object)) {
80 foreach (MethodInfo mi
in t
.GetMethods (DefaultBindingFlags
)) {
81 if (mi
.IsDefined (attr
, false)) {
87 // FIXME: MS.NET is checking for this with the verifier at assembly load time.
89 throw new TypeLoadException (
90 String
.Format ("Type '{0}' has more than one method with the following attribute: '{1}'.", type
.AssemblyQualifiedName
, attr
.FullName
));
95 // optimize memory usage
96 return list
.Count
== 0 ? null : list
;
99 static void Invoke (ArrayList list
, object target
, StreamingContext context
)
104 CallbackHandler handler
= null;
106 // construct a delegate from the specified list
107 foreach (MethodInfo mi
in list
) {
108 handler
= (CallbackHandler
)
110 Delegate
.CreateDelegate (typeof (CallbackHandler
), target
, mi
),
117 public void RaiseOnSerializing (object target
, StreamingContext contex
)
119 Invoke (onSerializingList
, target
, contex
);
122 public void RaiseOnSerialized (object target
, StreamingContext contex
)
124 Invoke (onSerializedList
, target
, contex
);
127 public void RaiseOnDeserializing (object target
, StreamingContext contex
)
129 Invoke (onDeserializingList
, target
, contex
);
132 public void RaiseOnDeserialized (object target
, StreamingContext contex
)
134 Invoke (onDeserializedList
, target
, contex
);
137 static Hashtable cache
= new Hashtable ();
138 static object cache_lock
= new object ();
140 public static SerializationCallbacks
GetSerializationCallbacks (Type t
)
142 SerializationCallbacks sc
= (SerializationCallbacks
) cache
[t
];
146 // Slow path, new entry, we need to copy
148 sc
= (SerializationCallbacks
) cache
[t
];
150 Hashtable copy
= (Hashtable
) cache
.Clone ();
152 sc
= new SerializationCallbacks (t
);