1 // Copyright 2004-2007 Castle Project - http://www.castleproject.org/
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
7 // http://www.apache.org/licenses/LICENSE-2.0
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
15 namespace Castle
.DynamicProxy
.Serialization
18 using System
.Collections
;
19 using System
.Reflection
;
20 using System
.Runtime
.Serialization
;
22 using Castle
.DynamicProxy
.Builder
.CodeGenerators
;
25 /// Handles the deserialization of proxies.
28 public class ProxyObjectReference
: IObjectReference
, ISerializable
30 private static ModuleScope _scope
= new ModuleScope();
32 private Type _baseType
;
33 private Type
[] _interfaces
;
34 private IInterceptor _interceptor
;
35 private object[] _mixins
;
36 private object[] _data
;
37 private object _proxy
;
40 /// Usefull for test cases
42 public static void ResetScope()
44 _scope
= new ModuleScope();
47 protected ProxyObjectReference(SerializationInfo info
, StreamingContext context
)
49 _interceptor
= (IInterceptor
) info
.GetValue("__interceptor", typeof(IInterceptor
) );
50 _baseType
= (Type
) info
.GetValue("__baseType", typeof(Type
) );
51 _mixins
= (object[]) info
.GetValue("__mixins", typeof(object[]) );
53 String
[] _interfaceNames
= (String
[]) info
.GetValue("__interfaces", typeof(String
[]) );
55 _interfaces
= new Type
[_interfaceNames
.Length
];
57 for (int i
= 0; i
< _interfaceNames
.Length
; i
++)
59 _interfaces
[i
] = Type
.GetType(_interfaceNames
[i
]);
62 _proxy
= RecreateProxy(info
, context
);
64 InvokeCallback(_proxy
);
67 protected virtual object RecreateProxy(SerializationInfo info
, StreamingContext context
)
69 if (_baseType
== typeof(object))
71 return RecreateInterfaceProxy(info
, context
);
75 return RecreateClassProxy(info
, context
);
79 public object RecreateInterfaceProxy(SerializationInfo info
, StreamingContext context
)
83 GeneratorContext genContext
= new GeneratorContext();
85 foreach(object mixin
in _mixins
)
87 genContext
.AddMixinInstance(mixin
);
90 InterfaceProxyGenerator gen
= new InterfaceProxyGenerator( _scope
, genContext
);
92 object target
= info
.GetValue("__target", typeof(object));
94 if (_mixins
.Length
== 0)
96 Type proxy_type
= gen
.GenerateCode( _interfaces
, target
.GetType());
98 proxy
= Activator
.CreateInstance( proxy_type
, new object[] { _interceptor, target }
);
102 Type proxy_type
= gen
.GenerateCode( _interfaces
, target
.GetType() );
104 proxy
= Activator
.CreateInstance( proxy_type
, new object[] { _interceptor, target, genContext.MixinsAsArray() }
);
110 public object RecreateClassProxy(SerializationInfo info
, StreamingContext context
)
112 bool delegateBaseSer
= info
.GetBoolean("__delegateToBase");
114 if (!delegateBaseSer
)
116 _data
= (object[]) info
.GetValue("__data", typeof(object[]) );
121 GeneratorContext genContext
= new GeneratorContext();
123 if (_mixins
.Length
!= 0)
125 foreach(object mixin
in _mixins
)
127 genContext
.AddMixinInstance(mixin
);
131 ClassProxyGenerator cpGen
= new ClassProxyGenerator( _scope
, genContext
);
135 if (_mixins
.Length
== 0)
137 proxy_type
= cpGen
.GenerateCode( _baseType
, _interfaces
);
141 proxy_type
= cpGen
.GenerateCustomCode( _baseType
, _interfaces
);
146 proxy
= Activator
.CreateInstance( proxy_type
, new object[] { info, context }
);
150 if (_mixins
.Length
== 0)
152 proxy
= Activator
.CreateInstance( proxy_type
, new object[] { _interceptor }
);
156 ArrayList args
= new ArrayList();
157 args
.Add(_interceptor
);
158 args
.Add(genContext
.MixinsAsArray());
160 proxy
= Activator
.CreateInstance( proxy_type
, args
.ToArray() );
163 MemberInfo
[] members
= FormatterServices
.GetSerializableMembers( _baseType
);
164 FormatterServices
.PopulateObjectMembers(proxy
, members
, _data
);
170 protected void InvokeCallback(object target
)
172 if (target
is IDeserializationCallback
)
174 (target
as IDeserializationCallback
).OnDeserialization(this);
178 public object GetRealObject(StreamingContext context
)
183 public void GetObjectData(SerializationInfo info
, StreamingContext context
)
185 // There is no need to implement this method as
186 // this class would never be serialized.