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
18 using System
.Collections
;
20 using Castle
.DynamicProxy
.Builder
;
23 /// Generates a Java style proxy. This overrides the .Net proxy requirements
24 /// that forces one to extend MarshalByRefObject or (for a different purpose)
25 /// ContextBoundObject to have a Proxiable class.
28 /// The <see cref="ProxyGenerator"/> should be used to generate a class
29 /// implementing the specified interfaces. The dynamic implementation will
30 /// only calls the internal <see cref="IInterceptor"/> instance.
33 /// Please note that this proxy implementation currently doesn't not supports ref and out arguments
35 /// Also note that only virtual methods can be proxied in a class.
39 /// MyInvocationHandler interceptor = ...
40 /// ProxyGenerator generator = new ProxyGenerator();
41 /// IInterfaceExposed proxy =
42 /// generator.CreateProxy( new Type[] { typeof(IInterfaceExposed) }, interceptor );
45 public class ProxyGenerator
47 private IProxyBuilder _builder
;
49 public ProxyGenerator(IProxyBuilder builder
)
54 public ProxyGenerator() : this( new DefaultProxyBuilder() )
58 public IProxyBuilder ProxyBuilder
60 get { return _builder; }
61 set { _builder = value; }
64 public virtual object CreateClassProxy(Type baseClass
, IInterceptor interceptor
,
65 params object[] argumentsForConstructor
)
67 return CreateClassProxy (baseClass
, interceptor
, true, argumentsForConstructor
);
70 public virtual object CreateClassProxy(Type baseClass
, IInterceptor interceptor
, bool checkAbstract
,
71 params object[] argumentsForConstructor
)
73 AssertUtil
.IsClass(baseClass
, "baseClass", checkAbstract
);
74 AssertUtil
.NotNull(interceptor
, "interceptor");
76 Type newType
= ProxyBuilder
.CreateClassProxy(baseClass
);
77 return CreateClassProxyInstance( newType
, interceptor
, argumentsForConstructor
);
80 public virtual object CreateClassProxy(Type baseClass
, Type
[] interfaces
,
81 IInterceptor interceptor
, params object[] argumentsForConstructor
)
83 return CreateClassProxy(baseClass
, interfaces
, interceptor
, true, argumentsForConstructor
);
86 public virtual object CreateClassProxy(Type baseClass
, Type
[] interfaces
,
87 IInterceptor interceptor
, bool checkAbstract
, params object[] argumentsForConstructor
)
89 AssertUtil
.IsClass(baseClass
, "baseClass", checkAbstract
);
90 AssertUtil
.NotNull(interceptor
, "interceptor");
91 AssertUtil
.NotNull(interfaces
, "interfaces");
93 Type newType
= ProxyBuilder
.CreateClassProxy(baseClass
, interfaces
);
95 return CreateClassProxyInstance( newType
, interceptor
, argumentsForConstructor
);
98 public virtual object CreateCustomClassProxy(Type baseClass
,
99 IInterceptor interceptor
, GeneratorContext context
,
100 params object[] argumentsForConstructor
)
102 return CreateCustomClassProxy(baseClass
, interceptor
, context
, true, argumentsForConstructor
);
105 public virtual object CreateCustomClassProxy(Type baseClass
,
106 IInterceptor interceptor
, GeneratorContext context
, bool checkAbstract
,
107 params object[] argumentsForConstructor
)
109 AssertUtil
.IsClass(baseClass
, "baseClass", checkAbstract
);
110 AssertUtil
.NotNull(interceptor
, "interceptor");
111 AssertUtil
.NotNull(context
, "context");
113 Type newType
= ProxyBuilder
.CreateCustomClassProxy(baseClass
, context
);
114 return CreateCustomClassProxyInstance( newType
, interceptor
, context
,
115 argumentsForConstructor
);
119 /// Generates a proxy implementing all the specified interfaces and
120 /// redirecting method invocations to the specifed interceptor.
122 /// <param name="theInterface">Interface to be implemented</param>
123 /// <param name="interceptor">instance of <see cref="IInterceptor"/></param>
124 /// <param name="target">The proxy target.</param>
125 /// <returns>Proxy instance</returns>
126 public virtual object CreateProxy(Type theInterface
, IInterceptor interceptor
, object target
)
128 return CreateProxy(new Type
[] {theInterface}
, interceptor
, target
);
132 /// Generates a proxy implementing all the specified interfaces and
133 /// redirecting method invocations to the specifed interceptor.
135 /// <param name="interfaces">Array of interfaces to be implemented</param>
136 /// <param name="interceptor">instance of <see cref="IInterceptor"/></param>
137 /// <param name="target">The proxy target.</param>
138 /// <returns>Proxy instance</returns>
139 public virtual object CreateProxy(Type
[] interfaces
, IInterceptor interceptor
, object target
)
141 AssertUtil
.IsInterface(interfaces
, "interfaces");
142 AssertUtil
.NotNull(interceptor
, "interceptor");
143 AssertUtil
.NotNull(target
, "target");
145 Type newType
= ProxyBuilder
.CreateInterfaceProxy(interfaces
, target
.GetType());
146 return CreateProxyInstance( newType
, interceptor
, target
);
152 /// <param name="theInterface"></param>
153 /// <param name="interceptor"></param>
154 /// <param name="context"></param>
155 /// <param name="target">The proxy target.</param>
156 /// <returns></returns>
157 public virtual object CreateCustomProxy(Type theInterface
,
158 IInterceptor interceptor
, object target
, GeneratorContext context
)
160 return CreateCustomProxy( new Type
[] { theInterface }
, interceptor
, target
, context
);
166 /// <param name="interfaces"></param>
167 /// <param name="interceptor"></param>
168 /// <param name="context"></param>
169 /// <param name="target">The proxy target.</param>
170 /// <returns></returns>
171 public virtual object CreateCustomProxy(Type
[] interfaces
,
172 IInterceptor interceptor
, object target
, GeneratorContext context
)
174 AssertUtil
.IsInterface(interfaces
, "interfaces");
175 AssertUtil
.NotNull(interceptor
, "interceptor");
176 AssertUtil
.NotNull(target
, "target");
177 AssertUtil
.NotNull(context
, "context");
179 Type newType
= ProxyBuilder
.CreateCustomInterfaceProxy(interfaces
, target
.GetType(), context
);
180 return CreateCustomProxyInstance( newType
, interceptor
, target
, context
);
183 protected virtual object CreateProxyInstance(Type type
, IInterceptor interceptor
, object target
)
185 return Activator
.CreateInstance(type
, new object[] {interceptor, target}
);
188 protected virtual object CreateCustomProxyInstance(Type type
, IInterceptor interceptor
,
189 object target
, GeneratorContext context
)
191 if (context
.HasMixins
)
193 return Activator
.CreateInstance( type
, new object[] { interceptor, target, context.MixinsAsArray() }
);
195 return CreateProxyInstance( type
, interceptor
, target
);
198 protected virtual object CreateClassProxyInstance(Type type
, IInterceptor interceptor
,
199 params object[] argumentsForConstructor
)
201 ArrayList args
= new ArrayList();
202 args
.Add(interceptor
);
203 args
.AddRange(argumentsForConstructor
);
205 return Activator
.CreateInstance(type
, args
.ToArray());
208 protected virtual object CreateCustomClassProxyInstance(Type type
, IInterceptor interceptor
,
209 GeneratorContext context
, params object[] argumentsForConstructor
)
211 if (context
.HasMixins
)
213 ArrayList args
= new ArrayList();
214 args
.Add(interceptor
);
215 args
.Add(context
.MixinsAsArray());
216 args
.AddRange(argumentsForConstructor
);
218 return Activator
.CreateInstance( type
, args
.ToArray() );
220 return CreateClassProxyInstance( type
, interceptor
, argumentsForConstructor
);
223 protected virtual object CreateCustomClassProxyInstance(Type type
, IInterceptor interceptor
,
224 GeneratorContext context
, object target
)
226 return CreateProxyInstance( type
, interceptor
, target
);