1 // Copyright 2004-2008 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
.Windsor
.Proxy
18 using System
.Reflection
;
19 using System
.Runtime
.Serialization
;
21 using Castle
.Core
.Interceptor
;
22 using Castle
.DynamicProxy
;
23 using Castle
.MicroKernel
;
24 using Castle
.MicroKernel
.Proxy
;
27 /// This implementation of <see cref="IProxyFactory"/> relies
28 /// on DynamicProxy to expose proxy capabilies.
31 /// Note that only virtual methods can be intercepted in a
32 /// concrete class. However, if the component
33 /// was registered with a service interface, we proxy
34 /// the interface and the methods don't need to be virtual,
37 public class DefaultProxyFactory
: AbstractProxyFactory
, IDeserializationCallback
40 protected ProxyGenerator generator
;
43 /// Constructs a DefaultProxyFactory
45 public DefaultProxyFactory()
51 /// Creates the proxy for the supplied component.
53 /// <param name="kernel">The kernel.</param>
54 /// <param name="target">The target.</param>
55 /// <param name="model">The model.</param>
56 /// <param name="constructorArguments">The constructor arguments.</param>
57 /// <returns>The component proxy.</returns>
58 public override object Create(IKernel kernel
, object target
, ComponentModel model
,
59 params object[] constructorArguments
)
63 IInterceptor
[] interceptors
= ObtainInterceptors(kernel
, model
);
65 ProxyOptions proxyOptions
= ProxyUtil
.ObtainProxyOptions(model
, true);
66 ProxyGenerationOptions proxyGenOptions
= CreateProxyGenerationOptionsFrom(proxyOptions
);
68 CustomizeOptions(proxyGenOptions
, kernel
, model
, constructorArguments
);
70 Type
[] interfaces
= proxyOptions
.AdditionalInterfaces
;
72 if (model
.Service
.IsInterface
)
74 if (proxyOptions
.OmitTarget
)
76 proxy
= generator
.CreateInterfaceProxyWithoutTarget(model
.Service
, interfaces
,
77 proxyGenOptions
, interceptors
);
79 else if (proxyOptions
.AllowChangeTarget
)
81 proxy
= generator
.CreateInterfaceProxyWithTargetInterface(model
.Service
, target
,
82 proxyGenOptions
, interceptors
);
86 if (!proxyOptions
.UseSingleInterfaceProxy
)
88 interfaces
= CollectInterfaces(interfaces
, model
);
91 proxy
= generator
.CreateInterfaceProxyWithTarget(model
.Service
, interfaces
,
92 target
, proxyGenOptions
, interceptors
);
97 proxy
= generator
.CreateClassProxy(model
.Implementation
, interfaces
, proxyGenOptions
,
98 constructorArguments
, interceptors
);
101 CustomizeProxy(proxy
, proxyGenOptions
, kernel
, model
);
106 protected static ProxyGenerationOptions
CreateProxyGenerationOptionsFrom(ProxyOptions proxyOptions
)
108 ProxyGenerationOptions proxyGenOptions
= new ProxyGenerationOptions();
110 if (proxyOptions
.Hook
!= null)
112 proxyGenOptions
.Hook
= new ProxyGenerationHookAdapter(proxyOptions
.Hook
);
115 if (proxyOptions
.UseMarshalByRefAsBaseClass
)
117 proxyGenOptions
.BaseTypeForInterfaceProxy
= typeof(MarshalByRefObject
);
120 return proxyGenOptions
;
123 protected virtual void CustomizeProxy(object proxy
, ProxyGenerationOptions options
,
124 IKernel kernel
, ComponentModel model
)
128 protected virtual void CustomizeOptions(ProxyGenerationOptions options
, IKernel kernel
,
129 ComponentModel model
, object[] arguments
)
134 /// Determines if the component requiries a target instance for proxying.
136 /// <param name="kernel">The kernel.</param>
137 /// <param name="model">The model.</param>
138 /// <returns>true if an instance is required.</returns>
139 public override bool RequiresTargetInstance(IKernel kernel
, ComponentModel model
)
141 ProxyOptions proxyOptions
= ProxyUtil
.ObtainProxyOptions(model
, true);
143 return model
.Service
.IsInterface
&& !proxyOptions
.OmitTarget
;
146 protected Type
[] CollectInterfaces(Type
[] interfaces
, ComponentModel model
)
148 Type
[] modelInterfaces
= model
.Implementation
.FindInterfaces(
149 new TypeFilter(EmptyTypeFilter
), model
.Service
);
151 if (interfaces
== null || interfaces
.Length
== 0)
153 interfaces
= modelInterfaces
;
155 else if (modelInterfaces
!= null && modelInterfaces
.Length
> 0)
157 Type
[] allInterfaces
= new Type
[interfaces
.Length
+ modelInterfaces
.Length
];
158 interfaces
.CopyTo(allInterfaces
, 0);
159 modelInterfaces
.CopyTo(allInterfaces
, interfaces
.Length
);
160 interfaces
= allInterfaces
;
166 private bool EmptyTypeFilter(Type type
, object criteria
)
168 Type mainInterface
= (Type
) criteria
;
170 return !type
.IsAssignableFrom(mainInterface
);
173 #region IDeserializationCallback
175 public void OnDeserialization(object sender
)
184 generator
= new ProxyGenerator();