Adding Mixin support.
[castle.git] / Tools / Castle.DynamicProxy2 / Castle.DynamicProxy / ProxyGenerator.cs
blob06905d0ad12697e1cc703f92884babd3e2d8b5f3
1 // Copyright 2004-2007 Castle Project - http://www.castleproject.org/
2 //
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
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
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 using System.Collections;
17 namespace Castle.DynamicProxy
19 using System;
20 using Castle.Core.Interceptor;
22 [CLSCompliant(true)]
23 public class ProxyGenerator
25 private readonly IProxyBuilder proxyBuilder;
27 #region Constructors
29 /// <summary>
30 /// Initializes a new instance of the <see cref="ProxyGenerator"/> class.
31 /// </summary>
32 /// <param name="builder">The builder.</param>
33 public ProxyGenerator(IProxyBuilder builder)
35 proxyBuilder = builder;
38 /// <summary>
39 /// Initializes a new instance of the <see cref="ProxyGenerator"/> class.
40 /// </summary>
41 public ProxyGenerator() : this(new DefaultProxyBuilder())
45 #endregion
47 #region Properties
49 /// <summary>
50 /// Gets the proxy builder instance.
51 /// </summary>
52 /// <value>The proxy builder.</value>
53 public IProxyBuilder ProxyBuilder
55 get { return proxyBuilder; }
58 #endregion
60 #region CreateInterfaceProxyWithTarget
61 #if DOTNET2
63 public T CreateInterfaceProxyWithTarget<T>(object target, params IInterceptor[] interceptors)
65 return (T) CreateInterfaceProxyWithTarget(typeof(T), target, ProxyGenerationOptions.Default, interceptors);
68 public T CreateInterfaceProxyWithTarget<T>(object target, ProxyGenerationOptions options,
69 params IInterceptor[] interceptors)
71 return (T) CreateInterfaceProxyWithTarget(typeof(T), target, options, interceptors);
73 #endif
75 public object CreateInterfaceProxyWithTarget(Type theInterface, object target, params IInterceptor[] interceptors)
77 return CreateInterfaceProxyWithTarget(theInterface, target, ProxyGenerationOptions.Default, interceptors);
80 public object CreateInterfaceProxyWithTarget(Type theInterface, object target, ProxyGenerationOptions options,
81 params IInterceptor[] interceptors)
83 return CreateInterfaceProxyWithTarget(theInterface, null, target, options, interceptors);
86 public object CreateInterfaceProxyWithTarget(Type theInterface, Type[] interfaces,
87 object target, params IInterceptor[] interceptors)
89 return CreateInterfaceProxyWithTarget(theInterface, interfaces, target, ProxyGenerationOptions.Default, interceptors);
92 public object CreateInterfaceProxyWithTarget(Type theInterface, Type[] interfaces, object target,
93 ProxyGenerationOptions options, params IInterceptor[] interceptors)
95 if (theInterface == null)
97 throw new ArgumentNullException("theInterface");
99 if (target == null)
101 throw new ArgumentNullException("target");
103 if (interceptors == null)
105 throw new ArgumentNullException("interceptors");
108 if (!theInterface.IsInterface)
110 throw new ArgumentException("Specified type is not an interface", "theInterface");
113 if (!theInterface.IsAssignableFrom(target.GetType()))
115 throw new ArgumentException("Target does not implement interface " + theInterface.FullName, "target");
118 if (theInterface.IsGenericTypeDefinition)
120 throw new ArgumentException("You can't specify a generic interface definition", "theInterface");
123 Type targetType = target.GetType();
124 Type generatedType;
126 if (theInterface.IsGenericType)
128 generatedType =
129 CreateInterfaceProxyTypeWithTarget(theInterface.GetGenericTypeDefinition(), interfaces,
130 targetType.GetGenericTypeDefinition(), options);
132 else
134 generatedType = CreateInterfaceProxyTypeWithTarget(theInterface, interfaces, targetType, options);
137 if (theInterface.IsGenericType)
139 Type[] args = theInterface.GetGenericArguments();
140 generatedType = generatedType.MakeGenericType(args);
143 ArrayList argsForCtor = new ArrayList();
144 argsForCtor.AddRange(options.MixinInterfaceImplementationsAsArray());
145 argsForCtor.Add(interceptors);
146 argsForCtor.Add(target);
147 return Activator.CreateInstance(generatedType, argsForCtor.ToArray());
150 #endregion
152 #region CreateInterfaceProxyWithTargetInterface
154 public object CreateInterfaceProxyWithTargetInterface(Type theInterface, object target,
155 params IInterceptor[] interceptors)
157 return CreateInterfaceProxyWithTargetInterface(theInterface, target, ProxyGenerationOptions.Default, interceptors);
160 public object CreateInterfaceProxyWithTargetInterface(Type theInterface, object target,
161 ProxyGenerationOptions options,
162 params IInterceptor[] interceptors)
164 if (!theInterface.IsInstanceOfType(target))
166 throw new ArgumentException("targetType");
168 if (theInterface == null)
170 throw new ArgumentNullException("theInterface");
172 if (target == null)
174 throw new ArgumentNullException("target");
176 if (interceptors == null)
178 throw new ArgumentNullException("interceptors");
181 if (!theInterface.IsInterface)
183 throw new ArgumentException("Specified type is not an interface", "theInterface");
186 if (!theInterface.IsAssignableFrom(target.GetType()))
188 throw new ArgumentException("Target does not implement interface " + theInterface.FullName, "target");
191 if (theInterface.IsGenericTypeDefinition)
193 throw new ArgumentException("You can't specify a generic interface definition", "theInterface");
196 Type generatedType;
198 if (theInterface.IsGenericType)
200 generatedType =
201 CreateInterfaceProxyTypeWithTargetInterface(theInterface.GetGenericTypeDefinition(), null,
202 theInterface.GetGenericTypeDefinition(), options);
204 else
206 generatedType = CreateInterfaceProxyTypeWithTargetInterface(theInterface, null, theInterface, options);
209 if (theInterface.IsGenericType)
211 Type[] args = theInterface.GetGenericArguments();
212 generatedType = generatedType.MakeGenericType(args);
215 return Activator.CreateInstance(generatedType, new object[] {interceptors, target});
218 #endregion
220 #region CreateInterfaceProxyWithoutTarget
221 #if DOTNET2
222 public T CreateInterfaceProxyWithoutTarget<T>(IInterceptor interceptor)
224 return (T) CreateInterfaceProxyWithoutTarget(typeof(T), interceptor);
227 public T CreateInterfaceProxyWithoutTarget<T>(params IInterceptor[] interceptors)
229 return (T) CreateInterfaceProxyWithoutTarget(typeof(T), interceptors);
231 #endif
232 public object CreateInterfaceProxyWithoutTarget(Type theInterface, IInterceptor interceptor)
234 return CreateInterfaceProxyWithoutTarget(theInterface, new Type[0],
235 ProxyGenerationOptions.Default,
236 interceptor);
239 public object CreateInterfaceProxyWithoutTarget(Type theInterface, params IInterceptor[] interceptors)
241 return CreateInterfaceProxyWithoutTarget(theInterface, new Type[0], ProxyGenerationOptions.Default, interceptors);
244 public object CreateInterfaceProxyWithoutTarget(Type theInterface, Type[] interfaces,
245 params IInterceptor[] interceptors)
247 return CreateInterfaceProxyWithoutTarget(theInterface, interfaces, ProxyGenerationOptions.Default, interceptors);
250 public object CreateInterfaceProxyWithoutTarget(Type theInterface, Type[] interfaces, ProxyGenerationOptions options,
251 params IInterceptor[] interceptors)
253 if (theInterface == null)
255 throw new ArgumentNullException("theInterface");
257 if (interceptors == null)
259 throw new ArgumentNullException("interceptors");
262 if (!theInterface.IsInterface)
264 throw new ArgumentException("Specified type is not an interface", "theInterface");
267 if (theInterface.IsGenericTypeDefinition)
269 throw new ArgumentException("You can't specify a generic interface definition", "theInterface");
272 Type generatedType;
274 if (theInterface.IsGenericType)
276 generatedType = CreateInterfaceProxyTypeWithoutTarget(theInterface.GetGenericTypeDefinition(), interfaces, options);
278 else
280 generatedType = CreateInterfaceProxyTypeWithoutTarget(theInterface, interfaces, options);
283 if (theInterface.IsGenericType)
285 Type[] args = theInterface.GetGenericArguments();
286 generatedType = generatedType.MakeGenericType(args);
289 return Activator.CreateInstance(generatedType, new object[] {interceptors, new object(),});
292 #endregion
294 #region CreateClassProxy
295 #if DOTNET2
296 public T CreateClassProxy<T>(params IInterceptor[] interceptors)
298 return (T) CreateClassProxy(typeof(T), ProxyGenerationOptions.Default, interceptors);
301 public object CreateClassProxy(Type targetType, params IInterceptor[] interceptors)
303 return CreateClassProxy(targetType, ProxyGenerationOptions.Default, interceptors);
305 #endif
306 /// <summary>
307 /// Creates the class proxy.
308 /// </summary>
309 /// <param name="targetType">Type of the target.</param>
310 /// <param name="interfaces">The interfaces.</param>
311 /// <param name="interceptors">The interceptors.</param>
312 /// <returns></returns>
313 public object CreateClassProxy(Type targetType, Type[] interfaces, params IInterceptor[] interceptors)
315 return CreateClassProxy(targetType, interfaces, ProxyGenerationOptions.Default, interceptors);
318 /// <summary>
319 /// Creates the class proxy.
320 /// </summary>
321 /// <param name="targetType">Type of the target.</param>
322 /// <param name="interceptors">The interceptors.</param>
323 /// <param name="constructorArgs">The constructor args.</param>
324 /// <returns></returns>
325 public object CreateClassProxy(Type targetType, IInterceptor[] interceptors,
326 params object[] constructorArgs)
328 return CreateClassProxy(targetType, null, ProxyGenerationOptions.Default,
329 constructorArgs, interceptors);
332 /// <summary>
333 ///
334 /// </summary>
335 /// <param name="targetType"></param>
336 /// <param name="options"></param>
337 /// <param name="interceptors"></param>
338 /// <returns></returns>
339 public object CreateClassProxy(Type targetType, ProxyGenerationOptions options, params IInterceptor[] interceptors)
341 return CreateClassProxy(targetType, null, options, interceptors);
344 public object CreateClassProxy(Type targetType, Type[] interfaces,
345 ProxyGenerationOptions options, params IInterceptor[] interceptors)
347 return CreateClassProxy(targetType, interfaces, options, null, interceptors);
350 /// <summary>
351 /// Creates the class proxy.
352 /// </summary>
353 /// <param name="targetType">Type of the target.</param>
354 /// <param name="interfaces">The interfaces.</param>
355 /// <param name="options">The options.</param>
356 /// <param name="constructorArgs">The constructor args.</param>
357 /// <param name="interceptors">The interceptors.</param>
358 /// <returns></returns>
359 public object CreateClassProxy(Type targetType, Type[] interfaces, ProxyGenerationOptions options,
360 object[] constructorArgs, params IInterceptor[] interceptors)
362 if (targetType == null)
364 throw new ArgumentNullException("targetType");
366 if (options == null)
368 throw new ArgumentNullException("options");
370 if (!targetType.IsClass)
372 throw new ArgumentException("'targetType' must be a class", "targetType");
375 Type proxyType;
377 #if DOTNET2
378 if (targetType.IsGenericTypeDefinition)
380 throw new ArgumentException("You can't specify a generic type definition", "baseClass");
384 if (targetType.IsGenericType)
386 proxyType = CreateClassProxyType(targetType.GetGenericTypeDefinition(), interfaces, options);
388 else
389 #endif
391 proxyType = CreateClassProxyType(targetType, interfaces, options);
394 #if DOTNET2
395 if (targetType.IsGenericType)
397 proxyType = proxyType.MakeGenericType(targetType.GetGenericArguments());
399 #endif
401 object[] args = GetConstructorArguments(constructorArgs, interceptors, options);
403 return Activator.CreateInstance(proxyType, args);
406 private static object[] GetConstructorArguments(object[] constructorArgs, IInterceptor[] interceptors, ProxyGenerationOptions options)
408 ArrayList args = new ArrayList();
409 args.AddRange(options.MixinInterfaceImplementationsAsArray());
411 args.Add(interceptors);
414 if (constructorArgs != null && constructorArgs.Length != 0)
416 args.AddRange(constructorArgs);
418 return args.ToArray();
421 #endregion
423 protected Type CreateClassProxyType(Type baseClass, Type[] interfaces, ProxyGenerationOptions options)
425 options.Initialize();
426 return ProxyBuilder.CreateClassProxy(baseClass, interfaces, options);
429 protected Type CreateInterfaceProxyTypeWithTarget(Type theInterface, Type[] interfaces, Type targetType,
430 ProxyGenerationOptions options)
432 options.Initialize();
433 return ProxyBuilder.CreateInterfaceProxyTypeWithTarget(theInterface, interfaces, targetType, options);
436 protected Type CreateInterfaceProxyTypeWithTargetInterface(Type theInterface, Type[] interfaces, Type targetType,
437 ProxyGenerationOptions options)
439 options.Initialize();
440 return ProxyBuilder.CreateInterfaceProxyTypeWithTargetInterface(theInterface, options);
443 protected Type CreateInterfaceProxyTypeWithoutTarget(Type theInterface, Type[] interfaces,
444 ProxyGenerationOptions options)
446 options.Initialize();
447 return ProxyBuilder.CreateInterfaceProxyTypeWithoutTarget(theInterface, interfaces, options);