Adding #if DOTNET35 for REST
[castle.git] / Facilities / Wcf / Castle.Facilities.WcfIntegration / Service / WcfServiceExtension.cs
blobb1caf2efd75ed4eeb81c41991143beb937d32a7b
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.Facilities.WcfIntegration
17 using System;
18 using System.Threading;
19 using System.Reflection;
20 using System.Collections.Generic;
21 using System.ServiceModel;
22 using Castle.Core;
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();
48 #endregion
50 public WcfServiceExtension(IKernel kernel)
52 this.kernel = 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);
66 return this;
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)
94 serviceHost.Close();
98 private void AddDefaultServiceHostBuilders()
100 AddServiceHostBuilder<DefaultServiceHostBuilder, WcfServiceModel>(false);
101 #if DOTNET35
102 AddServiceHostBuilder<RestServiceHostBuilder, RestServiceModel>(false);
103 #endif
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();
133 return serviceModel;
136 #region CreateServiceHost Members
138 public static ServiceHost CreateServiceHost(IKernel kernel, IWcfServiceModel serviceModel,
139 Type serviceType)
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);
171 finally
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>>();
184 if (model != null)
186 return serviceHostBuilder.Build(model, (M)serviceModel);
188 return serviceHostBuilder.Build(serviceType, (M)serviceModel);
191 #endregion
193 #region IDisposable Members
195 public void Dispose()
199 #endregion