Fixing the build, will not add an interceptor twice when it was already added by...
[castle.git] / InversionOfControl / Castle.MicroKernel / Handlers / DefaultGenericHandler.cs
blobad30c51cd44fa85e888487477a4067e758540b1e
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.MicroKernel.Handlers
17 using System;
18 using System.Collections.Generic;
19 using Core;
21 /// <summary>
22 /// Summary description for DefaultGenericHandler.
23 /// </summary>
24 /// <remarks>
25 /// TODO: Consider refactoring AbstractHandler moving lifestylemanager
26 /// creation to DefaultHandler
27 /// </remarks>
28 [Serializable]
29 public class DefaultGenericHandler : AbstractHandler
31 private readonly IDictionary<Type, IHandler> type2SubHandler;
33 /// <summary>
34 /// Initializes a new instance of the <see cref="DefaultGenericHandler"/> class.
35 /// </summary>
36 /// <param name="model"></param>
37 public DefaultGenericHandler(ComponentModel model)
38 : base(model)
40 type2SubHandler = new Dictionary<Type, IHandler>();
43 public override object Resolve(CreationContext context)
45 Type implType = ComponentModel.Implementation.MakeGenericType(context.GenericArguments);
47 IHandler handler = GetSubHandler(context, implType);
49 //so the generic version wouldn't be considered as well
50 using (context.ResolvingHandler(this))
52 return handler.Resolve(context);
56 public override void Release(object instance)
58 IHandler handler = GetSubHandler(CreationContext.Empty, instance.GetType());
60 handler.Release(instance);
63 protected IHandler GetSubHandler(CreationContext context, Type genericType)
65 lock (type2SubHandler)
67 IHandler handler;
69 if (type2SubHandler.ContainsKey(genericType))
71 handler = type2SubHandler[genericType];
73 else
75 Type service = ComponentModel.Service.MakeGenericType(context.GenericArguments);
77 ComponentModel newModel = Kernel.ComponentModelBuilder.BuildModel(
78 ComponentModel.Name, service, genericType, null);
80 newModel.ExtendedProperties[ComponentModel.SkipRegistration] = true;
82 CloneParentProperties(newModel);
84 Kernel.AddCustomComponent(newModel);
86 handler = Kernel.HandlerFactory.Create(newModel);
88 type2SubHandler[genericType] = handler;
91 return handler;
95 /// <summary>
96 /// Clone some of the parent componentmodel properties to the generic subhandler.
97 /// </summary>
98 /// <remarks>
99 /// The following properties are copied:
100 /// <list type="bullet">
101 /// <item>
102 /// <description>The <see cref="LifestyleType"/></description>
103 /// </item>
104 /// <item>
105 /// <description>The <see cref="ComponentModel.Interceptors"/></description>
106 /// </item>
107 /// </list>
108 /// </remarks>
109 /// <param name="newModel">the subhandler</param>
110 private void CloneParentProperties(ComponentModel newModel)
112 // Inherits from LifeStyle's context.
113 newModel.LifestyleType = ComponentModel.LifestyleType;
115 // Inherit the parent handler interceptors.
116 foreach (InterceptorReference interceptor in ComponentModel.Interceptors)
118 // we need to check that we are not adding the inteceptor again, if it was added
119 // by a facility already
120 newModel.Interceptors.AddIfNotInCollection(interceptor);