DefaultProxyFactory
This implementation of IProxyFactory relies
on DynamicProxy to expose proxy capabilities.
using Castle.Core;
using Castle.Core.Interceptor;
using Castle.Core.Internal;
using Castle.DynamicProxy;
using Castle.MicroKernel;
using Castle.MicroKernel.Context;
using Castle.MicroKernel.Proxy;
using System;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization;
namespace Castle.Windsor.Proxy
{
[Serializable]
public class DefaultProxyFactory : AbstractProxyFactory, IDeserializationCallback
{
[NonSerialized]
protected ProxyGenerator generator;
public DefaultProxyFactory()
: this(new ProxyGenerator())
{
}
public DefaultProxyFactory(bool disableSignedModule)
: this(new ProxyGenerator(disableSignedModule))
{
}
public DefaultProxyFactory(ProxyGenerator generator)
{
this.generator = generator;
}
public override object Create(IProxyFactoryExtension customFactory, IKernel kernel, ComponentModel model, CreationContext context, params object[] constructorArguments)
{
IInterceptor[] interceptors = ObtainInterceptors(kernel, model, context);
ProxyGenerationOptions val = CreateProxyGenerationOptionsFrom(model.ObtainProxyOptions(true), kernel, context, model);
CustomizeOptions(val, kernel, model, constructorArguments);
IProxyBuilder builder = generator.get_ProxyBuilder();
object obj = customFactory.Generate(builder, val, interceptors, model, context);
CustomizeProxy(obj, val, kernel, model);
ReleaseHook(val, kernel);
return obj;
}
private void ReleaseHook(ProxyGenerationOptions proxyGenOptions, IKernel kernel)
{
if ((int)proxyGenOptions.get_Hook() != 0)
kernel.ReleaseComponent((object)proxyGenOptions.get_Hook());
}
public override object Create(IKernel kernel, object target, ComponentModel model, CreationContext context, params object[] constructorArguments)
{
IInterceptor[] array = ObtainInterceptors(kernel, model, context);
ProxyOptions proxyOptions = model.ObtainProxyOptions(true);
ProxyGenerationOptions val = CreateProxyGenerationOptionsFrom(proxyOptions, kernel, context, model);
CustomizeOptions(val, kernel, model, constructorArguments);
Type[] additionalInterfaces = proxyOptions.AdditionalInterfaces;
object obj;
if (!model.HasClassServices) {
Type type = model.Services.First();
Type[] array2 = model.Services.Skip(1).Concat(additionalInterfaces).ToArray();
obj = (proxyOptions.OmitTarget ? generator.CreateInterfaceProxyWithoutTarget(type, array2, val, array) : ((!proxyOptions.AllowChangeTarget) ? generator.CreateInterfaceProxyWithTarget(type, array2, target, val, array) : generator.CreateInterfaceProxyWithTargetInterface(type, array2, target, val, array)));
} else {
Type type2 = (!(model.Implementation != (Type)null) || !(model.Implementation != typeof(LateBoundComponent))) ? model.Services.First() : model.Implementation;
Type[] array3 = model.Services.SkipWhile((Type s) => s.GetTypeInfo().IsClass).Concat(additionalInterfaces).ToArray();
obj = generator.CreateClassProxy(type2, array3, val, constructorArguments, array);
}
CustomizeProxy(obj, val, kernel, model);
ReleaseHook(val, kernel);
return obj;
}
protected static ProxyGenerationOptions CreateProxyGenerationOptionsFrom(ProxyOptions proxyOptions, IKernel kernel, CreationContext context, ComponentModel model)
{
ProxyGenerationOptions val = new ProxyGenerationOptions();
if (proxyOptions.Hook != null) {
IProxyGenerationHook val2 = proxyOptions.Hook.Resolve(kernel, context);
if (val2 != null && val2 is IOnBehalfAware)
((IOnBehalfAware)val2).SetInterceptedComponentModel(model);
val.set_Hook(val2);
}
if (proxyOptions.Selector != null) {
IInterceptorSelector val3 = proxyOptions.Selector.Resolve(kernel, context);
if (val3 != null && val3 is IOnBehalfAware)
((IOnBehalfAware)val3).SetInterceptedComponentModel(model);
val.set_Selector(val3);
}
foreach (IReference<object> mixIn in proxyOptions.MixIns) {
object obj = mixIn.Resolve(kernel, context);
val.AddMixinInstance(obj);
}
return val;
}
protected virtual void CustomizeProxy(object proxy, ProxyGenerationOptions options, IKernel kernel, ComponentModel model)
{
}
protected virtual void CustomizeOptions(ProxyGenerationOptions options, IKernel kernel, ComponentModel model, object[] arguments)
{
}
public override bool RequiresTargetInstance(IKernel kernel, ComponentModel model)
{
ProxyOptions proxyOptions = model.ObtainProxyOptions(true);
if (!model.HasClassServices)
return !proxyOptions.OmitTarget;
return false;
}
public void OnDeserialization(object sender)
{
generator = new ProxyGenerator();
}
}
}