//******************************************************************************************************// SelfHostingService.cs - Gbtc//// Copyright © 2012, Grid Protection Alliance. All Rights Reserved.//// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See// the NOTICE file distributed with this work for additional information regarding copyright ownership.// The GPA licenses this file to you under the MIT License (MIT), 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.opensource.org/licenses/MIT//// Unless agreed to in writing, the subject software distributed under the License is distributed on an// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the// License for the specific language governing permissions and limitations.//// Code Modification History:// ----------------------------------------------------------------------------------------------------// 08/27/2009 - Pinal C. Patel// Generated original version of source code.// 09/02/2009 - Pinal C. Patel// Modified configuration of the default WebHttpBinding to enable receiving of large payloads.// 09/15/2009 - Stephen C. Wills// Added new header and license agreement.// 11/27/2009 - Pinal C. Patel// Fixed issue in the initialization of service contract name.// 03/30/2010 - Pinal C. Patel// Updated CanRead and CanWrite to not include Enabled in its evaluation.// 05/28/2010 - Pinal C. Patel// Added an endpoint for web service help.// 06/21/2010 - Pinal C. Patel// Added Singleton property for added control over the hosting process.// 10/08/2010 - Pinal C. Patel// Removed REST web service help endpoint since a similar feature is now part of WCF 4.0.// 10/14/2010 - Pinal C. Patel// Made changes for hosting flexibility and enabling security:// Deleted DataFlow since access restriction can now be imposed by enabling security.// Added SecurityPolicy and PublishMetadata.// Renamed ServiceUri to Endpoints and ServiceContract to Contract.// 10/26/2010 - Pinal C. Patel// Modified the implementation of ISupportLifecycle.Enabled property.// 10/29/2010 - Pinal C. Patel// Modified CreateServiceBinding() to explicitly disable security on created binding if specified.// 11/19/2010 - Pinal C. Patel// Changed to inherit from Adapter to take advantage of app domain isolation through AdapterLoader.// 12/09/2010 - Pinal C. Patel// Modified GetUnusedPort() to use GSF.Security.Cryptography.Random instead of System.Random to// unsure unique numbers.// 11/29/2011 - Pinal C. Patel// Modified InitializeServiceHost() to not use a random port number for the service host address// so that setting up security on the address is possible.// 08/02/2012 - J. Ritchie Carroll// Added cross-domain access support for Silverlight and Flash application using self hosted// web services (enables access to clientaccesspolicy.xml and crossdomain.xml).// 12/20/2012 - Starlynn Danyelle Gilliam// Modified Header.// 12/11/2013 - Pinal C. Patel// Added WindowsAuthentication property to allow Windows Authentication to be enabled explicitly// even if SecurityPolicy is not configured to allow for more flexibility.////****************************************************************************************************** using System;using System.Collections.Generic;using System.IdentityModel.Policy;using System.IO;using System.Linq;using System.Net;using System.Net.NetworkInformation;using System.ServiceModel;using System.ServiceModel.Channels;using System.ServiceModel.Description;using System.ServiceModel.Web;using System.Text;using System.Text.RegularExpressions;using GSF.Adapters;using GSF.Configuration;using Random = GSF.Security.Cryptography.Random; namespace GSF.ServiceModel{ /// <summary> /// A base class for web service that can send and receive data over REST (Representational State Transfer) interface. /// </summary> /// <example> /// This example shows how to create a WCF service derived from <see cref="SelfHostingService"/> that is capable of hosting itself: /// <code> /// using System.ServiceModel; /// using System.ServiceModel.Web; /// using GSF.ServiceModel; /// /// namespace Services /// { /// [ServiceContract()] /// public interface IService : ISelfHostingService /// { /// [OperationContract(), WebGet(UriTemplate = "/hello/{name}")] /// string Hello(string name); /// } /// /// public class Service : SelfHostingService, IService /// { /// public string Hello(string name) /// { /// return string.Format("Hello {0}!", name); /// } /// } /// } /// </code> /// This example shows how to activate a WCF service derived from <see cref="SelfHostingService"/> that is capable of hosting itself: /// <code> /// using System; /// using System.ServiceModel; /// using System.ServiceModel.Description; /// using System.ServiceModel.Web; /// using Services; /// using GSF.ServiceModel; /// /// class Program /// { /// static void Main(string[] args) /// { /// // Initialize web service. /// Service service = new Service(); /// service.PublishMetadata = true; /// service.Endpoints = "http.soap11://localhost:4500/soap; http.rest://localhost:4500/rest"; /// service.Initialize(); /// /// // Show web service status. /// if (service.ServiceHost.State == CommunicationState.Opened) /// { /// Console.WriteLine("\r\n{0} is running:", service.GetType().Name); /// foreach (ServiceEndpoint endpoint in service.ServiceHost.Description.Endpoints) /// { /// Console.WriteLine("- {0} ({1})", endpoint.Address, endpoint.Binding.GetType().Name); /// } /// Console.Write("\r\nPress Enter key to stop..."); /// } /// else /// { /// Console.WriteLine("\r\n{0} could not be started", service.GetType().Name); /// } /// /// // Shutdown. /// Console.ReadLine(); /// service.Dispose(); /// } /// } /// </code> /// This example shows how to host a WCF service derived from <see cref="SelfHostingService"/> inside ASP.NET: /// <code> /// <![CDATA[ /// <?xml version="1.0"?> /// <configuration> /// <system.serviceModel> /// <services> /// <service name="Services.Service"> /// <endpoint address="soap" contract="Services.IService" binding="basicHttpBinding"/> /// <endpoint address="rest" contract="Services.IService" binding="webHttpBinding" behaviorConfiguration="restBehavior"/> /// </service> /// </services> /// <behaviors> /// <serviceBehaviors> /// <behavior> /// <serviceMetadata httpGetEnabled="true"/> /// </behavior> /// </serviceBehaviors> /// <endpointBehaviors> /// <behavior name="restBehavior"> /// <webHttp helpEnabled="true"/> /// </behavior> /// </endpointBehaviors> /// </behaviors> /// <serviceHostingEnvironment multipleSiteBindingsEnabled="true"> /// <serviceActivations> /// <add relativeAddress="Service.svc" service="Services.Service, Services"/> /// </serviceActivations> /// </serviceHostingEnvironment> /// </system.serviceModel> /// </configuration> /// ]]> /// </code> /// </example> public class SelfHostingService : Adapter, ISelfHostingService, IPolicyRetriever { #region [ Members ] // Events /// <summary> /// Occurs when the <see cref="ServiceHost"/> has been created with the specified <see cref="Endpoints"/>. /// </summary> /// <remarks> /// When <see cref="ServiceHostCreated"/> event is fired, changes like adding new endpoints can be made to the <see cref="ServiceHost"/>. /// </remarks> public event EventHandler ServiceHostCreated; /// <summary> /// Occurs when the <see cref="ServiceHost"/> has can process requests via all of its endpoints. /// </summary> public event EventHandler ServiceHostStarted; /// <summary> /// Occurs when an <see cref="Exception"/> is encountered when processing a request. /// </summary> /// <remarks> /// <see cref="EventArgs{T}.Argument"/> is the exception encountered when processing a request. /// </remarks> public event EventHandler<EventArgs<Exception>> ServiceProcessException; // Fields private string m_endpoints; private string m_contractInterface; private bool m_singleton; private string m_securityPolicy; private bool m_publishMetadata; private bool m_allowCrossDomainAccess; private string m_allowedDomainList; private bool m_windowsAuthentication; private bool m_serviceEnabled; private bool m_disposed; private bool m_initialized; private ServiceHost m_serviceHost; #endregion #region [ Constructors ] /// <summary> /// Initializes a new instance of the web service. /// </summary> protected SelfHostingService() { Type type = GetType(); m_endpoints = string.Empty; m_contractInterface = type.Namespace + ".I" + type.Name + ", " + type.AssemblyQualifiedName.ToNonNullString().Split(',')[1].Trim(); m_allowCrossDomainAccess = false; m_allowedDomainList = "*"; m_serviceEnabled = true; } /// <summary> /// Releases the unmanaged resources before the web service is reclaimed by <see cref="GC"/>. /// </summary> ~SelfHostingService() { Dispose(false); } #endregion #region [ Properties ] /// <summary> /// Gets or sets a boolean value that indicates whether the web service is currently enabled. /// </summary> public override bool Enabled { get { return ((object)m_serviceHost != null && m_serviceHost.State == CommunicationState.Opened); } set { if (value && !Enabled) { // Enable if (!m_initialized) Initialize(); else InitializeServiceHost(); } else if (!value && Enabled) { // Disable m_serviceHost.Close(); } } } /// <summary> /// Gets or sets a semicolon delimited list of URIs where the web service can be accessed. /// </summary> /// <remarks> /// Set <see cref="Endpoints"/> to a null or empty string to disable web service hosting. Refer to <see cref="Service.CreateServiceBinding"/> /// for a list of supported URI formats. /// </remarks> public string Endpoints { get { return m_endpoints; } set { m_endpoints = value; } } /// <summary> /// Gets or sets the <see cref="Type.FullName"/> of the contract interface implemented by the web service. /// </summary> /// <exception cref="ArgumentNullException">The value being assigned is a null or empty string.</exception> public string ContractInterface { get { return m_contractInterface; } set { if (string.IsNullOrEmpty(value)) throw new ArgumentNullException("value"); m_contractInterface = value; } } /// <summary> /// Gets or sets a boolean value that indicates whether the <see cref="ServiceHost"/> will use the current instance of the web service for processing /// requests or base the web service instance creation on <see cref="InstanceContextMode"/> specified in its <see cref="ServiceBehaviorAttribute"/>. /// </summary> public bool Singleton { get { return m_singleton; } set { m_singleton = value; } } /// <summary> /// Gets or sets the <see cref="Type.FullName"/> of <see cref="IAuthorizationPolicy"/> to be used for securing all web service <see cref="Endpoints"/>. /// </summary> public string SecurityPolicy { get { return m_securityPolicy; } set { m_securityPolicy = value; } } /// <summary> /// Gets or sets a boolean value that indicates whether web service metadata is to made available at all web service <see cref="Endpoints"/>. /// </summary> public bool PublishMetadata { get { return m_publishMetadata; } set { m_publishMetadata = value; } } /// <summary> /// Gets or sets flag that indicates if web services will enable cross-domain access for Silverlight and Flash applications. /// </summary> public bool AllowCrossDomainAccess { get { return m_allowCrossDomainAccess; } set { m_allowCrossDomainAccess = value; } } /// <summary> /// Gets or sets comma separated list of allowed domains when <see cref="AllowCrossDomainAccess"/> is <c>true</c>. Use * for domain wildcards, e.g., *.consoto.com. /// </summary> /// <remarks> /// To allow all domains just set this property to "*". /// </remarks> public string AllowedDomainList { get { return m_allowedDomainList; } set { m_allowedDomainList = value; } } /// <summary> /// Gets or sets a boolean value that indicates whether Windows Authentication is to be enabled. /// </summary> public bool WindowsAuthentication { get { return m_windowsAuthentication; } set { m_windowsAuthentication = value; } } /// <summary> /// Gets or sets a boolean value that indicates whether the web service is to be enabled at startup. /// </summary> public bool ServiceEnabled { get { return m_serviceEnabled; } set { m_serviceEnabled = value; } } /// <summary> /// Gets the <see cref="WebServiceHost"/> hosting the web service. /// </summary> /// <remarks> /// By default, the <see cref="ServiceHost"/> only has <see cref="WebHttpBinding"/> endpoint at the <see cref="Endpoints"/>. /// Additional endpoints can be added to the <see cref="ServiceHost"/> when <see cref="ServiceHostCreated"/> event is fired. /// </remarks> public ServiceHost ServiceHost { get { return m_serviceHost; } } #endregion #region [ Methods ] /// <summary> /// Initializes the web service. /// </summary> public override void Initialize() { base.Initialize(); if (!m_initialized) { // Initialize the service host. InitializeServiceHost(); // Initialize only once. m_initialized = true; } } /// <summary> /// Saves web service settings to the config file if the <see cref="Adapter.PersistSettings"/> property is set to true. /// </summary> public override void SaveSettings() { base.SaveSettings(); if (PersistSettings) { // Save settings under the specified category. ConfigurationFile config = ConfigurationFile.Current; CategorizedSettingsElementCollection settings = config.Settings[SettingsCategory]; settings["Endpoints", true].Update(m_endpoints); settings["Contract", true].Update(m_contractInterface); settings["Singleton", true].Update(m_singleton); settings["SecurityPolicy", true].Update(m_securityPolicy); settings["PublishMetadata", true].Update(m_publishMetadata); settings["AllowCrossDomainAccess", true].Update(m_allowCrossDomainAccess); settings["AllowedDomainList", true].Update(m_allowedDomainList); config.Save(); } } /// <summary> /// Loads saved web service settings from the config file if the <see cref="Adapter.PersistSettings"/> property is set to true. /// </summary> public override void LoadSettings() { base.LoadSettings(); if (PersistSettings) { // Load settings from the specified category. ConfigurationFile config = ConfigurationFile.Current; CategorizedSettingsElementCollection settings = config.Settings[SettingsCategory];Lines 1–500 of 802. Load more
//****************************************************************************************************** // SelfHostingService.cs - Gbtc // // Copyright © 2012, Grid Protection Alliance. All Rights Reserved. // // Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See // the NOTICE file distributed with this work for additional information regarding copyright ownership. // The GPA licenses this file to you under the MIT License (MIT), 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.opensource.org/licenses/MIT // // Unless agreed to in writing, the subject software distributed under the License is distributed on an // "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the // License for the specific language governing permissions and limitations. // // Code Modification History: // ---------------------------------------------------------------------------------------------------- // 08/27/2009 - Pinal C. Patel // Generated original version of source code. // 09/02/2009 - Pinal C. Patel // Modified configuration of the default WebHttpBinding to enable receiving of large payloads. // 09/15/2009 - Stephen C. Wills // Added new header and license agreement. // 11/27/2009 - Pinal C. Patel // Fixed issue in the initialization of service contract name. // 03/30/2010 - Pinal C. Patel // Updated CanRead and CanWrite to not include Enabled in its evaluation. // 05/28/2010 - Pinal C. Patel // Added an endpoint for web service help. // 06/21/2010 - Pinal C. Patel // Added Singleton property for added control over the hosting process. // 10/08/2010 - Pinal C. Patel // Removed REST web service help endpoint since a similar feature is now part of WCF 4.0. // 10/14/2010 - Pinal C. Patel // Made changes for hosting flexibility and enabling security: // Deleted DataFlow since access restriction can now be imposed by enabling security. // Added SecurityPolicy and PublishMetadata. // Renamed ServiceUri to Endpoints and ServiceContract to Contract. // 10/26/2010 - Pinal C. Patel // Modified the implementation of ISupportLifecycle.Enabled property. // 10/29/2010 - Pinal C. Patel // Modified CreateServiceBinding() to explicitly disable security on created binding if specified. // 11/19/2010 - Pinal C. Patel // Changed to inherit from Adapter to take advantage of app domain isolation through AdapterLoader. // 12/09/2010 - Pinal C. Patel // Modified GetUnusedPort() to use GSF.Security.Cryptography.Random instead of System.Random to // unsure unique numbers. // 11/29/2011 - Pinal C. Patel // Modified InitializeServiceHost() to not use a random port number for the service host address // so that setting up security on the address is possible. // 08/02/2012 - J. Ritchie Carroll // Added cross-domain access support for Silverlight and Flash application using self hosted // web services (enables access to clientaccesspolicy.xml and crossdomain.xml). // 12/20/2012 - Starlynn Danyelle Gilliam // Modified Header. // 12/11/2013 - Pinal C. Patel // Added WindowsAuthentication property to allow Windows Authentication to be enabled explicitly // even if SecurityPolicy is not configured to allow for more flexibility. // //****************************************************************************************************** using System; using System.Collections.Generic; using System.IdentityModel.Policy; using System.IO; using System.Linq; using System.Net; using System.Net.NetworkInformation; using System.ServiceModel; using System.ServiceModel.Channels; using System.ServiceModel.Description; using System.ServiceModel.Web; using System.Text; using System.Text.RegularExpressions; using GSF.Adapters; using GSF.Configuration; using Random = GSF.Security.Cryptography.Random; namespace GSF.ServiceModel { /// <summary> /// A base class for web service that can send and receive data over REST (Representational State Transfer) interface. /// </summary> /// <example> /// This example shows how to create a WCF service derived from <see cref="SelfHostingService"/> that is capable of hosting itself: /// <code> /// using System.ServiceModel; /// using System.ServiceModel.Web; /// using GSF.ServiceModel; /// /// namespace Services /// { /// [ServiceContract()] /// public interface IService : ISelfHostingService /// { /// [OperationContract(), WebGet(UriTemplate = "/hello/{name}")] /// string Hello(string name); /// } /// /// public class Service : SelfHostingService, IService /// { /// public string Hello(string name) /// { /// return string.Format("Hello {0}!", name); /// } /// } /// } /// </code> /// This example shows how to activate a WCF service derived from <see cref="SelfHostingService"/> that is capable of hosting itself: /// <code> /// using System; /// using System.ServiceModel; /// using System.ServiceModel.Description; /// using System.ServiceModel.Web; /// using Services; /// using GSF.ServiceModel; /// /// class Program /// { /// static void Main(string[] args) /// { /// // Initialize web service. /// Service service = new Service(); /// service.PublishMetadata = true; /// service.Endpoints = "http.soap11://localhost:4500/soap; http.rest://localhost:4500/rest"; /// service.Initialize(); /// /// // Show web service status. /// if (service.ServiceHost.State == CommunicationState.Opened) /// { /// Console.WriteLine("\r\n{0} is running:", service.GetType().Name); /// foreach (ServiceEndpoint endpoint in service.ServiceHost.Description.Endpoints) /// { /// Console.WriteLine("- {0} ({1})", endpoint.Address, endpoint.Binding.GetType().Name); /// } /// Console.Write("\r\nPress Enter key to stop..."); /// } /// else /// { /// Console.WriteLine("\r\n{0} could not be started", service.GetType().Name); /// } /// /// // Shutdown. /// Console.ReadLine(); /// service.Dispose(); /// } /// } /// </code> /// This example shows how to host a WCF service derived from <see cref="SelfHostingService"/> inside ASP.NET: /// <code> /// <![CDATA[ /// <?xml version="1.0"?> /// <configuration> /// <system.serviceModel> /// <services> /// <service name="Services.Service"> /// <endpoint address="soap" contract="Services.IService" binding="basicHttpBinding"/> /// <endpoint address="rest" contract="Services.IService" binding="webHttpBinding" behaviorConfiguration="restBehavior"/> /// </service> /// </services> /// <behaviors> /// <serviceBehaviors> /// <behavior> /// <serviceMetadata httpGetEnabled="true"/> /// </behavior> /// </serviceBehaviors> /// <endpointBehaviors> /// <behavior name="restBehavior"> /// <webHttp helpEnabled="true"/> /// </behavior> /// </endpointBehaviors> /// </behaviors> /// <serviceHostingEnvironment multipleSiteBindingsEnabled="true"> /// <serviceActivations> /// <add relativeAddress="Service.svc" service="Services.Service, Services"/> /// </serviceActivations> /// </serviceHostingEnvironment> /// </system.serviceModel> /// </configuration> /// ]]> /// </code> /// </example> public class SelfHostingService : Adapter, ISelfHostingService, IPolicyRetriever { #region [ Members ] // Events /// <summary> /// Occurs when the <see cref="ServiceHost"/> has been created with the specified <see cref="Endpoints"/>. /// </summary> /// <remarks> /// When <see cref="ServiceHostCreated"/> event is fired, changes like adding new endpoints can be made to the <see cref="ServiceHost"/>. /// </remarks> public event EventHandler ServiceHostCreated; /// <summary> /// Occurs when the <see cref="ServiceHost"/> has can process requests via all of its endpoints. /// </summary> public event EventHandler ServiceHostStarted; /// <summary> /// Occurs when an <see cref="Exception"/> is encountered when processing a request. /// </summary> /// <remarks> /// <see cref="EventArgs{T}.Argument"/> is the exception encountered when processing a request. /// </remarks> public event EventHandler<EventArgs<Exception>> ServiceProcessException; // Fields private string m_endpoints; private string m_contractInterface; private bool m_singleton; private string m_securityPolicy; private bool m_publishMetadata; private bool m_allowCrossDomainAccess; private string m_allowedDomainList; private bool m_windowsAuthentication; private bool m_serviceEnabled; private bool m_disposed; private bool m_initialized; private ServiceHost m_serviceHost; #endregion #region [ Constructors ] /// <summary> /// Initializes a new instance of the web service. /// </summary> protected SelfHostingService() { Type type = GetType(); m_endpoints = string.Empty; m_contractInterface = type.Namespace + ".I" + type.Name + ", " + type.AssemblyQualifiedName.ToNonNullString().Split(',')[1].Trim(); m_allowCrossDomainAccess = false; m_allowedDomainList = "*"; m_serviceEnabled = true; } /// <summary> /// Releases the unmanaged resources before the web service is reclaimed by <see cref="GC"/>. /// </summary> ~SelfHostingService() { Dispose(false); } #endregion #region [ Properties ] /// <summary> /// Gets or sets a boolean value that indicates whether the web service is currently enabled. /// </summary> public override bool Enabled { get { return ((object)m_serviceHost != null && m_serviceHost.State == CommunicationState.Opened); } set { if (value && !Enabled) { // Enable if (!m_initialized) Initialize(); else InitializeServiceHost(); } else if (!value && Enabled) { // Disable m_serviceHost.Close(); } } } /// <summary> /// Gets or sets a semicolon delimited list of URIs where the web service can be accessed. /// </summary> /// <remarks> /// Set <see cref="Endpoints"/> to a null or empty string to disable web service hosting. Refer to <see cref="Service.CreateServiceBinding"/> /// for a list of supported URI formats. /// </remarks> public string Endpoints { get { return m_endpoints; } set { m_endpoints = value; } } /// <summary> /// Gets or sets the <see cref="Type.FullName"/> of the contract interface implemented by the web service. /// </summary> /// <exception cref="ArgumentNullException">The value being assigned is a null or empty string.</exception> public string ContractInterface { get { return m_contractInterface; } set { if (string.IsNullOrEmpty(value)) throw new ArgumentNullException("value"); m_contractInterface = value; } } /// <summary> /// Gets or sets a boolean value that indicates whether the <see cref="ServiceHost"/> will use the current instance of the web service for processing /// requests or base the web service instance creation on <see cref="InstanceContextMode"/> specified in its <see cref="ServiceBehaviorAttribute"/>. /// </summary> public bool Singleton { get { return m_singleton; } set { m_singleton = value; } } /// <summary> /// Gets or sets the <see cref="Type.FullName"/> of <see cref="IAuthorizationPolicy"/> to be used for securing all web service <see cref="Endpoints"/>. /// </summary> public string SecurityPolicy { get { return m_securityPolicy; } set { m_securityPolicy = value; } } /// <summary> /// Gets or sets a boolean value that indicates whether web service metadata is to made available at all web service <see cref="Endpoints"/>. /// </summary> public bool PublishMetadata { get { return m_publishMetadata; } set { m_publishMetadata = value; } } /// <summary> /// Gets or sets flag that indicates if web services will enable cross-domain access for Silverlight and Flash applications. /// </summary> public bool AllowCrossDomainAccess { get { return m_allowCrossDomainAccess; } set { m_allowCrossDomainAccess = value; } } /// <summary> /// Gets or sets comma separated list of allowed domains when <see cref="AllowCrossDomainAccess"/> is <c>true</c>. Use * for domain wildcards, e.g., *.consoto.com. /// </summary> /// <remarks> /// To allow all domains just set this property to "*". /// </remarks> public string AllowedDomainList { get { return m_allowedDomainList; } set { m_allowedDomainList = value; } } /// <summary> /// Gets or sets a boolean value that indicates whether Windows Authentication is to be enabled. /// </summary> public bool WindowsAuthentication { get { return m_windowsAuthentication; } set { m_windowsAuthentication = value; } } /// <summary> /// Gets or sets a boolean value that indicates whether the web service is to be enabled at startup. /// </summary> public bool ServiceEnabled { get { return m_serviceEnabled; } set { m_serviceEnabled = value; } } /// <summary> /// Gets the <see cref="WebServiceHost"/> hosting the web service. /// </summary> /// <remarks> /// By default, the <see cref="ServiceHost"/> only has <see cref="WebHttpBinding"/> endpoint at the <see cref="Endpoints"/>. /// Additional endpoints can be added to the <see cref="ServiceHost"/> when <see cref="ServiceHostCreated"/> event is fired. /// </remarks> public ServiceHost ServiceHost { get { return m_serviceHost; } } #endregion #region [ Methods ] /// <summary> /// Initializes the web service. /// </summary> public override void Initialize() { base.Initialize(); if (!m_initialized) { // Initialize the service host. InitializeServiceHost(); // Initialize only once. m_initialized = true; } } /// <summary> /// Saves web service settings to the config file if the <see cref="Adapter.PersistSettings"/> property is set to true. /// </summary> public override void SaveSettings() { base.SaveSettings(); if (PersistSettings) { // Save settings under the specified category. ConfigurationFile config = ConfigurationFile.Current; CategorizedSettingsElementCollection settings = config.Settings[SettingsCategory]; settings["Endpoints", true].Update(m_endpoints); settings["Contract", true].Update(m_contractInterface); settings["Singleton", true].Update(m_singleton); settings["SecurityPolicy", true].Update(m_securityPolicy); settings["PublishMetadata", true].Update(m_publishMetadata); settings["AllowCrossDomainAccess", true].Update(m_allowCrossDomainAccess); settings["AllowedDomainList", true].Update(m_allowedDomainList); config.Save(); } } /// <summary> /// Loads saved web service settings from the config file if the <see cref="Adapter.PersistSettings"/> property is set to true. /// </summary> public override void LoadSettings() { base.LoadSettings(); if (PersistSettings) { // Load settings from the specified category. ConfigurationFile config = ConfigurationFile.Current; CategorizedSettingsElementCollection settings = config.Settings[SettingsCategory];