| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124 |
- //-----------------------------------------------------------------------------
- // Copyright (c) Microsoft Corporation. All rights reserved.
- //-----------------------------------------------------------------------------
- namespace System.ServiceModel
- {
- using System;
- using System.Collections.Generic;
- using System.Collections.ObjectModel;
- using System.ComponentModel;
- using System.Diagnostics;
- using System.Globalization;
- using System.Net;
- using System.Runtime;
- using System.Security;
- using System.ServiceModel.Administration;
- using System.ServiceModel.Channels;
- using System.ServiceModel.Configuration;
- using System.ServiceModel.Description;
- using System.ServiceModel.Diagnostics;
- using System.ServiceModel.Dispatcher;
- using System.Text;
- using System.Runtime.Diagnostics;
- using System.Threading;
- using System.ServiceModel.Activation;
- using System.ServiceModel.Diagnostics.Application;
- using System.Reflection;
- using System.Linq.Expressions;
- public abstract class ServiceHostBase : CommunicationObject, IExtensibleObject<ServiceHostBase>, 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<ServiceHostBase> extensions;
- ReadOnlyCollection<Uri> externalBaseAddresses;
- IDictionary<string, ContractDescription> implementedContracts;
- IInstanceContextManager instances;
- TimeSpan openTimeout = ServiceDefaults.OpenTimeout;
- ServicePerformanceCountersBase servicePerformanceCounters;
- DefaultPerformanceCounters defaultPerformanceCounters;
- ServiceThrottle serviceThrottle;
- ServiceCredentials readOnlyCredentials;
- ServiceAuthorizationBehavior readOnlyAuthorization;
- ServiceAuthenticationBehavior readOnlyAuthentication;
- Dictionary<DispatcherBuilder.ListenUriInfo, Collection<ServiceEndpoint>> endpointsByListenUriInfo;
- int busyCount;
- EventTraceActivity eventTraceActivity;
- internal event EventHandler BusyCountIncremented;
- public event EventHandler<UnknownMessageReceivedEventArgs> UnknownMessageReceived;
- protected ServiceHostBase()
- {
- TraceUtility.SetEtwProviderId();
- this.baseAddresses = new UriSchemeKeyedCollection(this.ThisLock);
- this.channelDispatchers = new ChannelDispatcherCollection(this, this.ThisLock);
- this.extensions = new ExtensionCollection<ServiceHostBase>(this, this.ThisLock);
- this.instances = new InstanceContextManager(this.ThisLock);
- this.serviceThrottle = new ServiceThrottle(this);
- this.TraceOpenAndClose = true;
- this.Faulted += new EventHandler(OnServiceHostFaulted);
- }
- internal EventTraceActivity EventTraceActivity
- {
- get
- {
- if (this.eventTraceActivity == null)
- {
- this.eventTraceActivity = new EventTraceActivity();
- }
- return eventTraceActivity;
- }
- }
- 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 ServiceAuthenticationBehavior Authentication
- {
- get
- {
- if (this.Description == null)
- {
- return null;
- }
- else if (this.State == CommunicationState.Created || this.State == CommunicationState.Opening)
- {
- return EnsureAuthentication(this.Description);
- }
- else
- {
- return this.readOnlyAuthentication;
- }
- }
- }
- public ReadOnlyCollection<Uri> BaseAddresses
- {
- get
- {
- externalBaseAddresses = new ReadOnlyCollection<Uri>(new List<Uri>(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 ServicePerformanceCountersBase Counters
- {
- get
- {
- return this.servicePerformanceCounters;
- }
- set
- {
- this.servicePerformanceCounters = value;
- this.serviceThrottle.SetServicePerformanceCounters(this.servicePerformanceCounters);
- }
- }
- 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<ServiceHostBase> Extensions
- {
- get { return this.extensions; }
- }
- protected internal IDictionary<string, ContractDescription> 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;
- }
- }
- internal Dictionary<DispatcherBuilder.ListenUriInfo, Collection<ServiceEndpoint>> EndpointsByListenUriInfo
- {
- get
- {
- if (this.endpointsByListenUriInfo == null)
- {
- this.endpointsByListenUriInfo = this.GetEndpointsByListenUriInfo();
- }
- return this.endpointsByListenUriInfo;
- }
- }
- Dictionary<DispatcherBuilder.ListenUriInfo, Collection<ServiceEndpoint>> GetEndpointsByListenUriInfo()
- {
- Dictionary<DispatcherBuilder.ListenUriInfo, Collection<ServiceEndpoint>> endpointDictionary = new Dictionary<DispatcherBuilder.ListenUriInfo, Collection<ServiceEndpoint>>();
- foreach (ServiceEndpoint endpoint in this.Description.Endpoints)
- {
- DispatcherBuilder.ListenUriInfo listenUriInfo = DispatcherBuilder.GetListenUriInfoForEndpoint(this, endpoint);
- if (!endpointDictionary.ContainsKey(listenUriInfo))
- {
- endpointDictionary.Add(listenUriInfo, new Collection<ServiceEndpoint>());
- }
- endpointDictionary[listenUriInfo].Add(endpoint);
- }
- return endpointDictionary;
- }
- 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)
- {
- endpoint.UnresolvedListenUri = listenUri;
- 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);
- serviceEndpoint.UnresolvedAddress = address;
- if (listenUri != null)
- {
- serviceEndpoint.UnresolvedListenUri = listenUri;
- listenUri = MakeAbsoluteUri(listenUri, binding);
- serviceEndpoint.ListenUri = listenUri;
- }
- return serviceEndpoint;
- }
- public virtual void AddServiceEndpoint(ServiceEndpoint endpoint)
- {
- if (endpoint == null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("endpoint");
- }
- 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)));
- }
- if (endpoint.Address == null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(SR.GetString(SR.SFxEndpointAddressNotSpecified));
- }
- if (endpoint.Contract == null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(SR.GetString(SR.SFxEndpointContractNotSpecified));
- }
- if (endpoint.Binding == null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(SR.GetString(SR.SFxEndpointBindingNotSpecified));
- }
- if (!endpoint.IsSystemEndpoint || endpoint.Contract.ContractType == typeof(IMetadataExchange))
- {
- ConfigLoader loader = new ConfigLoader(GetContractResolver(this.implementedContracts));
- loader.LookupContract(endpoint.Contract.ConfigurationName, this.Description.Name);
- }
- this.Description.Endpoints.Add(endpoint);
- }
- public void SetEndpointAddress(ServiceEndpoint endpoint, string relativeAddress)
- {
- if (endpoint == null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("endpoint");
- }
- if (relativeAddress == null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("relativeAddress");
- }
- if (endpoint.Binding == null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(SR.GetString(SR.SFxEndpointBindingNotSpecified));
- }
- Uri absoluteUri = MakeAbsoluteUri(new Uri(relativeAddress, UriKind.Relative), endpoint.Binding);
- endpoint.Address = new EndpointAddress(absoluteUri);
- }
- 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));
- // Call the overload of LoadConfigurationSectionInternal which looks up the serviceElement from ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None)
- LoadConfigurationSectionInternal(configLoader, this.Description, this.Description.ConfigurationName);
- EnsureAuthenticationAuthorizationDebug(this.Description);
- }
- internal void EnsureAuthenticationAuthorizationDebug(ServiceDescription description)
- {
- EnsureAuthentication(description);
- EnsureAuthorization(description);
- EnsureDebug(description);
- }
- public virtual ReadOnlyCollection<ServiceEndpoint> AddDefaultEndpoints()
- {
- List<ServiceEndpoint> defaultEndpoints = new List<ServiceEndpoint>();
- foreach (Uri baseAddress in this.InternalBaseAddresses)
- {
- ProtocolMappingItem protocolMappingItem = ConfigLoader.LookupProtocolMapping(baseAddress.Scheme);
- if (protocolMappingItem != null)
- {
- Binding defaultBinding = ConfigLoader.LookupBinding(protocolMappingItem.Binding, protocolMappingItem.BindingConfiguration);
- if (defaultBinding != null)
- {
- AddDefaultEndpoints(defaultBinding, defaultEndpoints);
- }
- else
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Exception(SR.GetString(SR.BindingProtocolMappingNotDefined, baseAddress.Scheme)));
- }
- }
- }
- if (DiagnosticUtility.ShouldTraceInformation && defaultEndpoints.Count > 0)
- {
- Dictionary<string, string> dictionary = new Dictionary<string, string>();
- dictionary["ServiceConfigurationName"] = this.description.ConfigurationName;
- TraceUtility.TraceEvent(TraceEventType.Information, TraceCode.DefaultEndpointsAdded, SR.GetString(SR.TraceCodeDefaultEndpointsAdded), new DictionaryTraceRecord(dictionary));
- }
- return new ReadOnlyCollection<ServiceEndpoint>(defaultEndpoints);
- }
- internal virtual void AddDefaultEndpoints(Binding defaultBinding, List<ServiceEndpoint> defaultEndpoints)
- {
- }
- 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<string, ContractDescription> implementedContracts);
- protected virtual void InitializeRuntime()
- {
- if (this.Description == null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxServiceHostBaseCannotInitializeRuntimeWithoutDescription)));
- }
- if (this.Description.Endpoints.Count == 0)
- {
- this.AddDefaultEndpoints();
- }
- this.EnsureAuthenticationSchemes();
- DispatcherBuilder dispatcherBuilder = new DispatcherBuilder();
- dispatcherBuilder.InitializeServiceHost(description, this);
- SecurityValidationBehavior.Instance.AfterBuildTimeValidation(description);
- }
- internal virtual void AfterInitializeRuntime(TimeSpan timeout)
- {
- }
- internal virtual IAsyncResult BeginAfterInitializeRuntime(TimeSpan timeout, AsyncCallback callback, object state)
- {
- return new CompletedAsyncResult(callback, state);
- }
- internal virtual void EndAfterInitializeRuntime(IAsyncResult result)
- {
- CompletedAsyncResult.End(result);
- }
- ServiceAuthorizationBehavior EnsureAuthorization(ServiceDescription description)
- {
- Fx.Assert(this.State == CommunicationState.Created || this.State == CommunicationState.Opening, "");
- ServiceAuthorizationBehavior a = description.Behaviors.Find<ServiceAuthorizationBehavior>();
- if (a == null)
- {
- a = new ServiceAuthorizationBehavior();
- description.Behaviors.Add(a);
- }
- return a;
- }
- ServiceAuthenticationBehavior EnsureAuthentication(ServiceDescription description)
- {
- Fx.Assert(this.State == CommunicationState.Created || this.State == CommunicationState.Opening, "");
- ServiceAuthenticationBehavior a = description.Behaviors.Find<ServiceAuthenticationBehavior>();
- if (a == null)
- {
- a = new ServiceAuthenticationBehavior();
- description.Behaviors.Add(a);
- }
- return a;
- }
- ServiceDebugBehavior EnsureDebug(ServiceDescription description)
- {
- Fx.Assert(this.State == CommunicationState.Created || this.State == CommunicationState.Opening, "");
- ServiceDebugBehavior m = description.Behaviors.Find<ServiceDebugBehavior>();
- if (m == null)
- {
- m = new ServiceDebugBehavior();
- description.Behaviors.Add(m);
- }
- return m;
- }
- ServiceCredentials EnsureCredentials(ServiceDescription description)
- {
- Fx.Assert(this.State == CommunicationState.Created || this.State == CommunicationState.Opening, "");
- ServiceCredentials c = description.Behaviors.Find<ServiceCredentials>();
- 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 BindingParameterCollection GetBindingParameters()
- {
- return DispatcherBuilder.GetBindingParameters(this, new Collection<ServiceEndpoint>());
- }
- internal BindingParameterCollection GetBindingParameters(ServiceEndpoint inputEndpoint)
- {
- Collection<ServiceEndpoint> endpoints;
- if (inputEndpoint == null)
- {
- endpoints = new Collection<ServiceEndpoint>();
- }
- else if (!this.EndpointsByListenUriInfo.TryGetValue(DispatcherBuilder.GetListenUriInfoForEndpoint(this, inputEndpoint), out endpoints) || !endpoints.Contains(inputEndpoint))
- {
- endpoints = new Collection<ServiceEndpoint>();
- endpoints.Add(inputEndpoint);
- }
- return DispatcherBuilder.GetBindingParameters(this, endpoints);
- }
- internal BindingParameterCollection GetBindingParameters(Collection<ServiceEndpoint> endpoints)
- {
- return DispatcherBuilder.GetBindingParameters(this, endpoints);
- }
- internal ReadOnlyCollection<InstanceContext> GetInstanceContexts()
- {
- return Array.AsReadOnly<InstanceContext>(this.instances.ToArray());
- }
- internal virtual IContractResolver GetContractResolver(IDictionary<string, ContractDescription> 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<string, ContractDescription> 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);
- }
- [Fx.Tag.SecurityNote(Critical = "Calls LookupService which is critical.",
- Safe = "Doesn't leak ServiceElement out of SecurityCritical code.")]
- [SecuritySafeCritical]
- void LoadConfigurationSectionInternal(ConfigLoader configLoader, ServiceDescription description, string configurationName)
- {
- ServiceElement serviceSection = configLoader.LookupService(configurationName);
- LoadConfigurationSectionInternal(configLoader, description, serviceSection);
- }
- [Fx.Tag.SecurityNote(Critical = "Handles a ServiceElement, which should not be leaked out of SecurityCritical code.",
- Safe = "Doesn't leak ServiceElement out of SecurityCritical code.")]
- [SecuritySafeCritical]
- void LoadConfigurationSectionInternal(ConfigLoader configLoader, ServiceDescription description, ServiceElement serviceSection)
- {
- // caller must validate arguments before calling
- configLoader.LoadServiceDescription(this, description, serviceSection, this.LoadConfigurationSectionHelper);
- }
- protected override void OnAbort()
- {
- this.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 override IAsyncResult OnBeginClose(TimeSpan timeout, AsyncCallback callback, object state)
- {
- return new CloseAsyncResult(timeout, callback, state, this);
- }
- void OnBeginOpen()
- {
- this.TraceServiceHostOpenStart();
- this.TraceBaseAddresses();
- MessageLogger.EnsureInitialized(); //force config validation instead of waiting for the first message exchange
- InitializeRuntime();
- }
- protected override IAsyncResult OnBeginOpen(TimeSpan timeout, AsyncCallback callback, object state)
- {
- this.OnBeginOpen();
- return new OpenAsyncResult(this, timeout, callback, state);
- }
- IAsyncResult BeginOpenChannelDispatchers(TimeSpan timeout, AsyncCallback callback, object state)
- {
- 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(timeoutHelper.RemainingTime());
- }
- // Wait for existing work to complete
- this.instances.CloseInput(timeoutHelper.RemainingTime());
- // Close instances (closes contexts/channels)
- this.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 (TD.CloseTimeoutIsEnabled())
- {
- TD.CloseTimeout(SR.GetString(SR.TraceCodeServiceHostTimeoutOnClose));
- }
- if (DiagnosticUtility.ShouldTraceWarning)
- {
- TraceUtility.TraceEvent(TraceEventType.Warning, TraceCode.ServiceHostTimeoutOnClose, SR.GetString(SR.TraceCodeServiceHostTimeoutOnClose), this, e);
- }
- this.Abort();
- }
- }
- protected override void OnClosed()
- {
- try
- {
- for (int i = 0; i < this.ChannelDispatchers.Count; i++)
- {
- ChannelDispatcher dispatcher = this.ChannelDispatchers[i] as ChannelDispatcher;
- if (dispatcher != null)
- {
- dispatcher.ReleasePerformanceCounters();
- }
- }
- }
- finally
- {
- base.OnClosed();
- }
- }
- void TraceBaseAddresses()
- {
- if (DiagnosticUtility.ShouldTraceInformation && this.baseAddresses != null
- && this.baseAddresses.Count > 0)
- {
- TraceUtility.TraceEvent(TraceEventType.Information,
- TraceCode.ServiceHostBaseAddresses,
- SR.GetString(SR.TraceCodeServiceHostBaseAddresses),
- new CollectionTraceRecord("BaseAddresses", "Address", this.baseAddresses),
- this, null);
- }
- }
- void TraceServiceHostOpenStart()
- {
- if (TD.ServiceHostOpenStartIsEnabled())
- {
- TD.ServiceHostOpenStart(this.EventTraceActivity);
- }
- }
- protected override void OnEndClose(IAsyncResult result)
- {
- try
- {
- CloseAsyncResult.End(result);
- this.TraceBaseAddresses();
- ThreadTrace.StopTracing();
- }
- catch (TimeoutException e)
- {
- if (TD.CloseTimeoutIsEnabled())
- {
- TD.CloseTimeout(SR.GetString(SR.TraceCodeServiceHostTimeoutOnClose));
- }
- if (DiagnosticUtility.ShouldTraceWarning)
- {
- TraceUtility.TraceEvent(TraceEventType.Warning, TraceCode.ServiceHostTimeoutOnClose,
- SR.GetString(SR.TraceCodeServiceHostTimeoutOnClose), this, e);
- }
- this.Abort();
- }
- }
- protected override void OnEndOpen(IAsyncResult result)
- {
- OpenAsyncResult.End(result);
- }
- void EndOpenChannelDispatchers(IAsyncResult result)
- {
- OpenCollectionAsyncResult.End(result);
- }
- void EnsureAuthenticationSchemes()
- {
- if (this.Authentication == null)
- {
- return;
- }
- //Exit immediately when not hosted in IIS or if VirtualPathExtension is not set. VirtualPathExtension is used as a flag to indicate whether a ServiceHost
- // is webhosted (WsDualHttpBinding-ChannelFactory is using HttpListener instead of IIS even when running in IIS)
- if (!AspNetEnvironment.Enabled ||
- this.Extensions.Find<VirtualPathExtension>() == null)
- {
- return;
- }
- foreach (ServiceEndpoint serviceEndpoint in this.Description.Endpoints)
- {
- if (serviceEndpoint.Binding != null &&
- serviceEndpoint.ListenUri != null &&
- ("http".Equals(serviceEndpoint.ListenUri.Scheme, StringComparison.OrdinalIgnoreCase) || "https".Equals(serviceEndpoint.ListenUri.Scheme, StringComparison.OrdinalIgnoreCase)) &&
- this.baseAddresses.Contains(serviceEndpoint.ListenUri.Scheme))
- {
- HttpTransportBindingElement httpTransportBindingElement = serviceEndpoint.Binding.CreateBindingElements().Find<HttpTransportBindingElement>();
- if (httpTransportBindingElement != null)
- {
- AuthenticationSchemes hostSupportedAuthenticationSchemes = AspNetEnvironment.Current.GetAuthenticationSchemes(this.baseAddresses[serviceEndpoint.ListenUri.Scheme]);
- if (hostSupportedAuthenticationSchemes != AuthenticationSchemes.None)
- {
- //If no authentication schemes are explicitly defined for the ServiceHost...
- if (this.Authentication.AuthenticationSchemes == AuthenticationSchemes.None)
- {
- //Inherit authentication schemes from IIS
- this.Authentication.AuthenticationSchemes = hostSupportedAuthenticationSchemes;
- }
- else
- {
- // Build intersection between authenticationSchemes on the ServiceHost and in IIS
- this.Authentication.AuthenticationSchemes &= hostSupportedAuthenticationSchemes;
- }
- }
- }
- break;
- }
- }
- }
- protected override void OnOpen(TimeSpan timeout)
- {
- TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);
- this.OnBeginOpen();
- AfterInitializeRuntime(timeoutHelper.RemainingTime());
- for (int i = 0; i < this.ChannelDispatchers.Count; i++)
- {
- ChannelDispatcherBase dispatcher = this.ChannelDispatchers[i];
- dispatcher.Open(timeoutHelper.RemainingTime());
- }
- }
- protected override void OnOpened()
- {
- if (this.Description != null)
- {
- ServiceCredentials c = description.Behaviors.Find<ServiceCredentials>();
- if (c != null)
- {
- ServiceCredentials credentialsCopy = c.Clone();
- credentialsCopy.MakeReadOnly();
- this.readOnlyCredentials = credentialsCopy;
- }
- ServiceAuthorizationBehavior authorization = description.Behaviors.Find<ServiceAuthorizationBehavior>();
- if (authorization != null)
- {
- ServiceAuthorizationBehavior authorizationCopy = authorization.Clone();
- authorizationCopy.MakeReadOnly();
- this.readOnlyAuthorization = authorizationCopy;
- }
- ServiceAuthenticationBehavior authentication = description.Behaviors.Find<ServiceAuthenticationBehavior>();
- if (authentication != null)
- {
- ServiceAuthenticationBehavior authenticationCopy = authentication.Clone();
- authentication.MakeReadOnly();
- this.readOnlyAuthentication = authenticationCopy;
- }
- if (ManagementExtension.IsEnabled)
- {
- ManagementExtension.OnServiceOpened(this);
- }
- }
- base.OnOpened();
- if (TD.ServiceHostOpenStopIsEnabled())
- {
- TD.ServiceHostOpenStop(this.EventTraceActivity);
- }
- }
- 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 (TD.ServiceHostFaultedIsEnabled())
- {
- TD.ServiceHostFaulted(this.EventTraceActivity, this);
- }
- if (DiagnosticUtility.ShouldTraceWarning)
- {
- TraceUtility.TraceEvent(TraceEventType.Warning, TraceCode.ServiceHostFaulted,
- SR.GetString(SR.TraceCodeServiceHostFaulted), this);
- }
- foreach (ICommunicationObject channelDispatcher in this.SnapshotChannelDispatchers())
- {
- if (channelDispatcher.State == CommunicationState.Opened)
- {
- channelDispatcher.Abort();
- }
- }
- }
- internal void RaiseUnknownMessageReceived(Message message)
- {
- try
- {
- EventHandler<UnknownMessageReceivedEventArgs> handler = UnknownMessageReceived;
- if (handler != null)
- {
- handler(this, new UnknownMessageReceivedEventArgs(message));
- }
- }
- catch (Exception e)
- {
- if (Fx.IsFatal(e))
- throw;
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperCallback(e);
- }
- }
- protected void ReleasePerformanceCounters()
- {
- if (this.servicePerformanceCounters != null)
- {
- lock (this.ThisLock)
- {
- if (this.servicePerformanceCounters != null)
- {
- this.servicePerformanceCounters.Dispose();
- this.servicePerformanceCounters = null;
- }
- }
- }
- if (this.defaultPerformanceCounters != null)
- {
- lock (this.ThisLock)
- {
- if (this.defaultPerformanceCounters != null)
- {
- this.defaultPerformanceCounters.Dispose();
- this.defaultPerformanceCounters = null;
- }
- }
- }
- }
- ICommunicationObject[] SnapshotChannelDispatchers()
- {
- lock (this.ThisLock)
- {
- ICommunicationObject[] array = new ICommunicationObject[this.ChannelDispatchers.Count];
- for (int i = 0; i < array.Length; i++)
- {
- array[i] = this.ChannelDispatchers[i];
- }
- return array;
- }
- }
- internal virtual void UnbindInstance(InstanceContext instance)
- {
- this.instances.Remove(instance);
- if (null != this.servicePerformanceCounters)
- {
- lock (this.ThisLock)
- {
- if (null != this.servicePerformanceCounters)
- {
- this.servicePerformanceCounters.ServiceInstanceRemoved();
- }
- }
- }
- }
- internal void IncrementBusyCount()
- {
- if (AspNetEnvironment.Enabled)
- {
- AspNetEnvironment.Current.IncrementBusyCount();
- Interlocked.Increment(ref this.busyCount);
- }
- EventHandler handler = this.BusyCountIncremented;
- if (handler != null)
- {
- try
- {
- handler(this, EventArgs.Empty);
- }
- catch (Exception exception)
- {
- if (Fx.IsFatal(exception))
- throw;
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperCallback(exception);
- }
- }
- }
- internal void DecrementBusyCount()
- {
- if (AspNetEnvironment.Enabled)
- {
- Interlocked.Decrement(ref this.busyCount);
- AspNetEnvironment.Current.DecrementBusyCount();
- }
- }
- internal int BusyCount
- {
- get
- {
- return this.busyCount;
- }
- }
- class OpenAsyncResult : AsyncResult
- {
- static AsyncCompletion handleEndAfterInitializeRuntime = new AsyncCompletion(HandleEndAfterInitializeRuntime);
- static AsyncCompletion handleEndOpenChannelDispatchers = new AsyncCompletion(HandleEndOpenChannelDispatchers);
- TimeoutHelper timeoutHelper;
- ServiceHostBase host;
- public OpenAsyncResult(ServiceHostBase host, TimeSpan timeout, AsyncCallback callback, object state)
- : base(callback, state)
- {
- this.timeoutHelper = new TimeoutHelper(timeout);
- this.host = host;
- if (ProcessAfterInitializeRuntime())
- {
- Complete(true);
- }
- }
- bool ProcessAfterInitializeRuntime()
- {
- IAsyncResult result = this.host.BeginAfterInitializeRuntime(
- this.timeoutHelper.RemainingTime(), PrepareAsyncCompletion(handleEndAfterInitializeRuntime), this);
- return SyncContinue(result);
- }
- static bool HandleEndAfterInitializeRuntime(IAsyncResult result)
- {
- OpenAsyncResult thisPtr = (OpenAsyncResult)result.AsyncState;
- thisPtr.host.EndAfterInitializeRuntime(result);
- return thisPtr.ProcessOpenChannelDispatchers();
- }
- bool ProcessOpenChannelDispatchers()
- {
- IAsyncResult result = this.host.BeginOpenChannelDispatchers(
- this.timeoutHelper.RemainingTime(), PrepareAsyncCompletion(handleEndOpenChannelDispatchers), this);
- return SyncContinue(result);
- }
- static bool HandleEndOpenChannelDispatchers(IAsyncResult result)
- {
- OpenAsyncResult thisPtr = (OpenAsyncResult)result.AsyncState;
- thisPtr.host.EndOpenChannelDispatchers(result);
- return true;
- }
- public static void End(IAsyncResult result)
- {
- AsyncResult.End<OpenAsyncResult>(result);
- }
- }
- class CloseAsyncResult : AsyncResult
- {
- ServiceHostBase serviceHost;
- TimeoutHelper timeoutHelper;
- public CloseAsyncResult(TimeSpan timeout, AsyncCallback callback, object state, ServiceHostBase serviceHost)
- : base(callback, state)
- {
- this.timeoutHelper = new TimeoutHelper(timeout);
- this.serviceHost = serviceHost;
- if (ManagementExtension.IsEnabled && null != serviceHost.Description)
- {
- ManagementExtension.OnServiceClosing(serviceHost);
- }
- this.CloseListeners(true);
- }
- void CloseListeners(bool completedSynchronously)
- {
- List<ICommunicationObject> listeners = new List<ICommunicationObject>();
- for (int i = 0; i < this.serviceHost.ChannelDispatchers.Count; i++)
- {
- if (this.serviceHost.ChannelDispatchers[i].Listener != null)
- {
- listeners.Add(this.serviceHost.ChannelDispatchers[i].Listener);
- }
- }
- AsyncCallback callback = Fx.ThunkCallback(this.CloseListenersCallback);
- TimeSpan timeout = this.timeoutHelper.RemainingTime();
- Exception exception = null;
- IAsyncResult result = null;
- try
- {
- result = new CloseCollectionAsyncResult(timeout, callback, this, listeners);
- }
- catch (Exception e)
- {
- if (Fx.IsFatal(e) || completedSynchronously)
- {
- throw;
- }
- exception = e;
- }
- if (exception != null)
- {
- this.CallComplete(completedSynchronously, exception);
- }
- else if (result.CompletedSynchronously)
- {
- this.FinishCloseListeners(result, completedSynchronously);
- }
- }
- void CloseListenersCallback(IAsyncResult result)
- {
- if (!result.CompletedSynchronously)
- {
- ((CloseAsyncResult)result.AsyncState).FinishCloseListeners(result, false);
- }
- }
- void FinishCloseListeners(IAsyncResult result, bool completedSynchronously)
- {
- Exception exception = null;
- try
- {
- CloseCollectionAsyncResult.End(result);
- }
- catch (Exception e)
- {
- if (Fx.IsFatal(e) || completedSynchronously)
- {
- throw;
- }
- exception = e;
- }
- if (exception != null)
- {
- this.CallComplete(completedSynchronously, exception);
- }
- else
- {
- this.CloseInput(completedSynchronously);
- }
- }
- // Wait for existing work to complete
- void CloseInput(bool completedSynchronously)
- {
- AsyncCallback callback = Fx.ThunkCallback(this.CloseInputCallback);
- Exception exception = null;
- IAsyncResult result = null;
- try
- {
- for (int i = 0; i < this.serviceHost.ChannelDispatchers.Count; i++)
- {
- ChannelDispatcherBase dispatcher = this.serviceHost.ChannelDispatchers[i];
- dispatcher.CloseInput(this.timeoutHelper.RemainingTime());
- }
- result = this.serviceHost.instances.BeginCloseInput(this.timeoutHelper.RemainingTime(), callback, this);
- }
- catch (Exception e)
- {
- if (Fx.IsFatal(e) || completedSynchronously)
- {
- throw;
- }
- exception = e;
- }
- if (exception != null)
- {
- // Any exception during async processing causes this
- // async callback to report the error and then relies on
- // Abort to cleanup any unclosed channels or instance contexts.
- FxTrace.Exception.AsWarning(exception);
- this.CallComplete(completedSynchronously, exception);
- }
- else if (result.CompletedSynchronously)
- {
- this.FinishCloseInput(result, completedSynchronously);
- }
- }
- void CloseInputCallback(IAsyncResult result)
- {
- if (!result.CompletedSynchronously)
- {
- ((CloseAsyncResult)result.AsyncState).FinishCloseInput(result, false);
- }
- }
- void FinishCloseInput(IAsyncResult result, bool completedSynchronously)
- {
- Exception exception = null;
- try
- {
- serviceHost.instances.EndCloseInput(result);
- }
- catch (Exception e)
- {
- if (Fx.IsFatal(e) || completedSynchronously)
- {
- throw;
- }
- exception = e;
- }
- if (exception != null)
- {
- this.CallComplete(completedSynchronously, exception);
- }
- else
- {
- this.CloseInstances(completedSynchronously);
- }
- }
- // Close instances (closes contexts/channels)
- void CloseInstances(bool completedSynchronously)
- {
- AsyncCallback callback = Fx.ThunkCallback(this.CloseInstancesCallback);
- TimeSpan timeout = this.timeoutHelper.RemainingTime();
- Exception exception = null;
- IAsyncResult result = null;
- try
- {
- result = this.serviceHost.instances.BeginClose(timeout, callback, this);
- }
- catch (Exception e)
- {
- if (Fx.IsFatal(e) || completedSynchronously)
- {
- throw;
- }
- exception = e;
- }
- if (exception != null)
- {
- this.CallComplete(completedSynchronously, exception);
- }
- else if (result.CompletedSynchronously)
- {
- this.FinishCloseInstances(result, completedSynchronously);
- }
- }
- void CloseInstancesCallback(IAsyncResult result)
- {
- if (!result.CompletedSynchronously)
- {
- ((CloseAsyncResult)result.AsyncState).FinishCloseInstances(result, false);
- }
- }
- void FinishCloseInstances(IAsyncResult result, bool completedSynchronously)
- {
- Exception exception = null;
- try
- {
- this.serviceHost.instances.EndClose(result);
- }
- catch (Exception e)
- {
- if (Fx.IsFatal(e) || completedSynchronously)
- {
- throw;
- }
- exception = e;
- }
- if (exception != null)
- {
- this.CallComplete(completedSynchronously, exception);
- }
- else
- {
- this.CloseChannelDispatchers(completedSynchronously);
- }
- }
- void CloseChannelDispatchers(bool completedSynchronously)
- {
- IList<ICommunicationObject> channelDispatchers = this.serviceHost.SnapshotChannelDispatchers();
- AsyncCallback callback = Fx.ThunkCallback(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 (Fx.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 (Fx.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<CloseAsyncResult>(result);
- }
- }
- class ImplementedContractsContractResolver : IContractResolver
- {
- IDictionary<string, ContractDescription> implementedContracts;
- public ImplementedContractsContractResolver(IDictionary<string, ContractDescription> 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<string, ContractDescription> behaviorContracts;
- public Dictionary<string, ContractDescription> BehaviorContracts
- {
- get { return behaviorContracts; }
- }
- public ServiceAndBehaviorsContractResolver(IContractResolver serviceResolver)
- {
- this.serviceResolver = serviceResolver;
- behaviorContracts = new Dictionary<string, ContractDescription>();
- }
- 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<IServiceBehavior> behaviors)
- {
- // It would be nice to make this loop over all Behaviors... someday.
- if (behaviors != null && behaviors.Contains(typeof(ServiceMetadataBehavior)))
- {
- behaviors.Find<ServiceMetadataBehavior>().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);
- }
- void ValidateContractType(Type implementedContract, ReflectedAndBehaviorContractCollection reflectedAndBehaviorContracts)
- {
- 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 (!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)));
- }
- }
- public ServiceEndpoint AddServiceEndpoint(Type implementedContract, Binding binding, Uri address, Uri listenUri)
- {
- if (implementedContract == null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("implementedContract"));
- }
- 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);
- ValidateContractType(implementedContract, reflectedAndBehaviorContracts);
- ServiceEndpoint endpoint = AddServiceEndpoint(reflectedAndBehaviorContracts.GetConfigKey(implementedContract), binding, address);
- if (listenUri != null)
- {
- listenUri = MakeAbsoluteUri(listenUri, binding);
- endpoint.ListenUri = listenUri;
- }
- return endpoint;
- }
- internal override void AddDefaultEndpoints(Binding defaultBinding, List<ServiceEndpoint> defaultEndpoints)
- {
- // don't generate endpoints for contracts that serve as the base type for other reflected contracts
- List<ContractDescription> mostSpecificContracts = new List<ContractDescription>();
- for (int i = 0; i < this.reflectedContracts.Count; i++)
- {
- bool addContractEndpoint = true;
- ContractDescription contract = this.reflectedContracts[i];
- Type contractType = contract.ContractType;
- if (contractType != null)
- {
- for (int j = 0; j < this.reflectedContracts.Count; j++)
- {
- ContractDescription otherContract = this.reflectedContracts[j];
- Type otherContractType = otherContract.ContractType;
- if (i == j || otherContractType == null)
- {
- continue;
- }
- if (contractType.IsAssignableFrom(otherContractType))
- {
- addContractEndpoint = false;
- break;
- }
- }
- }
- if (addContractEndpoint)
- {
- mostSpecificContracts.Add(contract);
- }
- }
- foreach (ContractDescription contract in mostSpecificContracts)
- {
- ServiceEndpoint endpoint = AddServiceEndpoint(contract.ConfigurationName, defaultBinding, string.Empty);
- ConfigLoader.LoadDefaultEndpointBehaviors(endpoint);
- defaultEndpoints.Add(endpoint);
- }
- }
- // Run static Configure method on service type if it exists, else load configuration from Web.config/App.config
- protected override void ApplyConfiguration()
- {
- // Load from static Configure method if it exists with the right signature
- Type serviceType = this.Description.ServiceType;
- if (serviceType != null)
- {
- MethodInfo configure = GetConfigureMethod(serviceType);
- if (configure != null)
- {
- // load <host> config
- ConfigLoader configLoader = new ConfigLoader(GetContractResolver(this.ImplementedContracts));
- LoadHostConfigurationInternal(configLoader, this.Description, this.Description.ConfigurationName);
- // Invoke configure method for service
- ServiceConfiguration configuration = new ServiceConfiguration(this);
- InvokeConfigure(configure, configuration);
- return;
- }
- }
- // else just load from Web.config/App.config
- base.ApplyConfiguration();
- }
- // Find the Configure method with the required signature, closest to serviceType in the type hierarchy
- static MethodInfo GetConfigureMethod(Type serviceType)
- {
- // Use recursion instead of BindingFlags.FlattenHierarchy because we require return type to be void
-
- // base case: all Types are rooted in object eventually
- if (serviceType == typeof(object))
- {
- return null;
- }
- // signature: "public static void Configure(ServiceConfiguration)"
- MethodInfo configure = serviceType.GetMethod("Configure", BindingFlags.Static | BindingFlags.Public, null, new[] { typeof(ServiceConfiguration) }, null);
- if (configure != null && configure.ReturnType == typeof(void))
- {
- return configure;
- }
- else
- {
- return GetConfigureMethod(serviceType.BaseType);
- }
- }
- static void InvokeConfigure(MethodInfo configureMethod, ServiceConfiguration configuration)
- {
- Action<ServiceConfiguration> call = Delegate.CreateDelegate(typeof(Action<ServiceConfiguration>), configureMethod) as Action<ServiceConfiguration>;
- call(configuration);
- }
- // called from ServiceConfiguration.LoadFromConfiguration()
- internal void LoadFromConfiguration()
- {
- if (this.Description == null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxServiceHostBaseCannotApplyConfigurationWithoutDescription)));
- }
- ConfigLoader configLoader = new ConfigLoader(GetContractResolver(this.ImplementedContracts));
- // Call the overload of LoadConfigurationSectionInternal which looks up the serviceElement from ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None)
- LoadConfigurationSectionExceptHostInternal(configLoader, this.Description, this.Description.ConfigurationName);
- EnsureAuthenticationAuthorizationDebug(this.Description);
- }
- // called from ServiceConfiguration.LoadFromConfiguration(configuration)
- internal void LoadFromConfiguration(System.Configuration.Configuration configuration)
- {
- if (this.Description == null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxServiceHostBaseCannotApplyConfigurationWithoutDescription)));
- }
- ConfigLoader configLoader = new ConfigLoader(GetContractResolver(this.ImplementedContracts));
- // Look up the serviceElement explicitly on configuration, then call the overload of LoadConfigurationSectionInternal that loads the rest of the config from the same configuration as serviceElement
- ServicesSection servicesSection = (ServicesSection)configuration.GetSection(ConfigurationStrings.ServicesSectionPath);
- ServiceElement serviceElement = configLoader.LookupService(this.Description.ConfigurationName, servicesSection);
- configLoader.LoadServiceDescription(this, this.Description, serviceElement, this.LoadConfigurationSectionHelper, skipHost: true);
- EnsureAuthenticationAuthorizationDebug(this.Description);
- }
- // Load only "host" section within "service" tag
- [Fx.Tag.SecurityNote(Critical = "Calls LookupService which is critical.",
- Safe = "Doesn't leak ServiceElement out of SecurityCritical code.")]
- [SecuritySafeCritical]
- void LoadHostConfigurationInternal(ConfigLoader configLoader, ServiceDescription description, string configurationName)
- {
- ServiceElement serviceSection = configLoader.LookupService(configurationName);
- if (serviceSection != null)
- {
- configLoader.LoadHostConfig(serviceSection, this, (addr => this.InternalBaseAddresses.Add(addr)));
- }
- }
- // Load service description for service from config, but skip "host" section within "service" tag
- [Fx.Tag.SecurityNote(Critical = "Calls LookupService which is critical.",
- Safe = "Doesn't leak ServiceElement out of SecurityCritical code.")]
- [SecuritySafeCritical]
- void LoadConfigurationSectionExceptHostInternal(ConfigLoader configLoader, ServiceDescription description, string configurationName)
- {
- ServiceElement serviceSection = configLoader.LookupService(configurationName);
- configLoader.LoadServiceDescription(this, description, serviceSection, this.LoadConfigurationSectionHelper, skipHost: true);
- }
-
- 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<string, ContractDescription> 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<ServiceBehaviorAttribute>();
- 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<Type> 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<ContractDescription> 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<Type, ContractDescription>
- {
- public ReflectedContractCollection()
- : base(null, 4)
- {
- }
- protected override Type GetKeyForItem(ContractDescription item)
- {
- if (item == null)
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("item");
- return item.ContractType;
- }
- public IDictionary<string, ContractDescription> ToImplementedContracts()
- {
- Dictionary<string, ContractDescription> implementedContracts = new Dictionary<string, ContractDescription>();
- 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<IServiceBehavior> behaviors;
- public ReflectedAndBehaviorContractCollection(ReflectedContractCollection reflectedContracts, KeyedByTypeCollection<IServiceBehavior> 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;
- }
- Fx.Assert("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)));
- }
- }
- }
- }
|