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.
18 using System
.Collections
;
19 using System
.Collections
.Specialized
;
20 using System
.Diagnostics
;
21 using Castle
.Core
.Configuration
;
22 using System
.Collections
.Generic
;
27 /// Enumeration used to mark the component's lifestyle.
29 public enum LifestyleType
32 /// No lifestyle specified.
36 /// Singleton components are instantiated once, and shared
37 /// between all clients.
41 /// Thread components have a unique instance per thread.
45 /// Transient components are created on demand.
49 /// Optimization of transient components that keeps
50 /// instance in a pool instead of always creating them.
54 /// Any other logic to create/release components.
58 /// PerWebRequest components are created once per Http Request
66 public enum PropertiesInspectionBehavior
77 /// Represents the collection of information and
78 /// meta information collected about a component.
80 [DebuggerDisplay("{Implementation} / {Service}")]
84 public sealed class ComponentModel
: GraphNode
86 public const string SkipRegistration
= "skip.registration";
89 // Note the use of volatile for fields used in the double checked lock pattern.
90 // This is necessary to ensure the pattern works correctly.
92 /// <summary>Name (key) of the component</summary>
95 /// <summary>Service exposed</summary>
98 /// <summary>Implementation for the service</summary>
99 private Type implementation
;
101 /// <summary>Extended properties</summary>
105 private volatile IDictionary extended
;
107 /// <summary>Lifestyle for the component</summary>
108 private LifestyleType lifestyleType
;
110 private PropertiesInspectionBehavior inspectionBehavior
;
112 /// <summary>Custom lifestyle, if any</summary>
113 private Type customLifestyle
;
115 /// <summary>Custom activator, if any</summary>
116 private Type customComponentActivator
;
118 /// <summary>Dependencies the kernel must resolve</summary>
119 private volatile DependencyModelCollection dependencies
;
121 /// <summary>All available constructors</summary>
122 private volatile ConstructorCandidateCollection constructors
;
124 /// <summary>All potential properties that can be setted by the kernel</summary>
125 private volatile PropertySetCollection properties
;
127 //private MethodMetaModelCollection methodMetaModels;
129 /// <summary>Steps of lifecycle</summary>
130 private volatile LifecycleStepCollection lifecycleSteps
;
132 /// <summary>External parameters</summary>
133 private volatile ParameterModelCollection parameters
;
135 /// <summary>Configuration node associated</summary>
136 private IConfiguration configuration
;
138 /// <summary>Interceptors associated</summary>
139 private volatile InterceptorReferenceCollection interceptors
;
141 /// <summary>/// Custom dependencies/// </summary>
145 private IDictionary customDependencies
;
147 private bool requiresGenericArguments
;
152 /// Constructs a ComponentModel
154 public ComponentModel(String name
, Type service
, Type implementation
)
157 this.service
= service
;
158 this.implementation
= implementation
;
159 lifestyleType
= LifestyleType
.Undefined
;
160 inspectionBehavior
= PropertiesInspectionBehavior
.Undefined
;
164 /// Sets or returns the component key
169 set { name = value; }
173 /// Gets or sets the service exposed.
175 /// <value>The service.</value>
178 get { return service; }
179 set { service = value; }
183 /// Gets or sets the component implementation.
185 /// <value>The implementation.</value>
186 public Type Implementation
188 get { return implementation; }
189 set { implementation = value; }
193 /// Gets or sets a value indicating whether the component requires generic arguments.
196 /// <c>true</c> if generic arguments are required; otherwise, <c>false</c>.
198 public bool RequiresGenericArguments
200 get { return requiresGenericArguments; }
201 set { requiresGenericArguments = value; }
205 /// Gets or sets the extended properties.
207 /// <value>The extended properties.</value>
208 public IDictionary ExtendedProperties
212 if (extended
== null)
216 if (extended
== null) extended
= new Dictionary
<object, object>();
221 set { extended = value; }
225 /// Gets the constructors candidates.
227 /// <value>The constructors.</value>
228 public ConstructorCandidateCollection Constructors
232 if (constructors
== null)
236 if (constructors
== null) constructors
= new ConstructorCandidateCollection();
244 /// Gets the properties set.
246 /// <value>The properties.</value>
247 public PropertySetCollection Properties
251 if (properties
== null)
255 if (properties
== null) properties
= new PropertySetCollection();
263 /// Gets or sets the configuration.
265 /// <value>The configuration.</value>
266 public IConfiguration Configuration
268 get { return configuration; }
269 set { configuration = value; }
273 /// Gets the lifecycle steps.
275 /// <value>The lifecycle steps.</value>
276 public LifecycleStepCollection LifecycleSteps
280 if (lifecycleSteps
== null)
284 if (lifecycleSteps
== null) lifecycleSteps
= new LifecycleStepCollection();
287 return lifecycleSteps
;
292 /// Gets or sets the lifestyle type.
294 /// <value>The type of the lifestyle.</value>
295 public LifestyleType LifestyleType
297 get { return lifestyleType; }
298 set { lifestyleType = value; }
302 /// Gets or sets the strategy for
303 /// inspecting public properties
304 /// on the components
306 public PropertiesInspectionBehavior InspectionBehavior
308 get { return inspectionBehavior; }
309 set { inspectionBehavior = value; }
313 /// Gets or sets the custom lifestyle.
315 /// <value>The custom lifestyle.</value>
316 public Type CustomLifestyle
318 get { return customLifestyle; }
319 set { customLifestyle = value; }
323 /// Gets or sets the custom component activator.
325 /// <value>The custom component activator.</value>
326 public Type CustomComponentActivator
328 get { return customComponentActivator; }
329 set { customComponentActivator = value; }
333 /// Gets the interceptors.
335 /// <value>The interceptors.</value>
336 public InterceptorReferenceCollection Interceptors
340 if (interceptors
== null)
344 if (interceptors
== null) interceptors
= new InterceptorReferenceCollection();
352 /// Gets the parameter collection.
354 /// <value>The parameters.</value>
355 public ParameterModelCollection Parameters
359 if (parameters
== null)
363 if (parameters
== null) parameters
= new ParameterModelCollection();
371 /// Dependencies are kept within constructors and
372 /// properties. Others dependencies must be
373 /// registered here, so the kernel (as a matter
374 /// of fact the handler) can check them
376 public DependencyModelCollection Dependencies
380 if (dependencies
== null)
384 if (dependencies
== null) dependencies
= new DependencyModelCollection();
392 /// Gets or sets the custom dependencies.
394 /// <value>The custom dependencies.</value>
395 public IDictionary CustomDependencies
401 if (customDependencies
== null) customDependencies
= new Dictionary
<object, object>();
403 return customDependencies
;
405 set { customDependencies = value; }