Added RedirectUsingNamedRoute
[castle.git] / InversionOfControl / Castle.MicroKernel / ModelBuilder / Inspectors / ComponentProxyInspector.cs
blob36b35c9db84304b0fe976df2f7dd16169c446b0e
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.MicroKernel.ModelBuilder.Inspectors
17 using System;
18 using System.Configuration;
19 using Castle.Core;
20 using Castle.MicroKernel.Proxy;
21 using Castle.MicroKernel.SubSystems.Conversion;
23 /// <summary>
24 /// Inspects the component configuration and type looking for information
25 /// that can influence the generation of a proxy for that component.
26 /// <para>
27 /// We specifically look for <c>useSingleInterfaceProxy</c> and <c>marshalByRefProxy</c>
28 /// on the component configuration or the <see cref="ComponentProxyBehaviorAttribute"/>
29 /// attribute.
30 /// </para>
31 /// </summary>
32 [Serializable]
33 public class ComponentProxyInspector : IContributeComponentModelConstruction
35 /// <summary>
36 /// Seaches for proxy behavior in the configuration and, if unsuccessful
37 /// look for the <see cref="ComponentProxyBehaviorAttribute"/> attribute in
38 /// the implementation type.
39 /// </summary>
40 public virtual void ProcessModel(IKernel kernel, ComponentModel model)
42 ReadProxyBehavior(kernel, model);
45 /// <summary>
46 /// Reads the proxy behavior associated with the
47 /// component configuration/type and applies it to the model.
48 /// </summary>
49 /// <exception cref="System.Configuration.ConfigurationException">
50 /// If the conversion fails
51 /// </exception>
52 /// <param name="kernel"></param>
53 /// <param name="model"></param>
54 protected virtual void ReadProxyBehavior(IKernel kernel, ComponentModel model)
56 ComponentProxyBehaviorAttribute proxyBehaviorAtt = GetProxyBehaviorFromType(model.Implementation);
58 if (proxyBehaviorAtt == null)
60 proxyBehaviorAtt = new ComponentProxyBehaviorAttribute();
63 string useSingleInterfaceProxyAttrib = model.Configuration != null ? model.Configuration.Attributes["useSingleInterfaceProxy"] : null;
64 string marshalByRefProxyAttrib = model.Configuration != null ? model.Configuration.Attributes["marshalByRefProxy"] : null;
66 ITypeConverter converter = (ITypeConverter)kernel.GetSubSystem(SubSystemConstants.ConversionManagerKey);
68 if (useSingleInterfaceProxyAttrib != null)
70 try
72 proxyBehaviorAtt.UseSingleInterfaceProxy = (bool)
73 converter.PerformConversion(useSingleInterfaceProxyAttrib, typeof(bool));
75 catch(ConverterException ex)
77 throw new ConfigurationErrorsException("Could not convert attribute " +
78 "'useSingleInterfaceProxy' to bool. Value is " + useSingleInterfaceProxyAttrib, ex);
82 if (marshalByRefProxyAttrib != null)
84 try
86 proxyBehaviorAtt.UseMarshalByRefProxy = (bool)
87 converter.PerformConversion(marshalByRefProxyAttrib, typeof(bool));
89 catch(ConverterException ex)
91 throw new ConfigurationErrorsException("Could not convert attribute " +
92 "'marshalByRefProxy' to bool. Value is " + marshalByRefProxyAttrib, ex);
96 ApplyProxyBehavior(proxyBehaviorAtt, model);
99 /// <summary>
100 /// Returns a <see cref="ComponentProxyBehaviorAttribute"/> instance if the type
101 /// uses the attribute. Otherwise returns null.
102 /// </summary>
103 /// <param name="implementation"></param>
104 protected virtual ComponentProxyBehaviorAttribute GetProxyBehaviorFromType(Type implementation)
106 object[] attributes = implementation.GetCustomAttributes(
107 typeof(ComponentProxyBehaviorAttribute), true);
109 if (attributes.Length != 0)
111 return (ComponentProxyBehaviorAttribute) attributes[0];
114 return null;
117 private static void ApplyProxyBehavior(ComponentProxyBehaviorAttribute behavior, ComponentModel model)
119 if (behavior.UseSingleInterfaceProxy || behavior.UseMarshalByRefProxy)
121 EnsureComponentRegisteredWithInterface(model);
124 ProxyOptions options = ProxyUtil.ObtainProxyOptions(model, true);
126 options.UseSingleInterfaceProxy = behavior.UseSingleInterfaceProxy;
127 options.UseMarshalByRefAsBaseClass = behavior.UseMarshalByRefProxy;
128 options.AddAdditionalInterfaces(behavior.AdditionalInterfaces);
131 private static void EnsureComponentRegisteredWithInterface(ComponentModel model)
133 if (!model.Service.IsInterface)
135 String message = String.Format("The class {0} requested a single interface proxy, " +
136 "however the service {1} does not represent an interface",
137 model.Implementation.FullName, model.Service.FullName);
139 throw new ComponentRegistrationException(message);