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
;
26 /// Enumeration used to mark the component's lifestyle.
28 public enum LifestyleType
31 /// No lifestyle specified.
35 /// Singleton components are instantiated once, and shared
36 /// between all clients.
40 /// Thread components have a unique instance per thread.
44 /// Transient components are created on demand.
48 /// Optimization of transient components that keeps
49 /// instance in a pool instead of always creating them.
53 /// Any other logic to create/release components.
57 /// PerWebRequest components are created once per Http Request
65 public enum PropertiesInspectionBehavior
76 /// Represents the collection of information and
77 /// meta information collected about a component.
79 [DebuggerDisplay("{Implementation} / {Service}")]
81 public sealed class ComponentModel
: GraphNode
83 public const string SkipRegistration
= "skip.registration";
86 // Note the use of volatile for fields used in the double checked lock pattern.
87 // This is necessary to ensure the pattern works correctly.
89 /// <summary>Name (key) of the component</summary>
92 /// <summary>Service exposed</summary>
95 /// <summary>Implementation for the service</summary>
96 private Type implementation
;
98 /// <summary>Extended properties</summary>
99 [NonSerialized
] private volatile IDictionary extended
;
101 /// <summary>Lifestyle for the component</summary>
102 private LifestyleType lifestyleType
;
104 private PropertiesInspectionBehavior inspectionBehavior
;
106 /// <summary>Custom lifestyle, if any</summary>
107 private Type customLifestyle
;
109 /// <summary>Custom activator, if any</summary>
110 private Type customComponentActivator
;
112 /// <summary>Dependencies the kernel must resolve</summary>
113 private volatile DependencyModelCollection dependencies
;
115 /// <summary>All available constructors</summary>
116 private volatile ConstructorCandidateCollection constructors
;
118 /// <summary>All potential properties that can be setted by the kernel</summary>
119 private volatile PropertySetCollection properties
;
121 //private MethodMetaModelCollection methodMetaModels;
123 /// <summary>Steps of lifecycle</summary>
124 private volatile LifecycleStepCollection lifecycleSteps
;
126 /// <summary>External parameters</summary>
127 private volatile ParameterModelCollection parameters
;
129 /// <summary>Configuration node associated</summary>
130 private IConfiguration configuration
;
132 /// <summary>Interceptors associated</summary>
133 private volatile InterceptorReferenceCollection interceptors
;
135 /// <summary>/// Custom dependencies/// </summary>
136 [NonSerialized
] private IDictionary customDependencies
;
138 private bool requiresGenericArguments
;
143 /// Constructs a ComponentModel
145 public ComponentModel(String name
, Type service
, Type implementation
)
148 this.service
= service
;
149 this.implementation
= implementation
;
150 lifestyleType
= LifestyleType
.Undefined
;
151 inspectionBehavior
= PropertiesInspectionBehavior
.Undefined
;
155 /// Sets or returns the component key
160 set { name = value; }
164 /// Gets or sets the service exposed.
166 /// <value>The service.</value>
169 get { return service; }
170 set { service = value; }
174 /// Gets or sets the component implementation.
176 /// <value>The implementation.</value>
177 public Type Implementation
179 get { return implementation; }
180 set { implementation = value; }
184 /// Gets or sets a value indicating whether the component requires generic arguments.
187 /// <c>true</c> if generic arguments are required; otherwise, <c>false</c>.
189 public bool RequiresGenericArguments
191 get { return requiresGenericArguments; }
192 set { requiresGenericArguments = value; }
196 /// Gets or sets the extended properties.
198 /// <value>The extended properties.</value>
199 public IDictionary ExtendedProperties
203 if (extended
== null)
207 if (extended
== null) extended
= new HybridDictionary();
212 set { extended = value; }
216 /// Gets the constructors candidates.
218 /// <value>The constructors.</value>
219 public ConstructorCandidateCollection Constructors
223 if (constructors
== null)
227 if (constructors
== null) constructors
= new ConstructorCandidateCollection();
235 /// Gets the properties set.
237 /// <value>The properties.</value>
238 public PropertySetCollection Properties
242 if (properties
== null)
246 if (properties
== null) properties
= new PropertySetCollection();
254 /// Gets or sets the configuration.
256 /// <value>The configuration.</value>
257 public IConfiguration Configuration
259 get { return configuration; }
260 set { configuration = value; }
264 /// Gets the lifecycle steps.
266 /// <value>The lifecycle steps.</value>
267 public LifecycleStepCollection LifecycleSteps
271 if (lifecycleSteps
== null)
275 if (lifecycleSteps
== null) lifecycleSteps
= new LifecycleStepCollection();
278 return lifecycleSteps
;
283 /// Gets or sets the lifestyle type.
285 /// <value>The type of the lifestyle.</value>
286 public LifestyleType LifestyleType
288 get { return lifestyleType; }
289 set { lifestyleType = value; }
293 /// Gets or sets the strategy for
294 /// inspecting public properties
295 /// on the components
297 public PropertiesInspectionBehavior InspectionBehavior
299 get { return inspectionBehavior; }
300 set { inspectionBehavior = value; }
304 /// Gets or sets the custom lifestyle.
306 /// <value>The custom lifestyle.</value>
307 public Type CustomLifestyle
309 get { return customLifestyle; }
310 set { customLifestyle = value; }
314 /// Gets or sets the custom component activator.
316 /// <value>The custom component activator.</value>
317 public Type CustomComponentActivator
319 get { return customComponentActivator; }
320 set { customComponentActivator = value; }
324 /// Gets the interceptors.
326 /// <value>The interceptors.</value>
327 public InterceptorReferenceCollection Interceptors
331 if (interceptors
== null)
335 if (interceptors
== null) interceptors
= new InterceptorReferenceCollection();
343 /// Gets the parameter collection.
345 /// <value>The parameters.</value>
346 public ParameterModelCollection Parameters
350 if (parameters
== null)
354 if (parameters
== null) parameters
= new ParameterModelCollection();
362 /// Dependencies are kept within constructors and
363 /// properties. Others dependencies must be
364 /// registered here, so the kernel (as a matter
365 /// of fact the handler) can check them
367 public DependencyModelCollection Dependencies
371 if (dependencies
== null)
375 if (dependencies
== null) dependencies
= new DependencyModelCollection();
383 /// Gets or sets the custom dependencies.
385 /// <value>The custom dependencies.</value>
386 public IDictionary CustomDependencies
392 if (customDependencies
== null) customDependencies
= new HybridDictionary();
394 return customDependencies
;
396 set { customDependencies = value; }