Added container accessor to Castle.Core
[castle.git] / InversionOfControl / Castle.MicroKernel / ModelBuilder / Inspectors / PropertiesDependenciesModelInspector.cs
blobc9a9fd7fded4962d3f1b96a29e0d94cc8bb98f59
1 // Copyright 2004-2007 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.Reflection;
20 using Castle.Core;
21 using Castle.MicroKernel.SubSystems.Conversion;
22 using Castle.Core.Configuration;
24 /// <summary>
25 /// This implementation of <see cref="IContributeComponentModelConstruction"/>
26 /// collects all potential writable puplic properties exposed by the component
27 /// implementation and populates the model with them.
28 /// The Kernel might be able to set some of these properties when the component
29 /// is requested.
30 /// </summary>
31 [Serializable]
32 public class PropertiesDependenciesModelInspector : IContributeComponentModelConstruction
34 [NonSerialized]
35 private IConversionManager converter;
37 /// <summary>
38 /// Initializes a new instance of the <see cref="PropertiesDependenciesModelInspector"/> class.
39 /// </summary>
40 public PropertiesDependenciesModelInspector()
44 /// <summary>
45 /// Adds the properties as optional dependencies of this component.
46 /// </summary>
47 /// <param name="kernel"></param>
48 /// <param name="model"></param>
49 public virtual void ProcessModel(IKernel kernel, ComponentModel model)
51 if (converter == null)
53 converter = (IConversionManager)
54 kernel.GetSubSystem( SubSystemConstants.ConversionManagerKey );
57 InspectProperties(model);
60 protected virtual void InspectProperties(ComponentModel model)
62 if (model.InspectionBehavior == PropertiesInspectionBehavior.Undefined)
64 model.InspectionBehavior = GetInspectionBehaviorFromTheConfiguration(model.Configuration);
67 if (model.InspectionBehavior == PropertiesInspectionBehavior.None)
69 // Nothing to be inspected
70 return;
73 BindingFlags bindingFlags;
75 if (model.InspectionBehavior == PropertiesInspectionBehavior.DeclaredOnly)
77 bindingFlags = BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly;
79 else // if (model.InspectionBehavior == PropertiesInspectionBehavior.All) or Undefined
81 bindingFlags = BindingFlags.Public | BindingFlags.Instance;
84 Type targetType = model.Implementation;
86 PropertyInfo[] properties = targetType.GetProperties(bindingFlags);
88 foreach(PropertyInfo property in properties)
90 if (!property.CanWrite)
92 continue;
95 ParameterInfo[] indexerParams = property.GetIndexParameters();
97 if (indexerParams != null && indexerParams.Length != 0)
99 continue;
102 if (property.IsDefined(typeof(DoNotWireAttribute), true))
104 continue;
107 DependencyModel dependency;
109 Type propertyType = property.PropertyType;
111 // All these dependencies are simple guesses
112 // So we make them optional (the 'true' parameter below)
114 if ( converter.IsSupportedAndPrimitiveType(propertyType) )
116 dependency = new DependencyModel(DependencyType.Parameter, property.Name, propertyType, true);
118 else if (propertyType.IsInterface || propertyType.IsClass)
120 dependency = new DependencyModel(DependencyType.Service, property.Name, propertyType, true);
122 else
124 // What is it?!
125 // Awkward type, probably.
127 continue;
130 model.Properties.Add( new PropertySet(property, dependency) );
134 private PropertiesInspectionBehavior GetInspectionBehaviorFromTheConfiguration(IConfiguration config)
136 if (config == null || config.Attributes["inspectionBehavior"] == null)
138 // return default behavior
139 return PropertiesInspectionBehavior.All;
142 String enumStringVal = config.Attributes["inspectionBehavior"];
146 return (PropertiesInspectionBehavior)
147 Enum.Parse(typeof(PropertiesInspectionBehavior), enumStringVal, true);
149 catch(Exception)
151 String[] enumNames = Enum.GetNames(typeof(PropertiesInspectionBehavior));
153 String message = String.Format("Error on properties inspection. " +
154 "Could not convert the inspectionBehavior attribute value into an expected enum value. " +
155 "Value found is '{0}' while possible values are '{1}'",
156 enumStringVal, String.Join(",", enumNames));
158 throw new KernelException(message);