Applied patch from Jan Limpens 'ReflectionBasedDictionaryAdapter needs to check if...
[castle.git] / Core / Castle.Core / Model / ComponentModel.cs
blob2d4716ce13a248cbc3477d0705f06abd381e3eac
1 // Copyright 2004-2008 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.Core
17 using System;
18 using System.Collections;
19 using System.Collections.Specialized;
20 using System.Diagnostics;
21 using Castle.Core.Configuration;
22 using System.Collections.Generic;
24 #region Enums
26 /// <summary>
27 /// Enumeration used to mark the component's lifestyle.
28 /// </summary>
29 public enum LifestyleType
31 /// <summary>
32 /// No lifestyle specified.
33 /// </summary>
34 Undefined,
35 /// <summary>
36 /// Singleton components are instantiated once, and shared
37 /// between all clients.
38 /// </summary>
39 Singleton,
40 /// <summary>
41 /// Thread components have a unique instance per thread.
42 /// </summary>
43 Thread,
44 /// <summary>
45 /// Transient components are created on demand.
46 /// </summary>
47 Transient,
48 /// <summary>
49 /// Optimization of transient components that keeps
50 /// instance in a pool instead of always creating them.
51 /// </summary>
52 Pooled,
53 /// <summary>
54 /// Any other logic to create/release components.
55 /// </summary>
56 Custom,
57 /// <summary>
58 /// PerWebRequest components are created once per Http Request
59 /// </summary>
60 PerWebRequest
63 /// <summary>
64 ///
65 /// </summary>
66 public enum PropertiesInspectionBehavior
68 Undefined,
69 None,
70 All,
71 DeclaredOnly
74 #endregion
76 /// <summary>
77 /// Represents the collection of information and
78 /// meta information collected about a component.
79 /// </summary>
80 [DebuggerDisplay("{Implementation} / {Service}")]
81 #if !SILVERLIGHT
82 [Serializable]
83 #endif
84 public sealed class ComponentModel : GraphNode
86 public const string SkipRegistration = "skip.registration";
88 #region Fields
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>
93 private String name;
95 /// <summary>Service exposed</summary>
96 private Type service;
98 /// <summary>Implementation for the service</summary>
99 private Type implementation;
101 /// <summary>Extended properties</summary>
102 #if !SILVERLIGHT
103 [NonSerialized]
104 #endif
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>
142 #if !SILVERLIGHT
143 [NonSerialized]
144 #endif
145 private IDictionary customDependencies;
147 private bool requiresGenericArguments;
149 #endregion
151 /// <summary>
152 /// Constructs a ComponentModel
153 /// </summary>
154 public ComponentModel(String name, Type service, Type implementation)
156 this.name = name;
157 this.service = service;
158 this.implementation = implementation;
159 lifestyleType = LifestyleType.Undefined;
160 inspectionBehavior = PropertiesInspectionBehavior.Undefined;
163 /// <summary>
164 /// Sets or returns the component key
165 /// </summary>
166 public String Name
168 get { return name; }
169 set { name = value; }
172 /// <summary>
173 /// Gets or sets the service exposed.
174 /// </summary>
175 /// <value>The service.</value>
176 public Type Service
178 get { return service; }
179 set { service = value; }
182 /// <summary>
183 /// Gets or sets the component implementation.
184 /// </summary>
185 /// <value>The implementation.</value>
186 public Type Implementation
188 get { return implementation; }
189 set { implementation = value; }
192 /// <summary>
193 /// Gets or sets a value indicating whether the component requires generic arguments.
194 /// </summary>
195 /// <value>
196 /// <c>true</c> if generic arguments are required; otherwise, <c>false</c>.
197 /// </value>
198 public bool RequiresGenericArguments
200 get { return requiresGenericArguments; }
201 set { requiresGenericArguments = value; }
204 /// <summary>
205 /// Gets or sets the extended properties.
206 /// </summary>
207 /// <value>The extended properties.</value>
208 public IDictionary ExtendedProperties
212 if (extended == null)
214 lock (this)
216 if (extended == null) extended = new Dictionary<object, object>();
219 return extended;
221 set { extended = value; }
224 /// <summary>
225 /// Gets the constructors candidates.
226 /// </summary>
227 /// <value>The constructors.</value>
228 public ConstructorCandidateCollection Constructors
232 if (constructors == null)
234 lock (this)
236 if (constructors == null) constructors = new ConstructorCandidateCollection();
239 return constructors;
243 /// <summary>
244 /// Gets the properties set.
245 /// </summary>
246 /// <value>The properties.</value>
247 public PropertySetCollection Properties
251 if (properties == null)
253 lock (this)
255 if (properties == null) properties = new PropertySetCollection();
258 return properties;
262 /// <summary>
263 /// Gets or sets the configuration.
264 /// </summary>
265 /// <value>The configuration.</value>
266 public IConfiguration Configuration
268 get { return configuration; }
269 set { configuration = value; }
272 /// <summary>
273 /// Gets the lifecycle steps.
274 /// </summary>
275 /// <value>The lifecycle steps.</value>
276 public LifecycleStepCollection LifecycleSteps
280 if (lifecycleSteps == null)
282 lock (this)
284 if (lifecycleSteps == null) lifecycleSteps = new LifecycleStepCollection();
287 return lifecycleSteps;
291 /// <summary>
292 /// Gets or sets the lifestyle type.
293 /// </summary>
294 /// <value>The type of the lifestyle.</value>
295 public LifestyleType LifestyleType
297 get { return lifestyleType; }
298 set { lifestyleType = value; }
301 /// <summary>
302 /// Gets or sets the strategy for
303 /// inspecting public properties
304 /// on the components
305 /// </summary>
306 public PropertiesInspectionBehavior InspectionBehavior
308 get { return inspectionBehavior; }
309 set { inspectionBehavior = value; }
312 /// <summary>
313 /// Gets or sets the custom lifestyle.
314 /// </summary>
315 /// <value>The custom lifestyle.</value>
316 public Type CustomLifestyle
318 get { return customLifestyle; }
319 set { customLifestyle = value; }
322 /// <summary>
323 /// Gets or sets the custom component activator.
324 /// </summary>
325 /// <value>The custom component activator.</value>
326 public Type CustomComponentActivator
328 get { return customComponentActivator; }
329 set { customComponentActivator = value; }
332 /// <summary>
333 /// Gets the interceptors.
334 /// </summary>
335 /// <value>The interceptors.</value>
336 public InterceptorReferenceCollection Interceptors
340 if (interceptors == null)
342 lock (this)
344 if (interceptors == null) interceptors = new InterceptorReferenceCollection();
347 return interceptors;
351 /// <summary>
352 /// Gets the parameter collection.
353 /// </summary>
354 /// <value>The parameters.</value>
355 public ParameterModelCollection Parameters
359 if (parameters == null)
361 lock (this)
363 if (parameters == null) parameters = new ParameterModelCollection();
366 return parameters;
370 /// <summary>
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
375 /// </summary>
376 public DependencyModelCollection Dependencies
380 if (dependencies == null)
382 lock (this)
384 if (dependencies == null) dependencies = new DependencyModelCollection();
387 return dependencies;
391 /// <summary>
392 /// Gets or sets the custom dependencies.
393 /// </summary>
394 /// <value>The custom dependencies.</value>
395 public IDictionary CustomDependencies
399 lock (this)
401 if (customDependencies == null) customDependencies = new Dictionary<object, object>();
403 return customDependencies;
405 set { customDependencies = value; }