1 // Copyright 2004-2007 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
.MicroKernel
.ModelBuilder
.Inspectors
18 using System
.Reflection
;
21 using Castle
.MicroKernel
.SubSystems
.Conversion
;
22 using Castle
.Core
.Configuration
;
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
32 public class PropertiesDependenciesModelInspector
: IContributeComponentModelConstruction
35 private IConversionManager converter
;
38 /// Initializes a new instance of the <see cref="PropertiesDependenciesModelInspector"/> class.
40 public PropertiesDependenciesModelInspector()
45 /// Adds the properties as optional dependencies of this component.
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
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
)
95 ParameterInfo
[] indexerParams
= property
.GetIndexParameters();
97 if (indexerParams
!= null && indexerParams
.Length
!= 0)
102 if (property
.IsDefined(typeof(DoNotWireAttribute
), true))
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);
125 // Awkward type, probably.
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);
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
);