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
.Handlers
18 using System
.Collections
.Generic
;
22 /// Summary description for DefaultGenericHandler.
25 /// TODO: Consider refactoring AbstractHandler moving lifestylemanager
26 /// creation to DefaultHandler
29 public class DefaultGenericHandler
: AbstractHandler
31 private readonly IDictionary
<Type
, IHandler
> type2SubHandler
;
34 /// Initializes a new instance of the <see cref="DefaultGenericHandler"/> class.
36 /// <param name="model"></param>
37 public DefaultGenericHandler(ComponentModel 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
)
69 if (type2SubHandler
.ContainsKey(genericType
))
71 handler
= type2SubHandler
[genericType
];
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
;
96 /// Clone some of the parent componentmodel properties to the generic subhandler.
99 /// The following properties are copied:
100 /// <list type="bullet">
102 /// <description>The <see cref="LifestyleType"/></description>
105 /// <description>The <see cref="ComponentModel.Interceptors"/></description>
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
);