From e4b2ae46849c77396d3c86ff8c07aeac860361e2 Mon Sep 17 00:00:00 2001 From: cneuwirt Date: Fri, 28 Mar 2008 02:28:49 +0000 Subject: [PATCH] Added DefaultServiceHost which will automatically add a default endpoint for http/https if a corresponding base address is found. This will allow absolutely no configuration or custom dependnency when hosted in IIS. git-svn-id: https://svn.castleproject.org/svn/castle/trunk@4960 73e77b4c-caa6-f847-a29a-24ab75ae54b6 --- .../Global.asax.cs | 6 +- .../Castle.Facilities.WcfIntegration-vs2008.csproj | 1 + .../IWcfServiceModel.cs | 13 +++ .../Service/AbstractServiceHostBuilder.cs | 51 ++++++++++-- .../Service/DefaultServiceHost.cs | 92 ++++++++++++++++++++++ .../Service/DefaultServiceHostBuilder.cs | 43 +--------- 6 files changed, 155 insertions(+), 51 deletions(-) create mode 100644 Facilities/Wcf/Castle.Facilities.WcfIntegration/Service/DefaultServiceHost.cs diff --git a/Facilities/Wcf/Castle.Facilities.WcfIntegration.Demo/Global.asax.cs b/Facilities/Wcf/Castle.Facilities.WcfIntegration.Demo/Global.asax.cs index b1d5f334e..e97946849 100644 --- a/Facilities/Wcf/Castle.Facilities.WcfIntegration.Demo/Global.asax.cs +++ b/Facilities/Wcf/Castle.Facilities.WcfIntegration.Demo/Global.asax.cs @@ -45,11 +45,7 @@ namespace Castle.Facilities.WcfIntegration.Demo .Named("look no config") .ImplementedBy() .CustomDependencies( - Property.ForKey("number").Eq(42), - Property.ForKey("serviceModel").Eq( - new WcfServiceModel().Hosted() - .AddEndpoints(WcfEndpoint.BoundTo(new BasicHttpBinding())) - )) + Property.ForKey("number").Eq(42)) ); WindsorServiceHostFactory.RegisterContainer(container.Kernel); } diff --git a/Facilities/Wcf/Castle.Facilities.WcfIntegration/Castle.Facilities.WcfIntegration-vs2008.csproj b/Facilities/Wcf/Castle.Facilities.WcfIntegration/Castle.Facilities.WcfIntegration-vs2008.csproj index c716ef258..29534a6f0 100644 --- a/Facilities/Wcf/Castle.Facilities.WcfIntegration/Castle.Facilities.WcfIntegration-vs2008.csproj +++ b/Facilities/Wcf/Castle.Facilities.WcfIntegration/Castle.Facilities.WcfIntegration-vs2008.csproj @@ -93,6 +93,7 @@ + diff --git a/Facilities/Wcf/Castle.Facilities.WcfIntegration/IWcfServiceModel.cs b/Facilities/Wcf/Castle.Facilities.WcfIntegration/IWcfServiceModel.cs index 83cf2feed..7d3420296 100644 --- a/Facilities/Wcf/Castle.Facilities.WcfIntegration/IWcfServiceModel.cs +++ b/Facilities/Wcf/Castle.Facilities.WcfIntegration/IWcfServiceModel.cs @@ -14,6 +14,9 @@ namespace Castle.Facilities.WcfIntegration { + using System; + using System.Collections.Generic; + /// /// Contract for all WCF service models. /// @@ -23,5 +26,15 @@ namespace Castle.Facilities.WcfIntegration /// Determines if the service will be hosted. /// bool IsHosted { get; } + + /// + /// Gets the service base addresses. + /// + ICollection BaseAddresses { get; } + + /// + /// Gets the service endpoints. + /// + ICollection Endpoints { get; } } } diff --git a/Facilities/Wcf/Castle.Facilities.WcfIntegration/Service/AbstractServiceHostBuilder.cs b/Facilities/Wcf/Castle.Facilities.WcfIntegration/Service/AbstractServiceHostBuilder.cs index dbbf0815e..6f35a0c54 100644 --- a/Facilities/Wcf/Castle.Facilities.WcfIntegration/Service/AbstractServiceHostBuilder.cs +++ b/Facilities/Wcf/Castle.Facilities.WcfIntegration/Service/AbstractServiceHostBuilder.cs @@ -19,6 +19,7 @@ namespace Castle.Facilities.WcfIntegration using System.ServiceModel.Description; using Castle.Core; using Castle.MicroKernel; + using Castle.MicroKernel.Facilities; public abstract class AbstractServiceHostBuilder : IWcfEndpointVisitor { @@ -140,8 +141,9 @@ namespace Castle.Facilities.WcfIntegration public ServiceHost Build(ComponentModel model, M serviceModel) { this.serviceModel = serviceModel; - ValidateServiceModel(model, serviceModel); + ValidateServiceModelInternal(model, serviceModel); ServiceHost serviceHost = CreateServiceHost(model, serviceModel); + ConfigureServiceHost(serviceHost, serviceModel); OpenServiceHost(serviceHost, serviceModel, model); return serviceHost; } @@ -155,14 +157,23 @@ namespace Castle.Facilities.WcfIntegration public ServiceHost Build(Type serviceType, M serviceModel) { this.serviceModel = serviceModel; - ValidateServiceModel(null, serviceModel); + ValidateServiceModelInternal(null, serviceModel); ServiceHost serviceHost = CreateServiceHost(serviceType, serviceModel); + ConfigureServiceHost(serviceHost, serviceModel); OpenServiceHost(serviceHost, serviceModel, null); return serviceHost; } #endregion + protected virtual void ConfigureServiceHost(ServiceHost serviceHost, M serviceModel) + { + foreach (IWcfEndpoint endpoint in serviceModel.Endpoints) + { + AddServiceEndpoint(serviceHost, endpoint); + } + } + private void OpenServiceHost(ServiceHost serviceHost, M serviceModel, ComponentModel model) { serviceHost.Opening += delegate { OnOpening(serviceHost, model); }; @@ -172,11 +183,41 @@ namespace Castle.Facilities.WcfIntegration serviceHost.Open(); } } - + + private void ValidateServiceModelInternal(ComponentModel model, M serviceModel) + { + ValidateServiceModel(model, serviceModel); + + foreach (IWcfEndpoint endpoint in serviceModel.Endpoints) + { + Type contract = endpoint.Contract; + + if (contract != null) + { + if (!contract.IsInterface) + { + throw new FacilityException("The service endpoint contract " + + contract.FullName + " does not represent an interface."); + } + } + else if (model == null || !model.Service.IsInterface) + { + throw new FacilityException( + "No service endpoint contract can be implied from the component."); + } + else + { + endpoint.Contract = model.Service; + } + } + } + + protected virtual void ValidateServiceModel(ComponentModel model, M serviceModel) + { + } + protected abstract ServiceHost CreateServiceHost(Type serviceType, M serviceModel); protected abstract ServiceHost CreateServiceHost(ComponentModel model, M serviceModel); - - protected abstract void ValidateServiceModel(ComponentModel model, M serviceModel); } } diff --git a/Facilities/Wcf/Castle.Facilities.WcfIntegration/Service/DefaultServiceHost.cs b/Facilities/Wcf/Castle.Facilities.WcfIntegration/Service/DefaultServiceHost.cs new file mode 100644 index 000000000..3f4638066 --- /dev/null +++ b/Facilities/Wcf/Castle.Facilities.WcfIntegration/Service/DefaultServiceHost.cs @@ -0,0 +1,92 @@ +// Copyright 2004-2008 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.Facilities.WcfIntegration +{ + using System; + using System.ServiceModel; + using System.ServiceModel.Description; + using Castle.Core; + + public class DefaultServiceHost : ServiceHost + { + private readonly ComponentModel model; + + public DefaultServiceHost(ComponentModel model, params Uri[] baseAddresses) + : base(model.Implementation, baseAddresses) + { + this.model = model; + } + + public DefaultServiceHost(Type serviceType, params Uri[] baseAddresses) + : base(serviceType, baseAddresses) + { + } + + protected override void OnOpening() + { + base.OnOpening(); + + AddDefaultEndpointIfNoneFound(); + } + + private void AddDefaultEndpointIfNoneFound() + { + if (Description != null && Description.Endpoints.Count == 0) + { + Type contract = ObtainDefaultContract(); + + if (contract != null) + { + foreach (Uri baseAddress in BaseAddresses) + { + BasicHttpBinding binding = null; + + if (baseAddress.Scheme == Uri.UriSchemeHttp) + { + binding = new BasicHttpBinding(); + } + else if (baseAddress.Scheme == Uri.UriSchemeHttps) + { + binding = new BasicHttpBinding(BasicHttpSecurityMode.Transport); + } + + if (binding != null) + { + AddServiceEndpoint(contract, binding, baseAddress); + } + } + } + } + } + + private Type ObtainDefaultContract() + { + if (model != null && model.Service.IsInterface) + { + return model.Service; + } + + if (ImplementedContracts.Count == 1) + { + foreach (ContractDescription contract in ImplementedContracts.Values) + { + return contract.ContractType; + } + } + + return null; + } + } +} diff --git a/Facilities/Wcf/Castle.Facilities.WcfIntegration/Service/DefaultServiceHostBuilder.cs b/Facilities/Wcf/Castle.Facilities.WcfIntegration/Service/DefaultServiceHostBuilder.cs index 999037f62..5f2db4c74 100644 --- a/Facilities/Wcf/Castle.Facilities.WcfIntegration/Service/DefaultServiceHostBuilder.cs +++ b/Facilities/Wcf/Castle.Facilities.WcfIntegration/Service/DefaultServiceHostBuilder.cs @@ -18,7 +18,6 @@ namespace Castle.Facilities.WcfIntegration using System.ServiceModel; using Castle.Core; using Castle.MicroKernel; - using Castle.MicroKernel.Facilities; /// /// The default implementation of . @@ -39,55 +38,17 @@ namespace Castle.Facilities.WcfIntegration protected override ServiceHost CreateServiceHost(ComponentModel model, WcfServiceModel serviceModel) { Uri[] baseAddresss = GetBaseAddressArray(serviceModel); - ServiceHost serviceHost = new ServiceHost(model.Implementation, baseAddresss); - ConfigureServiceHost(serviceHost, serviceModel); - return serviceHost; + return new DefaultServiceHost(model, baseAddresss); } protected override ServiceHost CreateServiceHost(Type serviceType, WcfServiceModel serviceModel) { Uri[] baseAddresss = GetBaseAddressArray(serviceModel); - ServiceHost serviceHost = new ServiceHost(serviceType, baseAddresss); - ConfigureServiceHost(serviceHost, serviceModel); - return serviceHost; - } - - protected override void ValidateServiceModel(ComponentModel model, WcfServiceModel serviceModel) - { - foreach (IWcfEndpoint endpoint in serviceModel.Endpoints) - { - Type contract = endpoint.Contract; - - if (contract != null) - { - if (!contract.IsInterface) - { - throw new FacilityException("The service endpoint contract " + - contract.FullName + " does not represent an interface."); - } - } - else if (model == null || !model.Service.IsInterface) - { - throw new FacilityException( - "No service endpoint contract can be implied from the componnt."); - } - else - { - endpoint.Contract = model.Service; - } - } + return new DefaultServiceHost(serviceType, baseAddresss); } #endregion - protected virtual void ConfigureServiceHost(ServiceHost serviceHost, WcfServiceModel serviceModel) - { - foreach (IWcfEndpoint endpoint in serviceModel.Endpoints) - { - AddServiceEndpoint(serviceHost, endpoint); - } - } - private Uri[] GetBaseAddressArray(WcfServiceModel serviceModel) { Uri[] baseAddresses = new Uri[serviceModel.BaseAddresses.Count]; -- 2.11.4.GIT