// Copyright 2004-2008 Castle Project - http://www.castleproject.org/
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
namespace Castle.DynamicProxy
{
using System;
using System.Collections;
using Castle.Core.Interceptor;
[CLSCompliant(true)]
public class ProxyGenerator
{
private readonly IProxyBuilder proxyBuilder;
#region Constructors
///
/// Initializes a new instance of the class.
///
/// The builder.
public ProxyGenerator(IProxyBuilder builder)
{
proxyBuilder = builder;
}
///
/// Initializes a new instance of the class.
///
public ProxyGenerator() : this(new DefaultProxyBuilder())
{
}
#endregion
#region Properties
///
/// Gets the proxy builder instance.
///
/// The proxy builder.
public IProxyBuilder ProxyBuilder
{
get { return proxyBuilder; }
}
#endregion
private void CheckNotGenericTypeDefinition(Type type, string argumentName)
{
if (type != null && type.IsGenericTypeDefinition)
{
throw new ArgumentException("You can't specify a generic type definition.", argumentName);
}
}
private void CheckNotGenericTypeDefinitions(IEnumerable types, string argumentName)
{
if (types != null)
{
foreach (Type t in types)
{
CheckNotGenericTypeDefinition(t, argumentName);
}
}
}
#region CreateInterfaceProxyWithTarget
public T CreateInterfaceProxyWithTarget(object target, params IInterceptor[] interceptors)
{
return (T) CreateInterfaceProxyWithTarget(typeof (T), target, ProxyGenerationOptions.Default, interceptors);
}
public T CreateInterfaceProxyWithTarget(object target, ProxyGenerationOptions options,
params IInterceptor[] interceptors)
{
return (T) CreateInterfaceProxyWithTarget(typeof (T), target, options, interceptors);
}
public object CreateInterfaceProxyWithTarget(Type theInterface, object target, params IInterceptor[] interceptors)
{
return CreateInterfaceProxyWithTarget(theInterface, target, ProxyGenerationOptions.Default, interceptors);
}
public object CreateInterfaceProxyWithTarget(Type theInterface, object target, ProxyGenerationOptions options,
params IInterceptor[] interceptors)
{
return CreateInterfaceProxyWithTarget(theInterface, null, target, options, interceptors);
}
public object CreateInterfaceProxyWithTarget(Type theInterface, Type[] interfaces,
object target, params IInterceptor[] interceptors)
{
return CreateInterfaceProxyWithTarget(theInterface, interfaces, target, ProxyGenerationOptions.Default, interceptors);
}
public object CreateInterfaceProxyWithTarget(Type theInterface, Type[] interfaces, object target,
ProxyGenerationOptions options, params IInterceptor[] interceptors)
{
if (theInterface == null)
{
throw new ArgumentNullException("theInterface");
}
if (target == null)
{
throw new ArgumentNullException("target");
}
if (interceptors == null)
{
throw new ArgumentNullException("interceptors");
}
if (!theInterface.IsInterface)
{
throw new ArgumentException("Specified type is not an interface", "theInterface");
}
if (!theInterface.IsAssignableFrom(target.GetType()))
{
throw new ArgumentException("Target does not implement interface " + theInterface.FullName, "target");
}
CheckNotGenericTypeDefinition(theInterface, "theInterface");
CheckNotGenericTypeDefinitions(interfaces, "interfaces");
Type targetType = target.GetType();
Type generatedType = CreateInterfaceProxyTypeWithTarget(theInterface, interfaces, targetType, options);
ArrayList arguments = GetConstructorArguments(target, interceptors, options);
return Activator.CreateInstance(generatedType, arguments.ToArray());
}
private ArrayList GetConstructorArguments(object target, IInterceptor[] interceptors, ProxyGenerationOptions options)
{
// create constructor arguments (initialized with mixin implementations, interceptors and target type constructor arguments)
ArrayList arguments = new ArrayList(options.MixinData.GetMixinInterfaceImplementationsAsArray());
arguments.Add(interceptors);
arguments.Add(target);
return arguments;
}
#endregion
#region CreateInterfaceProxyWithTargetInterface
public object CreateInterfaceProxyWithTargetInterface(Type theInterface, object target,
params IInterceptor[] interceptors)
{
return CreateInterfaceProxyWithTargetInterface(theInterface, target, ProxyGenerationOptions.Default, interceptors);
}
public object CreateInterfaceProxyWithTargetInterface(Type theInterface, object target,
ProxyGenerationOptions options,
params IInterceptor[] interceptors)
{
return CreateInterfaceProxyWithTargetInterface(theInterface, null, target, options, interceptors);
}
public object CreateInterfaceProxyWithTargetInterface(Type theInterface, Type[] interfaces, object target,
ProxyGenerationOptions options,
params IInterceptor[] interceptors)
{
if (!theInterface.IsInstanceOfType(target))
{
throw new ArgumentException("targetType");
}
if (theInterface == null)
{
throw new ArgumentNullException("theInterface");
}
if (target == null)
{
throw new ArgumentNullException("target");
}
if (interceptors == null)
{
throw new ArgumentNullException("interceptors");
}
if (!theInterface.IsInterface)
{
throw new ArgumentException("Specified type is not an interface", "theInterface");
}
if (!theInterface.IsAssignableFrom(target.GetType()))
{
throw new ArgumentException("Target does not implement interface " + theInterface.FullName, "target");
}
CheckNotGenericTypeDefinition(theInterface, "theInterface");
CheckNotGenericTypeDefinitions(interfaces, "interfaces");
Type generatedType = CreateInterfaceProxyTypeWithTargetInterface(theInterface, interfaces, theInterface, options);
ArrayList arguments = GetConstructorArguments(target, interceptors, options);
return Activator.CreateInstance(generatedType, arguments.ToArray());
}
#endregion
#region CreateInterfaceProxyWithoutTarget
public T CreateInterfaceProxyWithoutTarget(IInterceptor interceptor)
{
return (T) CreateInterfaceProxyWithoutTarget(typeof (T), interceptor);
}
public T CreateInterfaceProxyWithoutTarget(params IInterceptor[] interceptors)
{
return (T) CreateInterfaceProxyWithoutTarget(typeof (T), interceptors);
}
public object CreateInterfaceProxyWithoutTarget(Type theInterface, IInterceptor interceptor)
{
return CreateInterfaceProxyWithoutTarget(theInterface, new Type[0],
ProxyGenerationOptions.Default,
interceptor);
}
public object CreateInterfaceProxyWithoutTarget(Type theInterface, params IInterceptor[] interceptors)
{
return CreateInterfaceProxyWithoutTarget(theInterface, new Type[0], ProxyGenerationOptions.Default, interceptors);
}
public object CreateInterfaceProxyWithoutTarget(Type theInterface, Type[] interfaces,
params IInterceptor[] interceptors)
{
return CreateInterfaceProxyWithoutTarget(theInterface, interfaces, ProxyGenerationOptions.Default, interceptors);
}
public object CreateInterfaceProxyWithoutTarget(Type theInterface, Type[] interfaces, ProxyGenerationOptions options,
params IInterceptor[] interceptors)
{
if (theInterface == null)
{
throw new ArgumentNullException("theInterface");
}
if (interceptors == null)
{
throw new ArgumentNullException("interceptors");
}
if (!theInterface.IsInterface)
{
throw new ArgumentException("Specified type is not an interface", "theInterface");
}
CheckNotGenericTypeDefinition(theInterface, "theInterface");
CheckNotGenericTypeDefinitions(interfaces, "interfaces");
Type generatedType = CreateInterfaceProxyTypeWithoutTarget(theInterface, interfaces, options);
ArrayList arguments = GetConstructorArguments(new object(), interceptors, options);
return Activator.CreateInstance(generatedType, arguments.ToArray());
}
#endregion
#region CreateClassProxy
public T CreateClassProxy(params IInterceptor[] interceptors)
{
return (T) CreateClassProxy(typeof (T), ProxyGenerationOptions.Default, interceptors);
}
public object CreateClassProxy(Type targetType, params IInterceptor[] interceptors)
{
return CreateClassProxy(targetType, ProxyGenerationOptions.Default, interceptors);
}
///
/// Creates the class proxy.
///
/// Type of the target.
/// The interfaces.
/// The interceptors.
///
public object CreateClassProxy(Type targetType, Type[] interfaces, params IInterceptor[] interceptors)
{
return CreateClassProxy(targetType, interfaces, ProxyGenerationOptions.Default, interceptors);
}
///
/// Creates the class proxy.
///
/// Type of the target.
/// The interceptors.
/// The constructor args.
///
public object CreateClassProxy(Type targetType, IInterceptor[] interceptors,
params object[] constructorArgs)
{
return CreateClassProxy(targetType, null, ProxyGenerationOptions.Default,
constructorArgs, interceptors);
}
///
///
///
///
///
///
///
public object CreateClassProxy(Type targetType, ProxyGenerationOptions options, params IInterceptor[] interceptors)
{
return CreateClassProxy(targetType, null, options, interceptors);
}
public object CreateClassProxy(Type targetType, Type[] interfaces,
ProxyGenerationOptions options, params IInterceptor[] interceptors)
{
return CreateClassProxy(targetType, interfaces, options, null, interceptors);
}
///
/// Creates the class proxy.
///
/// Type of the target.
/// The interfaces.
/// The options.
/// The constructor args.
/// The interceptors.
///
public object CreateClassProxy(Type targetType, Type[] interfaces, ProxyGenerationOptions options,
object[] constructorArgs, params IInterceptor[] interceptors)
{
if (targetType == null)
{
throw new ArgumentNullException("targetType");
}
if (options == null)
{
throw new ArgumentNullException("options");
}
if (!targetType.IsClass)
{
throw new ArgumentException("'targetType' must be a class", "targetType");
}
CheckNotGenericTypeDefinition(targetType, "targetType");
CheckNotGenericTypeDefinitions(interfaces, "interfaces");
Type proxyType = CreateClassProxyType(targetType, interfaces, options);
// create constructor arguments (initialized with mixin implementations, interceptors and target type constructor arguments)
ArrayList arguments = new ArrayList(options.MixinData.GetMixinInterfaceImplementationsAsArray());
arguments.Add(interceptors);
if (constructorArgs != null && constructorArgs.Length != 0)
{
arguments.AddRange(constructorArgs);
}
// create instance
return Activator.CreateInstance(proxyType, arguments.ToArray());
}
#endregion
protected Type CreateClassProxyType(Type baseClass, Type[] interfaces, ProxyGenerationOptions options)
{
// create proxy
return ProxyBuilder.CreateClassProxy(baseClass, interfaces, options);
}
protected Type CreateInterfaceProxyTypeWithTarget(Type theInterface, Type[] interfaces, Type targetType,
ProxyGenerationOptions options)
{
// create proxy
return ProxyBuilder.CreateInterfaceProxyTypeWithTarget(theInterface, interfaces, targetType, options);
}
protected Type CreateInterfaceProxyTypeWithTargetInterface(Type theInterface, Type[] interfaces, Type targetType,
ProxyGenerationOptions options)
{
// create proxy
return ProxyBuilder.CreateInterfaceProxyTypeWithTargetInterface(theInterface, interfaces, options);
}
protected Type CreateInterfaceProxyTypeWithoutTarget(Type theInterface, Type[] interfaces,
ProxyGenerationOptions options)
{
// create proxy
return ProxyBuilder.CreateInterfaceProxyTypeWithoutTarget(theInterface, interfaces, options);
}
}
}