Code:
/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / ServiceModel / System / ServiceModel / ServiceHost.cs / 1 / ServiceHost.cs
//------------------------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. //----------------------------------------------------------------------------- namespace System.ServiceModel { using System; using System.ServiceModel.Administration; using System.ServiceModel.Dispatcher; using System.ServiceModel.Description; using System.Text; using System.ServiceModel.Configuration; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.Globalization; using System.Runtime.Serialization; using System.Runtime.InteropServices; using System.ServiceModel.Channels; using System.ServiceModel.Diagnostics; using System.Threading; using System.Xml; using System.Security; public abstract class ServiceHostBase : CommunicationObject, IExtensibleObject, IDisposable { internal static readonly Uri EmptyUri = new Uri(string.Empty, UriKind.RelativeOrAbsolute); bool initializeDescriptionHasFinished; UriSchemeKeyedCollection baseAddresses; ChannelDispatcherCollection channelDispatchers; TimeSpan closeTimeout = ServiceDefaults.ServiceHostCloseTimeout; ServiceDescription description; ExtensionCollection extensions; ReadOnlyCollection externalBaseAddresses; IDictionary implementedContracts; IInstanceContextManager instances; TimeSpan openTimeout = ServiceDefaults.OpenTimeout; ServicePerformanceCounters servicePerformanceCounters; DefaultPerformanceCounters defaultPerformanceCounters; ServiceThrottle serviceThrottle; ServiceCredentials readOnlyCredentials; ServiceAuthorizationBehavior readOnlyAuthorization; public event EventHandler UnknownMessageReceived; protected ServiceHostBase() { this.baseAddresses = new UriSchemeKeyedCollection(this.ThisLock); this.channelDispatchers = new ChannelDispatcherCollection(this, this.ThisLock); this.extensions = new ExtensionCollection (this, this.ThisLock); this.instances = new InstanceContextManager(this.ThisLock); this.serviceThrottle = new ServiceThrottle(this); this.TraceOpenAndClose = true; this.Faulted += new EventHandler(OnServiceHostFaulted); } public ServiceAuthorizationBehavior Authorization { get { if (this.Description == null) { return null; } else if (this.State == CommunicationState.Created || this.State == CommunicationState.Opening) { return EnsureAuthorization(this.Description); } else { return this.readOnlyAuthorization; } } } public ReadOnlyCollection BaseAddresses { get { externalBaseAddresses = new ReadOnlyCollection (new List (this.baseAddresses)); return externalBaseAddresses; } } public ChannelDispatcherCollection ChannelDispatchers { get { return this.channelDispatchers; } } public TimeSpan CloseTimeout { get { return this.closeTimeout; } set { if (value < TimeSpan.Zero) { string message = SR.GetString(SR.SFxTimeoutOutOfRange0); throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("value", message)); } if (TimeoutHelper.IsTooLarge(value)) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("value", SR.GetString(SR.SFxTimeoutOutOfRangeTooBig))); } lock (this.ThisLock) { this.ThrowIfClosedOrOpened(); this.closeTimeout = value; } } } internal ServicePerformanceCounters Counters { get { return this.servicePerformanceCounters; } set { this.servicePerformanceCounters = value; } } internal DefaultPerformanceCounters DefaultCounters { get { return this.defaultPerformanceCounters; } set { this.defaultPerformanceCounters = value; } } public ServiceCredentials Credentials { get { if (this.Description == null) { return null; } else if (this.State == CommunicationState.Created || this.State == CommunicationState.Opening) { return EnsureCredentials(this.Description); } else { return this.readOnlyCredentials; } } } protected override TimeSpan DefaultCloseTimeout { get { return this.CloseTimeout; } } protected override TimeSpan DefaultOpenTimeout { get { return this.OpenTimeout; } } public ServiceDescription Description { get { return this.description; } } public IExtensionCollection Extensions { get { return this.extensions; } } protected IDictionary ImplementedContracts { get { return this.implementedContracts; } } internal UriSchemeKeyedCollection InternalBaseAddresses { get { return this.baseAddresses; } } public int ManualFlowControlLimit { get { return this.ServiceThrottle.ManualFlowControlLimit; } set { this.ServiceThrottle.ManualFlowControlLimit = value; } } public TimeSpan OpenTimeout { get { return this.openTimeout; } set { if (value < TimeSpan.Zero) { string message = SR.GetString(SR.SFxTimeoutOutOfRange0); throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("value", message)); } if (TimeoutHelper.IsTooLarge(value)) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("value", SR.GetString(SR.SFxTimeoutOutOfRangeTooBig))); } lock (this.ThisLock) { this.ThrowIfClosedOrOpened(); this.openTimeout = value; } } } internal ServiceThrottle ServiceThrottle { get { return this.serviceThrottle; } } internal virtual object DisposableInstance { get { return null; } } protected void AddBaseAddress(Uri baseAddress) { if (this.initializeDescriptionHasFinished) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException( SR.GetString(SR.SFxCannotCallAddBaseAddress))); } this.baseAddresses.Add(baseAddress); } public ServiceEndpoint AddServiceEndpoint(string implementedContract, Binding binding, string address) { return this.AddServiceEndpoint(implementedContract, binding, address, (Uri)null); } public ServiceEndpoint AddServiceEndpoint(string implementedContract, Binding binding, string address, Uri listenUri) { if (address == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("address")); } ServiceEndpoint endpoint = this.AddServiceEndpoint(implementedContract, binding, new Uri(address, UriKind.RelativeOrAbsolute)); if (listenUri != null) { listenUri = MakeAbsoluteUri(listenUri, binding); endpoint.ListenUri = listenUri; } return endpoint; } public ServiceEndpoint AddServiceEndpoint(string implementedContract, Binding binding, Uri address) { return this.AddServiceEndpoint(implementedContract, binding, address, (Uri)null); } public ServiceEndpoint AddServiceEndpoint(string implementedContract, Binding binding, Uri address, Uri listenUri) { if (address == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("address")); } if (binding == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("binding")); } if (implementedContract == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("implementedContract")); } if (this.State != CommunicationState.Created && this.State != CommunicationState.Opening) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxServiceHostBaseCannotAddEndpointAfterOpen))); } if (this.Description == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxServiceHostBaseCannotAddEndpointWithoutDescription))); } Uri via = this.MakeAbsoluteUri(address, binding); ConfigLoader configLoader = new ConfigLoader(GetContractResolver(this.implementedContracts)); ContractDescription contract = configLoader.LookupContract(implementedContract, this.Description.Name); ServiceEndpoint serviceEndpoint = new ServiceEndpoint(contract, binding, new EndpointAddress(via)); this.Description.Endpoints.Add(serviceEndpoint); if (listenUri != null) { listenUri = MakeAbsoluteUri(listenUri, binding); serviceEndpoint.ListenUri = listenUri; } return serviceEndpoint; } internal Uri MakeAbsoluteUri(Uri relativeOrAbsoluteUri, Binding binding) { return MakeAbsoluteUri(relativeOrAbsoluteUri, binding, this.InternalBaseAddresses); } internal static Uri MakeAbsoluteUri(Uri relativeOrAbsoluteUri, Binding binding, UriSchemeKeyedCollection baseAddresses) { Uri result = relativeOrAbsoluteUri; if (!result.IsAbsoluteUri) { if (binding.Scheme == string.Empty) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxCustomBindingWithoutTransport))); } result = GetVia(binding.Scheme, result, baseAddresses); if (result == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxEndpointNoMatchingScheme, binding.Scheme, binding.Name, GetBaseAddressSchemes(baseAddresses)))); } } return result; } protected virtual void ApplyConfiguration() { if (this.Description == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxServiceHostBaseCannotApplyConfigurationWithoutDescription))); } ConfigLoader configLoader = new ConfigLoader(GetContractResolver(implementedContracts)); LoadConfigurationSectionInternal(configLoader, this.Description, this.Description.ConfigurationName); EnsureAuthorization(description); EnsureDebug(description); } internal virtual void BindInstance(InstanceContext instance) { this.instances.Add(instance); if (null != this.servicePerformanceCounters) { lock (this.ThisLock) { if (null != this.servicePerformanceCounters) { this.servicePerformanceCounters.ServiceInstanceCreated(); } } } } void IDisposable.Dispose() { Close(); } protected abstract ServiceDescription CreateDescription(out IDictionary implementedContracts); protected virtual void InitializeRuntime() { if (this.Description == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxServiceHostBaseCannotInitializeRuntimeWithoutDescription))); } DispatcherBuilder dispatcherBuilder = new DispatcherBuilder(); dispatcherBuilder.InitializeServiceHost(description, this); SecurityValidationBehavior.Instance.AfterBuildTimeValidation(description); } ServiceAuthorizationBehavior EnsureAuthorization(ServiceDescription description) { DiagnosticUtility.DebugAssert(this.State == CommunicationState.Created || this.State == CommunicationState.Opening, ""); ServiceAuthorizationBehavior a = description.Behaviors.Find (); if (a == null) { a = new ServiceAuthorizationBehavior(); description.Behaviors.Add(a); } return a; } ServiceDebugBehavior EnsureDebug(ServiceDescription description) { DiagnosticUtility.DebugAssert(this.State == CommunicationState.Created || this.State == CommunicationState.Opening, ""); ServiceDebugBehavior m = description.Behaviors.Find (); if (m == null) { m = new ServiceDebugBehavior(); description.Behaviors.Add(m); } return m; } ServiceCredentials EnsureCredentials(ServiceDescription description) { DiagnosticUtility.DebugAssert(this.State == CommunicationState.Created || this.State == CommunicationState.Opening, ""); ServiceCredentials c = description.Behaviors.Find (); if (c == null) { c = new ServiceCredentials(); description.Behaviors.Add(c); } return c; } internal void FaultInternal() { this.Fault(); } internal string GetBaseAddressSchemes() { return GetBaseAddressSchemes(baseAddresses); } internal static String GetBaseAddressSchemes(UriSchemeKeyedCollection uriSchemeKeyedCollection) { StringBuilder buffer = new StringBuilder(); bool firstScheme = true; foreach (Uri address in uriSchemeKeyedCollection) { if (firstScheme) { buffer.Append(address.Scheme); firstScheme = false; } else { buffer.Append(CultureInfo.CurrentCulture.TextInfo.ListSeparator).Append(address.Scheme); } } return buffer.ToString(); } internal ReadOnlyCollection GetInstanceContexts() { return new ReadOnlyCollection (Array.AsReadOnly (instances.ToArray())); } internal virtual IContractResolver GetContractResolver(IDictionary implementedContracts) { ServiceAndBehaviorsContractResolver resolver = new ServiceAndBehaviorsContractResolver(new ImplementedContractsContractResolver(implementedContracts)); resolver.AddBehaviorContractsToResolver(this.description==null ? null : this.description.Behaviors); return resolver; } internal static Uri GetUri(Uri baseUri, Uri relativeUri) { return GetUri(baseUri, relativeUri.OriginalString); } internal static Uri GetUri(Uri baseUri, string path) { if (path.StartsWith("/", StringComparison.Ordinal) || path.StartsWith("\\", StringComparison.Ordinal)) { int i = 1; for (; i < path.Length; ++i) { if (path[i] != '/' && path[i] != '\\') { break; } } path = path.Substring(i); } // VSWhidbey#541152: new Uri(Uri, string.Empty) is broken if (path.Length == 0) return baseUri; if (!baseUri.AbsoluteUri.EndsWith("/", StringComparison.Ordinal)) { baseUri = new Uri(baseUri.AbsoluteUri + "/"); } return new Uri(baseUri, path); } internal Uri GetVia(string scheme, Uri address) { return ServiceHost.GetVia(scheme, address, InternalBaseAddresses); } internal static Uri GetVia(string scheme, Uri address, UriSchemeKeyedCollection baseAddresses) { Uri via = address; if (!via.IsAbsoluteUri) { if (!baseAddresses.Contains(scheme)) { return null; } via = GetUri(baseAddresses[scheme], address); } return via; } public int IncrementManualFlowControlLimit(int incrementBy) { return this.ServiceThrottle.IncrementManualFlowControlLimit(incrementBy); } protected void InitializeDescription(UriSchemeKeyedCollection baseAddresses) { foreach (Uri baseAddress in baseAddresses) { this.baseAddresses.Add(baseAddress); } IDictionary implementedContracts = null; ServiceDescription description = CreateDescription(out implementedContracts); this.description = description; this.implementedContracts = implementedContracts; ApplyConfiguration(); this.initializeDescriptionHasFinished = true; } protected void LoadConfigurationSection(ServiceElement serviceSection) { if (serviceSection == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("serviceSection"); } if (this.Description == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxServiceHostBaseCannotLoadConfigurationSectionWithoutDescription))); } ConfigLoader configLoader = new ConfigLoader(GetContractResolver(this.ImplementedContracts)); LoadConfigurationSectionInternal(configLoader, this.Description, serviceSection); } internal void LoadConfigurationSectionHelper(Uri baseAddress) { this.AddBaseAddress(baseAddress); } /// /// Critical - calls LookupService which is critical /// Safe - doesn't leak ServiceElement out of SecurityCritical code /// [SecurityCritical, SecurityTreatAsSafe] void LoadConfigurationSectionInternal(ConfigLoader configLoader, ServiceDescription description, string configurationName) { ServiceElement serviceSection = configLoader.LookupService(configurationName); LoadConfigurationSectionInternal(configLoader, description, serviceSection); } ////// Critical - handles a ServiceElement, which should not be leaked out of SecurityCritical code /// Safe - doesn't leak ServiceElement out of SecurityCritical code /// [SecurityCritical, SecurityTreatAsSafe] void LoadConfigurationSectionInternal(ConfigLoader configLoader, ServiceDescription description, ServiceElement serviceSection) { // caller must validate arguments before calling configLoader.LoadServiceDescription(this, description, serviceSection, this.LoadConfigurationSectionHelper); } protected sealed override void OnAbort() { instances.Abort(); foreach (ChannelDispatcherBase dispatcher in this.ChannelDispatchers) { if (dispatcher.Listener != null) { dispatcher.Listener.Abort(); } dispatcher.Abort(); } ThreadTrace.StopTracing(); } internal void OnAddChannelDispatcher(ChannelDispatcherBase channelDispatcher) { lock (this.ThisLock) { this.ThrowIfClosedOrOpened(); channelDispatcher.AttachInternal(this); channelDispatcher.Faulted += new EventHandler(OnChannelDispatcherFaulted); } } protected sealed override IAsyncResult OnBeginClose(TimeSpan timeout, AsyncCallback callback, object state) { return new CloseAsyncResult(timeout, callback, state, this); } void OnBeginOpen() { this.TraceBaseAddresses(); MessageLogger.EnsureInitialized(); //force config validation instead of waiting for the first message exchange InitializeRuntime(); } protected sealed override IAsyncResult OnBeginOpen(TimeSpan timeout, AsyncCallback callback, object state) { TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); this.OnBeginOpen(); return new OpenCollectionAsyncResult(timeout, callback, state, this.SnapshotChannelDispatchers()); } protected override void OnClose(TimeSpan timeout) { try { TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); if (ManagementExtension.IsEnabled && null != this.Description) { ManagementExtension.OnServiceClosing(this); } for (int i = 0; i < this.ChannelDispatchers.Count; i++) { ChannelDispatcherBase dispatcher = this.ChannelDispatchers[i]; if (dispatcher.Listener != null) { dispatcher.Listener.Close(timeoutHelper.RemainingTime()); } } for (int i = 0; i < this.ChannelDispatchers.Count; i++) { ChannelDispatcherBase dispatcher = this.ChannelDispatchers[i]; dispatcher.CloseInput(); } // Wait for existing work to complete instances.CloseInput(timeoutHelper.RemainingTime()); // Close instances (closes contexts/channels) instances.Close(timeoutHelper.RemainingTime()); // Close dispatchers for (int i = 0; i < this.ChannelDispatchers.Count; i++) { ChannelDispatcherBase dispatcher = this.ChannelDispatchers[i]; dispatcher.Close(timeoutHelper.RemainingTime()); } this.ReleasePerformanceCounters(); this.TraceBaseAddresses(); ThreadTrace.StopTracing(); } catch (TimeoutException e) { if (DiagnosticUtility.ShouldTraceWarning) { TraceUtility.TraceEvent(TraceEventType.Warning, TraceCode.ServiceHostTimeoutOnClose, this, e); } this.Abort(); } } void TraceBaseAddresses() { if (DiagnosticUtility.ShouldTraceInformation && this.baseAddresses != null && this.baseAddresses.Count > 0) { TraceUtility.TraceEvent(TraceEventType.Information, TraceCode.ServiceHostBaseAddresses, new CollectionTraceRecord("BaseAddresses", "Address", this.baseAddresses), this, null); } } protected override void OnEndClose(IAsyncResult result) { try { CloseAsyncResult.End(result); this.ReleasePerformanceCounters(); this.TraceBaseAddresses(); ThreadTrace.StopTracing(); } catch (TimeoutException e) { if (DiagnosticUtility.ShouldTraceWarning) { TraceUtility.TraceEvent(TraceEventType.Warning, TraceCode.ServiceHostTimeoutOnClose, this, e); } this.Abort(); } } protected sealed override void OnEndOpen(IAsyncResult result) { OpenCollectionAsyncResult.End(result); } protected sealed override void OnOpen(TimeSpan timeout) { TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); this.OnBeginOpen(); for (int i=0; i(); if (c != null) { ServiceCredentials credentialsCopy = c.Clone(); credentialsCopy.MakeReadOnly(); this.readOnlyCredentials = credentialsCopy; } ServiceAuthorizationBehavior authorization = description.Behaviors.Find (); if (authorization != null) { ServiceAuthorizationBehavior authorizationCopy = authorization.Clone(); authorizationCopy.MakeReadOnly(); this.readOnlyAuthorization = authorizationCopy; } if (ManagementExtension.IsEnabled) { ManagementExtension.OnServiceOpened(this); } } base.OnOpened(); } internal void OnRemoveChannelDispatcher(ChannelDispatcherBase channelDispatcher) { lock (this.ThisLock) { this.ThrowIfClosedOrOpened(); channelDispatcher.DetachInternal(this); } } void OnChannelDispatcherFaulted(object sender, EventArgs e) { this.Fault(); } void OnServiceHostFaulted(object sender, EventArgs args) { if (DiagnosticUtility.ShouldTraceWarning) { TraceUtility.TraceEvent(TraceEventType.Warning, TraceCode.ServiceHostFaulted, this); } foreach (ICommunicationObject channelDispatcher in this.SnapshotChannelDispatchers()) { if (channelDispatcher.State == CommunicationState.Opened) { channelDispatcher.Abort(); } } } internal void RaiseUnknownMessageReceived(Message message) { try { EventHandler handler = UnknownMessageReceived; if (handler != null) { handler(this, new UnknownMessageReceivedEventArgs(message)); } } catch (Exception e) { if (DiagnosticUtility.IsFatal(e)) throw; throw DiagnosticUtility.ExceptionUtility.ThrowHelperCallback(e); } } protected void ReleasePerformanceCounters() { if (this.servicePerformanceCounters != null) { lock (this.ThisLock) { if (this.servicePerformanceCounters != null) { PerformanceCounters.ReleasePerformanceCountersForService(this.servicePerformanceCounters, false); this.servicePerformanceCounters = null; } } } if (this.defaultPerformanceCounters != null) { lock (this.ThisLock) { if (this.defaultPerformanceCounters != null) { PerformanceCounters.ReleasePerformanceCountersForService(this.defaultPerformanceCounters, true); this.defaultPerformanceCounters = null; } } } } ICommunicationObject[] SnapshotChannelDispatchers() { lock (this.ThisLock) { ICommunicationObject[] array = new ICommunicationObject[this.ChannelDispatchers.Count]; for (int i=0; i listeners = new List (); for (int i=0; i channelDispatchers = this.serviceHost.SnapshotChannelDispatchers(); AsyncCallback callback = DiagnosticUtility.ThunkAsyncCallback(this.CloseChannelDispatchersCallback); TimeSpan timeout = this.timeoutHelper.RemainingTime(); Exception exception = null; IAsyncResult result = null; try { result = new CloseCollectionAsyncResult(timeout, callback, this, channelDispatchers); } catch (Exception e) { if (DiagnosticUtility.IsFatal(e) || completedSynchronously) { throw; } exception = e; } if (exception != null) { this.CallComplete(completedSynchronously, exception); } else if (result.CompletedSynchronously) { this.FinishCloseChannelDispatchers(result, completedSynchronously); } } void CloseChannelDispatchersCallback(IAsyncResult result) { if (!result.CompletedSynchronously) { ((CloseAsyncResult)result.AsyncState).FinishCloseChannelDispatchers(result, false); } } void FinishCloseChannelDispatchers(IAsyncResult result, bool completedSynchronously) { Exception exception = null; try { CloseCollectionAsyncResult.End(result); } catch (Exception e) { if (DiagnosticUtility.IsFatal(e) || completedSynchronously) { throw; } exception = e; } this.CallComplete(completedSynchronously, exception); } void CallComplete(bool completedSynchronously, Exception exception) { this.Complete(completedSynchronously, exception); } public static void End(IAsyncResult result) { AsyncResult.End (result); } } class ImplementedContractsContractResolver : IContractResolver { IDictionary implementedContracts; public ImplementedContractsContractResolver(IDictionary implementedContracts) { this.implementedContracts = implementedContracts; } public ContractDescription ResolveContract(string contractName) { return this.implementedContracts != null && this.implementedContracts.ContainsKey(contractName) ? this.implementedContracts[contractName] : null; } } internal class ServiceAndBehaviorsContractResolver : IContractResolver { IContractResolver serviceResolver; Dictionary behaviorContracts; public Dictionary BehaviorContracts { get { return behaviorContracts; } } public ServiceAndBehaviorsContractResolver(IContractResolver serviceResolver) { this.serviceResolver = serviceResolver; behaviorContracts = new Dictionary (); } public ContractDescription ResolveContract(string contractName) { ContractDescription contract = serviceResolver.ResolveContract(contractName); if (contract == null) { contract = this.behaviorContracts.ContainsKey(contractName) ? this.behaviorContracts[contractName] : null; } return contract; } public void AddBehaviorContractsToResolver(KeyedByTypeCollection behaviors) { // It would be nice to make this loop over all Behaviors... someday. if (behaviors != null && behaviors.Contains(typeof(ServiceMetadataBehavior))) { behaviors.Find ().AddImplementedContracts(this); } } } } public class ServiceHost : ServiceHostBase { object singletonInstance; Type serviceType; ReflectedContractCollection reflectedContracts; IDisposable disposableInstance; protected ServiceHost() { } public ServiceHost(Type serviceType, params Uri[] baseAddresses) { if (serviceType == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("serviceType")); } this.serviceType = serviceType; using (ServiceModelActivity activity = DiagnosticUtility.ShouldUseActivity ? ServiceModelActivity.CreateBoundedActivity() : null) { if (DiagnosticUtility.ShouldUseActivity) { ServiceModelActivity.Start(activity, SR.GetString(SR.ActivityConstructServiceHost, serviceType.FullName), ActivityType.Construct); } InitializeDescription(serviceType, new UriSchemeKeyedCollection(baseAddresses)); } } public ServiceHost(object singletonInstance, params Uri[] baseAddresses) { if (singletonInstance == null) { throw new ArgumentNullException("singletonInstance"); } this.singletonInstance = singletonInstance; this.serviceType = singletonInstance.GetType(); using (ServiceModelActivity activity = DiagnosticUtility.ShouldUseActivity ? ServiceModelActivity.CreateBoundedActivity() : null) { if (DiagnosticUtility.ShouldUseActivity) { ServiceModelActivity.Start(activity, SR.GetString(SR.ActivityConstructServiceHost, serviceType.FullName), ActivityType.Construct); } InitializeDescription(singletonInstance, new UriSchemeKeyedCollection(baseAddresses)); } } public object SingletonInstance { get { return this.singletonInstance; } } internal override object DisposableInstance { get { return this.disposableInstance; } } public ServiceEndpoint AddServiceEndpoint(Type implementedContract, Binding binding, string address) { return this.AddServiceEndpoint(implementedContract, binding, address, (Uri)null); } public ServiceEndpoint AddServiceEndpoint(Type implementedContract, Binding binding, string address, Uri listenUri) { if (address == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("address")); } ServiceEndpoint endpoint = this.AddServiceEndpoint(implementedContract, binding, new Uri(address, UriKind.RelativeOrAbsolute)); if (listenUri != null) { listenUri = MakeAbsoluteUri(listenUri, binding); endpoint.ListenUri = listenUri; } return endpoint; } public ServiceEndpoint AddServiceEndpoint(Type implementedContract, Binding binding, Uri address) { return this.AddServiceEndpoint(implementedContract, binding, address, (Uri)null); } public ServiceEndpoint AddServiceEndpoint(Type implementedContract, Binding binding, Uri address, Uri listenUri) { if (implementedContract == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("implementedContract")); } if (!implementedContract.IsDefined(typeof(ServiceContractAttribute), false)) { #pragma warning suppress 56506 // implementedContract is never null at this point throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SfxServiceContractAttributeNotFound, implementedContract.FullName))); } if (this.reflectedContracts == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SfxReflectedContractsNotInitialized1, implementedContract.FullName))); } ReflectedAndBehaviorContractCollection reflectedAndBehaviorContracts = new ReflectedAndBehaviorContractCollection(this.reflectedContracts, this.Description.Behaviors); if (!reflectedAndBehaviorContracts.Contains(implementedContract)) { if (implementedContract == typeof(IMetadataExchange)) #pragma warning suppress 56506 // ServiceType is never null at this point throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SfxReflectedContractKeyNotFoundIMetadataExchange, this.serviceType.FullName))); else #pragma warning suppress 56506 // implementedContract and ServiceType are never null at this point throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SfxReflectedContractKeyNotFound2, implementedContract.FullName, this.serviceType.FullName))); } ServiceEndpoint endpoint = AddServiceEndpoint(reflectedAndBehaviorContracts.GetConfigKey(implementedContract), binding, address); if (listenUri != null) { listenUri = MakeAbsoluteUri(listenUri, binding); endpoint.ListenUri = listenUri; } return endpoint; } internal override string CloseActivityName { get { return SR.GetString(SR.ActivityCloseServiceHost, this.serviceType.FullName); } } internal override string OpenActivityName { get { return SR.GetString(SR.ActivityOpenServiceHost, this.serviceType.FullName); } } protected override ServiceDescription CreateDescription(out IDictionary implementedContracts) { if (this.serviceType == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxServiceHostCannotCreateDescriptionWithoutServiceType))); } ServiceDescription description; if (this.SingletonInstance != null) { description = ServiceDescription.GetService(this.SingletonInstance); } else { description = ServiceDescription.GetService(this.serviceType); } ServiceBehaviorAttribute serviceBehavior = description.Behaviors.Find (); object serviceInstanceUsedAsABehavior = serviceBehavior.GetWellKnownSingleton(); if (serviceInstanceUsedAsABehavior == null) { serviceInstanceUsedAsABehavior = serviceBehavior.GetHiddenSingleton(); this.disposableInstance = serviceInstanceUsedAsABehavior as IDisposable; } if ((typeof(IServiceBehavior).IsAssignableFrom(this.serviceType) || typeof(IContractBehavior).IsAssignableFrom(this.serviceType)) && serviceInstanceUsedAsABehavior == null) { serviceInstanceUsedAsABehavior = ServiceDescription.CreateImplementation(this.serviceType); this.disposableInstance = serviceInstanceUsedAsABehavior as IDisposable; } if (this.SingletonInstance == null) { if (serviceInstanceUsedAsABehavior is IServiceBehavior) { description.Behaviors.Add((IServiceBehavior)serviceInstanceUsedAsABehavior); } } ReflectedContractCollection reflectedContracts = new ReflectedContractCollection(); List interfaces = ServiceReflector.GetInterfaces(this.serviceType); for (int i = 0; i < interfaces.Count; i++) { Type contractType = interfaces[i]; if (!reflectedContracts.Contains(contractType)) { ContractDescription contract = null; if (serviceInstanceUsedAsABehavior != null) { contract = ContractDescription.GetContract(contractType, serviceInstanceUsedAsABehavior); } else { contract = ContractDescription.GetContract(contractType, this.serviceType); } reflectedContracts.Add(contract); Collection inheritedContracts = contract.GetInheritedContracts(); for (int j = 0; j < inheritedContracts.Count; j++) { ContractDescription inheritedContract = inheritedContracts[j]; if (!reflectedContracts.Contains(inheritedContract.ContractType)) { reflectedContracts.Add(inheritedContract); } } } } this.reflectedContracts = reflectedContracts; implementedContracts = reflectedContracts.ToImplementedContracts(); return description; } protected void InitializeDescription(object singletonInstance, UriSchemeKeyedCollection baseAddresses) { if (singletonInstance == null) { throw new ArgumentNullException("singletonInstance"); } this.singletonInstance = singletonInstance; InitializeDescription(singletonInstance.GetType(), baseAddresses); } protected void InitializeDescription(Type serviceType, UriSchemeKeyedCollection baseAddresses) { if (serviceType == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("serviceType")); } this.serviceType = serviceType; base.InitializeDescription(baseAddresses); } protected override void OnClosed() { base.OnClosed(); if (this.disposableInstance != null) { this.disposableInstance.Dispose(); } } class ReflectedContractCollection : KeyedCollection { public ReflectedContractCollection() : base(null, 4) { } protected override Type GetKeyForItem(ContractDescription item) { if (item == null) throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("item"); return item.ContractType; } public IDictionary ToImplementedContracts() { Dictionary implementedContracts = new Dictionary (); foreach (ContractDescription contract in this.Items) { implementedContracts.Add(GetConfigKey(contract), contract); } return implementedContracts; } internal static string GetConfigKey(ContractDescription contract) { return contract.ConfigurationName; } } class ReflectedAndBehaviorContractCollection { ReflectedContractCollection reflectedContracts; KeyedByTypeCollection behaviors; public ReflectedAndBehaviorContractCollection(ReflectedContractCollection reflectedContracts, KeyedByTypeCollection behaviors) { this.reflectedContracts = reflectedContracts; this.behaviors = behaviors; } internal bool Contains(Type implementedContract) { if (this.reflectedContracts.Contains(implementedContract)) { return true; } if (this.behaviors.Contains(typeof(ServiceMetadataBehavior)) && ServiceMetadataBehavior.IsMetadataImplementedType(implementedContract)) { return true; } return false; } internal string GetConfigKey(Type implementedContract) { if (this.reflectedContracts.Contains(implementedContract)) { return ReflectedContractCollection.GetConfigKey(reflectedContracts[implementedContract]); } if (this.behaviors.Contains(typeof(ServiceMetadataBehavior)) && ServiceMetadataBehavior.IsMetadataImplementedType(implementedContract)) { return ServiceMetadataBehavior.MexContractName; } DiagnosticUtility.DebugAssert("Calls to GetConfigKey are preceeded by calls to Contains."); #pragma warning suppress 56506 // implementedContract is never null at this point throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SfxReflectedContractKeyNotFound2, implementedContract.FullName, string.Empty))); } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- Parser.cs
- ListQueryResults.cs
- SQLRoleProvider.cs
- DbProviderServices.cs
- ColumnReorderedEventArgs.cs
- SelectedDatesCollection.cs
- DbParameterHelper.cs
- FixedSOMSemanticBox.cs
- XmlSecureResolver.cs
- SHA1CryptoServiceProvider.cs
- DataSourceHelper.cs
- ModelItem.cs
- SQLMoney.cs
- TextParagraph.cs
- PowerModeChangedEventArgs.cs
- CodeDOMProvider.cs
- ImageCodecInfo.cs
- JsonWriter.cs
- HashHelpers.cs
- ThemeInfoAttribute.cs
- PeerContact.cs
- StrongName.cs
- DependencyPropertyChangedEventArgs.cs
- TrackingMemoryStream.cs
- XmlWriterDelegator.cs
- RTTrackingProfile.cs
- SimpleHandlerBuildProvider.cs
- LZCodec.cs
- Configuration.cs
- TextServicesCompartment.cs
- peersecurityelement.cs
- Attributes.cs
- EllipticalNodeOperations.cs
- Transform3DCollection.cs
- Latin1Encoding.cs
- HttpCachePolicyElement.cs
- nulltextcontainer.cs
- HandleScope.cs
- HostProtectionPermission.cs
- XmlSchemaSequence.cs
- SerializerDescriptor.cs
- ListViewItemMouseHoverEvent.cs
- ContainerUIElement3D.cs
- SqlParameter.cs
- Terminate.cs
- ConfigPathUtility.cs
- TableCell.cs
- OutputChannel.cs
- WebPartConnectionCollection.cs
- ControllableStoryboardAction.cs
- PageContentAsyncResult.cs
- RMEnrollmentPage2.cs
- LicFileLicenseProvider.cs
- SpoolingTask.cs
- HandlerMappingMemo.cs
- Brushes.cs
- ObjectTag.cs
- PackageDigitalSignature.cs
- MSAANativeProvider.cs
- SystemColors.cs
- MaterializeFromAtom.cs
- ItemsPresenter.cs
- AudioStateChangedEventArgs.cs
- PropertySegmentSerializer.cs
- DataTemplate.cs
- SyndicationItemFormatter.cs
- XPathConvert.cs
- _ConnectStream.cs
- InternalTransaction.cs
- ProviderCommandInfoUtils.cs
- NeutralResourcesLanguageAttribute.cs
- DataGridRowsPresenter.cs
- DbReferenceCollection.cs
- TextShapeableCharacters.cs
- PopupControlService.cs
- DataListCommandEventArgs.cs
- ListSortDescription.cs
- NativeMethods.cs
- _SingleItemRequestCache.cs
- IisTraceWebEventProvider.cs
- LongValidatorAttribute.cs
- Form.cs
- AutomationEventArgs.cs
- MLangCodePageEncoding.cs
- StylusTip.cs
- PeerObject.cs
- MailAddress.cs
- ProfileInfo.cs
- EmbeddedMailObjectsCollection.cs
- InplaceBitmapMetadataWriter.cs
- StringAnimationBase.cs
- CodeTypeDelegate.cs
- TemplatedWizardStep.cs
- WebPartConnection.cs
- EntityProviderServices.cs
- SinglePhaseEnlistment.cs
- hresults.cs
- StatusBar.cs
- entitydatasourceentitysetnameconverter.cs
- ConnectorSelectionGlyph.cs