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
.Facilities
.WcfIntegration
18 using System
.Threading
;
19 using System
.Reflection
;
20 using System
.Collections
.Generic
;
21 using System
.ServiceModel
;
23 using Castle
.MicroKernel
;
24 using Castle
.Facilities
.WcfIntegration
.Internal
;
25 using Castle
.Facilities
.WcfIntegration
.Rest
;
27 public class WcfServiceExtension
: IDisposable
29 private readonly IKernel kernel
;
31 #region ServiceHostBuilder Delegate Fields
33 private delegate ServiceHost
CreateServiceHostDelegate(
34 IKernel kernel
, IWcfServiceModel serviceModel
, Type serviceType
, ComponentModel model
);
36 private static readonly MethodInfo createServiceHostMethod
=
37 typeof(WcfServiceExtension
).GetMethod("CreateServiceHostInternal",
38 BindingFlags
.NonPublic
| BindingFlags
.Static
, null,
39 new Type
[] { typeof(IKernel
), typeof(IWcfServiceModel
), typeof(Type
),
40 typeof(ComponentModel
) }, null
43 private static readonly Dictionary
<Type
, CreateServiceHostDelegate
>
44 createServiceHostCache
= new Dictionary
<Type
, CreateServiceHostDelegate
>();
46 private static ReaderWriterLock locker
= new ReaderWriterLock();
50 public WcfServiceExtension(IKernel kernel
)
54 AddDefaultServiceHostBuilders();
55 WindsorServiceHostFactory
.RegisterContainer(kernel
);
57 kernel
.ComponentRegistered
+= Kernel_ComponentRegistered
;
58 kernel
.ComponentUnregistered
+= Kernel_ComponentUnregistered
;
61 WcfServiceExtension AddServiceHostBuilder
<T
, M
>()
62 where T
: IServiceHostBuilder
<M
>
63 where M
: IWcfServiceModel
65 AddServiceHostBuilder
<T
, M
>(true);
69 private void Kernel_ComponentRegistered(string key
, IHandler handler
)
71 ComponentModel model
= handler
.ComponentModel
;
72 IWcfServiceModel serviceModel
= ResolveServiceModel(model
);
74 if (serviceModel
!= null)
76 model
.ExtendedProperties
[WcfConstants
.ServiceModelKey
] = serviceModel
;
78 if (!serviceModel
.IsHosted
)
80 ServiceHost serviceHost
= CreateServiceHost(kernel
, serviceModel
, model
);
81 model
.ExtendedProperties
[WcfConstants
.ServiceHostKey
] = serviceHost
;
86 private void Kernel_ComponentUnregistered(string key
, IHandler handler
)
88 ComponentModel model
= handler
.ComponentModel
;
89 ServiceHost serviceHost
=
90 model
.ExtendedProperties
[WcfConstants
.ServiceHostKey
] as ServiceHost
;
92 if (serviceHost
!= null)
98 private void AddDefaultServiceHostBuilders()
100 AddServiceHostBuilder
<DefaultServiceHostBuilder
, WcfServiceModel
>(false);
102 AddServiceHostBuilder
<RestServiceHostBuilder
, RestServiceModel
>(false);
106 internal void AddServiceHostBuilder
<T
, M
>(bool force
)
107 where T
: IServiceHostBuilder
<M
>
108 where M
: IWcfServiceModel
110 if (force
|| !kernel
.HasComponent(typeof(IServiceHostBuilder
<M
>)))
112 kernel
.AddComponent
<T
>(typeof(IServiceHostBuilder
<M
>));
116 private IWcfServiceModel
ResolveServiceModel(ComponentModel model
)
118 IWcfServiceModel serviceModel
= null;
120 if (model
.Implementation
.IsClass
&& !model
.Implementation
.IsAbstract
)
122 if (!WcfUtils
.FindDependency
<IWcfServiceModel
>(
123 model
.CustomDependencies
, out serviceModel
) &&
124 model
.Configuration
!= null)
126 if ("true" == model
.Configuration
.Attributes
[WcfConstants
.ServiceHostEnabled
])
128 serviceModel
= new WcfServiceModel();
136 #region CreateServiceHost Members
138 public static ServiceHost
CreateServiceHost(IKernel kernel
, IWcfServiceModel serviceModel
,
141 return CreateServiceHost(kernel
, serviceModel
, serviceType
, null);
144 public static ServiceHost
CreateServiceHost(IKernel kernel
, IWcfServiceModel serviceModel
,
145 ComponentModel model
)
147 return CreateServiceHost(kernel
, serviceModel
, null, model
);
150 private static ServiceHost
CreateServiceHost(IKernel kernel
, IWcfServiceModel serviceModel
,
151 Type serviceType
, ComponentModel model
)
153 CreateServiceHostDelegate createServiceHost
;
157 locker
.AcquireReaderLock(Timeout
.Infinite
);
159 Type serviceModelType
= serviceModel
.GetType();
161 if (!createServiceHostCache
.TryGetValue(serviceModelType
, out createServiceHost
))
163 locker
.UpgradeToWriterLock(Timeout
.Infinite
);
165 createServiceHost
= (CreateServiceHostDelegate
)
166 Delegate
.CreateDelegate(typeof(CreateServiceHostDelegate
),
167 createServiceHostMethod
.MakeGenericMethod(serviceModelType
));
168 createServiceHostCache
.Add(serviceModelType
, createServiceHost
);
173 locker
.ReleaseLock();
176 return createServiceHost(kernel
, serviceModel
, serviceType
, model
);
179 internal static ServiceHost CreateServiceHostInternal
<M
>(IKernel kernel
, IWcfServiceModel serviceModel
,
180 Type serviceType
, ComponentModel model
)
181 where M
: IWcfServiceModel
183 IServiceHostBuilder
<M
> serviceHostBuilder
= kernel
.Resolve
<IServiceHostBuilder
<M
>>();
186 return serviceHostBuilder
.Build(model
, (M
)serviceModel
);
188 return serviceHostBuilder
.Build(serviceType
, (M
)serviceModel
);
193 #region IDisposable Members
195 public void Dispose()