| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480 |
- //------------------------------------------------------------
- // Copyright (c) Microsoft Corporation. All rights reserved.
- //------------------------------------------------------------
- namespace System.ServiceModel
- {
- using System.ServiceModel.Administration;
- using System.ServiceModel.Channels;
- using System.ServiceModel.Dispatcher;
- using System.ServiceModel.Description;
- using System.ServiceModel.Configuration;
- using System.Runtime.Serialization;
- using System.Collections.ObjectModel;
- using System.Collections.Generic;
- using System.Threading;
- using System.Transactions;
- using System.Runtime.CompilerServices;
- using System.ComponentModel;
- using System.Globalization;
- [AttributeUsage(ServiceModelAttributeTargets.ServiceBehavior)]
- public sealed class ServiceBehaviorAttribute : Attribute, IServiceBehavior
- {
- internal static IsolationLevel DefaultIsolationLevel = IsolationLevel.Unspecified;
- ConcurrencyMode concurrencyMode = ConcurrencyMode.Single;
- bool ensureOrderedDispatch = false;
- string configurationName;
- bool includeExceptionDetailInFaults = false;
- InstanceContextMode instanceMode;
- bool releaseServiceInstanceOnTransactionComplete = true;
- bool releaseServiceInstanceOnTransactionCompleteSet = false;
- bool transactionAutoCompleteOnSessionClose = false;
- bool transactionAutoCompleteOnSessionCloseSet = false;
- object wellKnownSingleton = null; // if the user passes an object to the ServiceHost, it is stored here
- object hiddenSingleton = null; // if the user passes a type to the ServiceHost, and instanceMode==Single, we store the instance here
- bool validateMustUnderstand = true;
- bool ignoreExtensionDataObject = DataContractSerializerDefaults.IgnoreExtensionDataObject;
- int maxItemsInObjectGraph = DataContractSerializerDefaults.MaxItemsInObjectGraph;
- IsolationLevel transactionIsolationLevel = DefaultIsolationLevel;
- bool isolationLevelSet = false;
- bool automaticSessionShutdown = true;
- IInstanceProvider instanceProvider = null;
- TimeSpan transactionTimeout = TimeSpan.Zero;
- string transactionTimeoutString;
- bool transactionTimeoutSet = false;
- bool useSynchronizationContext = true;
- string serviceName = null;
- string serviceNamespace = null;
- AddressFilterMode addressFilterMode = AddressFilterMode.Exact;
- [DefaultValue(null)]
- public string Name
- {
- get { return serviceName; }
- set { serviceName = value; }
- }
- [DefaultValue(null)]
- public string Namespace
- {
- get { return serviceNamespace; }
- set { serviceNamespace = value; }
- }
- internal IInstanceProvider InstanceProvider
- {
- set { this.instanceProvider = value; }
- }
- [DefaultValue(AddressFilterMode.Exact)]
- public AddressFilterMode AddressFilterMode
- {
- get { return this.addressFilterMode; }
- set
- {
- if (!AddressFilterModeHelper.IsDefined(value))
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("value"));
- }
- this.addressFilterMode = value;
- }
- }
- [DefaultValue(true)]
- public bool AutomaticSessionShutdown
- {
- get { return this.automaticSessionShutdown; }
- set { this.automaticSessionShutdown = value; }
- }
- [DefaultValue(null)]
- public string ConfigurationName
- {
- get { return this.configurationName; }
- set
- {
- if (value == null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("value");
- }
- if (value == string.Empty)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("value",
- SR.GetString(SR.SFxConfigurationNameCannotBeEmpty)));
- }
- this.configurationName = value;
- }
- }
- public IsolationLevel TransactionIsolationLevel
- {
- get { return this.transactionIsolationLevel; }
- set
- {
- switch (value)
- {
- case IsolationLevel.Serializable:
- case IsolationLevel.RepeatableRead:
- case IsolationLevel.ReadCommitted:
- case IsolationLevel.ReadUncommitted:
- case IsolationLevel.Unspecified:
- case IsolationLevel.Chaos:
- case IsolationLevel.Snapshot:
- break;
- default:
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("value"));
- }
- this.transactionIsolationLevel = value;
- isolationLevelSet = true;
- }
- }
- public bool ShouldSerializeTransactionIsolationLevel()
- {
- return IsolationLevelSet;
- }
- internal bool IsolationLevelSet
- {
- get { return this.isolationLevelSet; }
- }
- [DefaultValue(false)]
- public bool IncludeExceptionDetailInFaults
- {
- get { return this.includeExceptionDetailInFaults; }
- set { this.includeExceptionDetailInFaults = value; }
- }
- [DefaultValue(ConcurrencyMode.Single)]
- public ConcurrencyMode ConcurrencyMode
- {
- get { return this.concurrencyMode; }
- set
- {
- if (!ConcurrencyModeHelper.IsDefined(value))
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("value"));
- }
- this.concurrencyMode = value;
- }
- }
- [DefaultValue(false)]
- public bool EnsureOrderedDispatch
- {
- get { return this.ensureOrderedDispatch; }
- set { this.ensureOrderedDispatch = value; }
- }
- [DefaultValue(InstanceContextMode.PerSession)]
- public InstanceContextMode InstanceContextMode
- {
- get { return this.instanceMode; }
- set
- {
- if (!InstanceContextModeHelper.IsDefined(value))
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("value"));
- }
- this.instanceMode = value;
- }
- }
- public bool ReleaseServiceInstanceOnTransactionComplete
- {
- get { return releaseServiceInstanceOnTransactionComplete; }
- set
- {
- this.releaseServiceInstanceOnTransactionComplete = value;
- this.releaseServiceInstanceOnTransactionCompleteSet = true;
- }
- }
- public bool ShouldSerializeConfigurationName()
- {
- return this.configurationName != null;
- }
- public bool ShouldSerializeReleaseServiceInstanceOnTransactionComplete()
- {
- return ReleaseServiceInstanceOnTransactionCompleteSet;
- }
- internal bool ReleaseServiceInstanceOnTransactionCompleteSet
- {
- get { return this.releaseServiceInstanceOnTransactionCompleteSet; }
- }
- public bool TransactionAutoCompleteOnSessionClose
- {
- get { return transactionAutoCompleteOnSessionClose; }
- set
- {
- this.transactionAutoCompleteOnSessionClose = value;
- this.transactionAutoCompleteOnSessionCloseSet = true;
- }
- }
- public bool ShouldSerializeTransactionAutoCompleteOnSessionClose()
- {
- return TransactionAutoCompleteOnSessionCloseSet;
- }
- internal bool TransactionAutoCompleteOnSessionCloseSet
- {
- get { return this.transactionAutoCompleteOnSessionCloseSet; }
- }
- public string TransactionTimeout
- {
- get { return transactionTimeoutString; }
- set
- {
- if (value == null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("value"));
- }
- try
- {
- TimeSpan timeout = TimeSpan.Parse(value, CultureInfo.InvariantCulture);
- if (timeout < TimeSpan.Zero)
- {
- string message = SR.GetString(SR.SFxTimeoutOutOfRange0);
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("value", value, message));
- }
- this.transactionTimeout = timeout;
- this.transactionTimeoutString = value;
- this.transactionTimeoutSet = true;
- }
- catch (FormatException e)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.SFxTimeoutInvalidStringFormat), "value", e));
- }
- catch (OverflowException)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("value"));
- }
- }
- }
- public bool ShouldSerializeTransactionTimeout()
- {
- return TransactionTimeoutSet;
- }
- internal TimeSpan TransactionTimeoutTimespan
- {
- get { return this.transactionTimeout; }
- }
- internal bool TransactionTimeoutSet
- {
- get { return this.transactionTimeoutSet; }
- }
- [DefaultValue(true)]
- public bool ValidateMustUnderstand
- {
- get { return validateMustUnderstand; }
- set { validateMustUnderstand = value; }
- }
- [DefaultValue(DataContractSerializerDefaults.IgnoreExtensionDataObject)]
- public bool IgnoreExtensionDataObject
- {
- get { return ignoreExtensionDataObject; }
- set { ignoreExtensionDataObject = value; }
- }
- [DefaultValue(DataContractSerializerDefaults.MaxItemsInObjectGraph)]
- public int MaxItemsInObjectGraph
- {
- get { return maxItemsInObjectGraph; }
- set { maxItemsInObjectGraph = value; }
- }
- [DefaultValue(true)]
- public bool UseSynchronizationContext
- {
- get { return this.useSynchronizationContext; }
- set { this.useSynchronizationContext = value; }
- }
- public object GetWellKnownSingleton()
- {
- return this.wellKnownSingleton;
- }
- public void SetWellKnownSingleton(object value)
- {
- if (value == null)
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("value");
- this.wellKnownSingleton = value;
- }
- internal object GetHiddenSingleton()
- {
- return this.hiddenSingleton;
- }
- internal void SetHiddenSingleton(object value)
- {
- if (value == null)
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("value");
- this.hiddenSingleton = value;
- }
- [MethodImpl(MethodImplOptions.NoInlining)]
- void SetIsolationLevel(ChannelDispatcher channelDispatcher)
- {
- if (channelDispatcher == null)
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("channelDispatcher");
- channelDispatcher.TransactionIsolationLevel = this.transactionIsolationLevel;
- }
- void IServiceBehavior.Validate(ServiceDescription description, ServiceHostBase serviceHostBase)
- {
- if (this.concurrencyMode != ConcurrencyMode.Single && this.ensureOrderedDispatch)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxNonConcurrentOrEnsureOrderedDispatch, description.Name)));
- }
- }
- void IServiceBehavior.AddBindingParameters(ServiceDescription description, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection parameters)
- {
- }
- void IServiceBehavior.ApplyDispatchBehavior(ServiceDescription description, ServiceHostBase serviceHostBase)
- {
- for (int i = 0; i < serviceHostBase.ChannelDispatchers.Count; i++)
- {
- ChannelDispatcher channelDispatcher = serviceHostBase.ChannelDispatchers[i] as ChannelDispatcher;
- if (channelDispatcher != null)
- {
- channelDispatcher.IncludeExceptionDetailInFaults = this.includeExceptionDetailInFaults;
- if (channelDispatcher.HasApplicationEndpoints())
- {
- channelDispatcher.TransactionTimeout = transactionTimeout;
- if (isolationLevelSet)
- SetIsolationLevel(channelDispatcher);
- foreach (EndpointDispatcher endpointDispatcher in channelDispatcher.Endpoints)
- {
- if (endpointDispatcher.IsSystemEndpoint)
- {
- continue;
- }
- DispatchRuntime behavior = endpointDispatcher.DispatchRuntime;
- behavior.ConcurrencyMode = this.concurrencyMode;
- behavior.EnsureOrderedDispatch = this.ensureOrderedDispatch;
- behavior.ValidateMustUnderstand = validateMustUnderstand;
- behavior.AutomaticInputSessionShutdown = this.automaticSessionShutdown;
- behavior.TransactionAutoCompleteOnSessionClose = this.transactionAutoCompleteOnSessionClose;
- behavior.ReleaseServiceInstanceOnTransactionComplete = this.releaseServiceInstanceOnTransactionComplete;
- if (!this.useSynchronizationContext)
- {
- behavior.SynchronizationContext = null;
- }
- if (!endpointDispatcher.AddressFilterSetExplicit)
- {
- EndpointAddress address = endpointDispatcher.OriginalAddress;
- if (address == null || this.AddressFilterMode == AddressFilterMode.Any)
- {
- endpointDispatcher.AddressFilter = new MatchAllMessageFilter();
- }
- else if (this.AddressFilterMode == AddressFilterMode.Prefix)
- {
- endpointDispatcher.AddressFilter = new PrefixEndpointAddressMessageFilter(address);
- }
- else if (this.AddressFilterMode == AddressFilterMode.Exact)
- {
- endpointDispatcher.AddressFilter = new EndpointAddressMessageFilter(address);
- }
- }
- }
- }
- #pragma warning suppress 56506
- }
- }
- DataContractSerializerServiceBehavior.ApplySerializationSettings(description, ignoreExtensionDataObject, maxItemsInObjectGraph);
- ApplyInstancing(description, serviceHostBase);
- }
- void ApplyInstancing(ServiceDescription description, ServiceHostBase serviceHostBase)
- {
- Type serviceType = description.ServiceType;
- InstanceContext singleton = null;
- for (int i = 0; i < serviceHostBase.ChannelDispatchers.Count; i++)
- {
- ChannelDispatcher channelDispatcher = serviceHostBase.ChannelDispatchers[i] as ChannelDispatcher;
- if (channelDispatcher != null)
- {
- foreach (EndpointDispatcher endpointDispatcher in channelDispatcher.Endpoints)
- {
- if (endpointDispatcher.IsSystemEndpoint)
- {
- continue;
- }
- DispatchRuntime dispatch = endpointDispatcher.DispatchRuntime;
- if (dispatch.InstanceProvider == null)
- {
- if (instanceProvider == null)
- {
- if (serviceType == null && this.wellKnownSingleton == null)
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.InstanceSettingsMustHaveTypeOrWellKnownObject0)));
- if (this.instanceMode != InstanceContextMode.Single && this.wellKnownSingleton != null)
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxWellKnownNonSingleton0)));
- }
- else
- {
- dispatch.InstanceProvider = instanceProvider;
- }
- }
- dispatch.Type = serviceType;
- dispatch.InstanceContextProvider = InstanceContextProviderBase.GetProviderForMode(this.instanceMode, dispatch);
- if ((this.instanceMode == InstanceContextMode.Single) &&
- (dispatch.SingletonInstanceContext == null))
- {
- if (singleton == null)
- {
- if (this.wellKnownSingleton != null)
- {
- singleton = new InstanceContext(serviceHostBase, this.wellKnownSingleton, true, false);
- }
- else if (this.hiddenSingleton != null)
- {
- singleton = new InstanceContext(serviceHostBase, this.hiddenSingleton, false, false);
- }
- else
- {
- singleton = new InstanceContext(serviceHostBase, false);
- }
- singleton.AutoClose = false;
- }
- dispatch.SingletonInstanceContext = singleton;
- }
- }
- }
- }
- }
- }
- }
|