Removed untyped contructor from ComponentRegistration and add a protected setter.
[castle.git] / InversionOfControl / Castle.Windsor / Proxy / DefaultProxyFactory.cs
blob989cc455122aac4cfa30b821bc4f6066acb26f20
1 // Copyright 2004-2008 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 namespace Castle.Windsor.Proxy
17 using System;
18 using System.Reflection;
19 using System.Runtime.Serialization;
20 using Castle.Core;
21 using Castle.Core.Interceptor;
22 using Castle.DynamicProxy;
23 using Castle.MicroKernel;
24 using Castle.MicroKernel.Proxy;
26 /// <summary>
27 /// This implementation of <see cref="IProxyFactory"/> relies
28 /// on DynamicProxy to expose proxy capabilies.
29 /// </summary>
30 /// <remarks>
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,
35 /// </remarks>
36 [Serializable]
37 public class DefaultProxyFactory : AbstractProxyFactory, IDeserializationCallback
39 [NonSerialized]
40 protected ProxyGenerator generator;
42 /// <summary>
43 /// Constructs a DefaultProxyFactory
44 /// </summary>
45 public DefaultProxyFactory()
47 Init();
50 /// <summary>
51 /// Creates the proxy for the supplied component.
52 /// </summary>
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)
61 object proxy;
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
81 if (!proxyOptions.UseSingleInterfaceProxy)
83 interfaces = CollectInterfaces(interfaces, model);
86 proxy = generator.CreateInterfaceProxyWithTarget(model.Service, interfaces,
87 target, proxyGenOptions, interceptors);
90 else
92 proxy = generator.CreateClassProxy(model.Implementation, interfaces, proxyGenOptions,
93 constructorArguments, interceptors);
96 CustomizeProxy(proxy, proxyGenOptions, kernel, model);
98 return proxy;
101 protected static ProxyGenerationOptions CreateProxyGenerationOptionsFrom(ProxyOptions proxyOptions)
103 ProxyGenerationOptions proxyGenOptions = new ProxyGenerationOptions();
105 if (proxyOptions.Hook != null)
107 proxyGenOptions.Hook = new ProxyGenerationHookAdapter(proxyOptions.Hook);
110 if (proxyOptions.UseMarshalByRefAsBaseClass)
112 proxyGenOptions.BaseTypeForInterfaceProxy = typeof(MarshalByRefObject);
115 return proxyGenOptions;
118 protected virtual void CustomizeProxy(object proxy, ProxyGenerationOptions options,
119 IKernel kernel, ComponentModel model)
123 protected virtual void CustomizeOptions(ProxyGenerationOptions options, IKernel kernel,
124 ComponentModel model, object[] arguments)
128 /// <summary>
129 /// Determines if the component requiries a target instance for proxying.
130 /// </summary>
131 /// <param name="kernel">The kernel.</param>
132 /// <param name="model">The model.</param>
133 /// <returns>true if an instance is required.</returns>
134 public override bool RequiresTargetInstance(IKernel kernel, ComponentModel model)
136 ProxyOptions proxyOptions = ProxyUtil.ObtainProxyOptions(model, true);
138 return model.Service.IsInterface && !proxyOptions.OmitTarget;
141 protected Type[] CollectInterfaces(Type[] interfaces, ComponentModel model)
143 Type[] modelInterfaces = model.Implementation.FindInterfaces(
144 new TypeFilter(EmptyTypeFilter), model.Service);
146 if (interfaces == null || interfaces.Length == 0)
148 interfaces = modelInterfaces;
150 else if (modelInterfaces != null && modelInterfaces.Length > 0)
152 Type[] allInterfaces = new Type[interfaces.Length + modelInterfaces.Length];
153 interfaces.CopyTo(allInterfaces, 0);
154 modelInterfaces.CopyTo(allInterfaces, interfaces.Length);
155 interfaces = allInterfaces;
158 return interfaces;
161 private bool EmptyTypeFilter(Type type, object criteria)
163 Type mainInterface = (Type) criteria;
165 return !type.IsAssignableFrom(mainInterface);
168 #region IDeserializationCallback
170 public void OnDeserialization(object sender)
172 Init();
175 #endregion
177 private void Init()
179 generator = new ProxyGenerator();