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
.MicroKernel
.ModelBuilder
.Inspectors
18 using System
.Reflection
;
20 using Castle
.MicroKernel
.SubSystems
.Conversion
;
21 using Castle
.MicroKernel
.Util
;
24 /// This implementation of <see cref="IContributeComponentModelConstruction"/>
25 /// collects all available constructors and populates them in the model
26 /// as candidates. The Kernel will pick up one of the candidates
27 /// according to a heuristic.
30 public class ConstructorDependenciesModelInspector
: IContributeComponentModelConstruction
33 private IConversionManager converter
;
35 public ConstructorDependenciesModelInspector()
39 public virtual void ProcessModel(IKernel kernel
, ComponentModel model
)
41 if (converter
== null)
43 converter
= (IConversionManager
)
44 kernel
.GetSubSystem(SubSystemConstants
.ConversionManagerKey
);
47 Type targetType
= model
.Implementation
;
49 ConstructorInfo
[] constructors
=
50 targetType
.GetConstructors(BindingFlags
.Public
| BindingFlags
.Instance
);
52 foreach(ConstructorInfo constructor
in constructors
)
54 // We register each public constructor
55 // and let the ComponentFactory select an
56 // eligible amongst the candidates later
57 model
.Constructors
.Add(CreateConstructorCandidate(model
, constructor
));
61 protected virtual ConstructorCandidate
CreateConstructorCandidate(ComponentModel model
, ConstructorInfo constructor
)
63 ParameterInfo
[] parameters
= constructor
.GetParameters();
65 DependencyModel
[] dependencies
= new DependencyModel
[parameters
.Length
];
67 for(int i
= 0; i
< parameters
.Length
; i
++)
69 ParameterInfo parameter
= parameters
[i
];
71 Type paramType
= parameter
.ParameterType
;
73 // This approach is somewhat problematic. We should use
74 // another strategy to differentiate types and classify dependencies
75 if (converter
.IsSupportedAndPrimitiveType(paramType
))
77 dependencies
[i
] = new DependencyModel(
78 DependencyType
.Parameter
, parameter
.Name
, paramType
, false);
82 ParameterModel modelParameter
= model
.Parameters
[parameter
.Name
];
84 if (modelParameter
!= null && ReferenceExpressionUtil
.IsReference(modelParameter
.Value
))
86 String key
= ReferenceExpressionUtil
.ExtractComponentKey(modelParameter
.Value
);
88 dependencies
[i
] = new DependencyModel(
89 DependencyType
.ServiceOverride
, key
, paramType
, false);
93 dependencies
[i
] = new DependencyModel(
94 DependencyType
.Service
, parameter
.Name
, paramType
, false);
99 return new ConstructorCandidate(constructor
, dependencies
);