DurableServiceAttribute.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / NetFx35 / System.WorkflowServices / System / ServiceModel / Description / DurableServiceAttribute.cs / 1305376 / DurableServiceAttribute.cs

                            //------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------
namespace System.ServiceModel.Description
{ 
    using System;
    using System.Runtime; 
    using System.ServiceModel.Administration; 
    using System.ServiceModel.Channels;
    using System.ServiceModel.Dispatcher; 
    using System.ServiceModel.Persistence;
    using System.Xml;

    [AttributeUsage(AttributeTargets.Class)] 
    public sealed class DurableServiceAttribute : Attribute, IServiceBehavior, IContextSessionProvider, IWmiInstanceProvider
    { 
        static DurableOperationAttribute defaultDurableOperationBehavior = new DurableOperationAttribute(); 
        bool saveStateInOperationTransaction;
        UnknownExceptionAction unknownExceptionAction; 

        public DurableServiceAttribute()
        {
            this.unknownExceptionAction = UnknownExceptionAction.TerminateInstance; 
        }
 
        public bool SaveStateInOperationTransaction 
        {
            get { return this.saveStateInOperationTransaction; } 
            set { this.saveStateInOperationTransaction = value; }
        }

        public UnknownExceptionAction UnknownExceptionAction 
        {
            get 
            { 
                return this.unknownExceptionAction;
            } 
            set
            {
                if (!UnknownExceptionActionHelper.IsDefined(value))
                { 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("value"));
                } 
 
                this.unknownExceptionAction = value;
            } 
        }

        public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, System.Collections.ObjectModel.Collection endpoints, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
        { 
            // empty
        } 
 
        public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
        { 
            if (serviceDescription == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("serviceDescription");
            } 

            if (serviceHostBase == null) 
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("serviceHostBase");
            } 

            if (serviceDescription.Endpoints == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("serviceDescription", SR2.GetString(SR2.NoEndpoints)); 
            }
 
            PersistenceProviderBehavior providerBehavior = null; 

            if (serviceDescription.Behaviors != null) 
            {
                providerBehavior = serviceDescription.Behaviors.Find();
            }
 
            if (providerBehavior == null)
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( 
                    new InvalidOperationException(
                    SR2.GetString( 
                    SR2.NonNullPersistenceProviderRequired,
                    typeof(PersistenceProvider).Name,
                    typeof(DurableServiceAttribute).Name)));
            } 

            if (providerBehavior.PersistenceProviderFactory == null) 
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                    new InvalidOperationException( 
                    SR2.GetString(
                    SR2.NonNullPersistenceProviderRequired,
                    typeof(PersistenceProvider).Name,
                    typeof(DurableServiceAttribute).Name))); 
            }
 
            providerBehavior.PersistenceProviderFactory.Open(); 
            serviceHostBase.Closed += new EventHandler(
                delegate(object sender, EventArgs args) 
            {
                Fx.Assert(sender is ServiceHostBase, "The sender should be serviceHostBase.");
                // We have no way of knowing whether the service host closed or aborted
                // so we err on the side of abort for right now. 
                providerBehavior.PersistenceProviderFactory.Abort();
            } 
                ); 

            DurableInstanceContextProvider instanceContextProvider = new ServiceDurableInstanceContextProvider( 
                serviceHostBase,
                false,
                serviceDescription.ServiceType,
                providerBehavior.PersistenceProviderFactory, 
                this.saveStateInOperationTransaction,
                this.unknownExceptionAction, 
                new DurableRuntimeValidator(this.saveStateInOperationTransaction, this.unknownExceptionAction), 
                providerBehavior.PersistenceOperationTimeout);
 
            DurableInstanceContextProvider singleCallInstanceContextProvider = null;

            IInstanceProvider instanceProvider = new DurableInstanceProvider(instanceContextProvider);
 
            bool includeExceptionDetails = false;
 
            if (serviceDescription.Behaviors != null) 
            {
                ServiceBehaviorAttribute serviceBehavior = serviceDescription.Behaviors.Find(); 

                if (serviceBehavior != null)
                {
                    includeExceptionDetails |= serviceBehavior.IncludeExceptionDetailInFaults; 
                }
 
                ServiceDebugBehavior serviceDebugBehavior = serviceDescription.Behaviors.Find(); 

                if (serviceDebugBehavior != null) 
                {
                    includeExceptionDetails |= serviceDebugBehavior.IncludeExceptionDetailInFaults;
                }
            } 

            IErrorHandler errorHandler = new ServiceErrorHandler(includeExceptionDetails); 
 
            foreach (ChannelDispatcherBase channelDispatcherBase in serviceHostBase.ChannelDispatchers)
            { 
                ChannelDispatcher channelDispatcher = channelDispatcherBase as ChannelDispatcher;

                if (channelDispatcher != null && channelDispatcher.HasApplicationEndpoints())
                { 
                    if (this.unknownExceptionAction == UnknownExceptionAction.AbortInstance)
                    { 
                        channelDispatcher.ErrorHandlers.Add(errorHandler); 
                    }
 
                    foreach (EndpointDispatcher endpointDispatcher in channelDispatcher.Endpoints)
                    {
                        if (endpointDispatcher.IsSystemEndpoint)
                        { 
                            continue;
                        } 
                        ServiceEndpoint serviceEndPoint = serviceDescription.Endpoints.Find(new XmlQualifiedName(endpointDispatcher.ContractName, endpointDispatcher.ContractNamespace)); 

                        if (serviceEndPoint != null) 
                        {
                            if (serviceEndPoint.Contract.SessionMode != SessionMode.NotAllowed)
                            {
                                endpointDispatcher.DispatchRuntime.InstanceContextProvider = instanceContextProvider; 
                            }
                            else 
                            { 
                                if (singleCallInstanceContextProvider == null)
                                { 
                                    singleCallInstanceContextProvider = new ServiceDurableInstanceContextProvider(
                                        serviceHostBase,
                                        true,
                                        serviceDescription.ServiceType, 
                                        providerBehavior.PersistenceProviderFactory,
                                        this.saveStateInOperationTransaction, 
                                        this.unknownExceptionAction, 
                                        new DurableRuntimeValidator(this.saveStateInOperationTransaction, this.unknownExceptionAction),
                                        providerBehavior.PersistenceOperationTimeout); 
                                }
                                endpointDispatcher.DispatchRuntime.InstanceContextProvider = singleCallInstanceContextProvider;
                            }
                            endpointDispatcher.DispatchRuntime.MessageInspectors.Add(new DurableMessageDispatchInspector(serviceEndPoint.Contract.SessionMode)); 
                            endpointDispatcher.DispatchRuntime.InstanceProvider = instanceProvider;
                            WorkflowServiceBehavior.SetContractFilterToIncludeAllOperations(endpointDispatcher, serviceEndPoint.Contract); 
                        } 
                    }
                } 
            }

            foreach (ServiceEndpoint endpoint in serviceDescription.Endpoints)
            { 
                if (!endpoint.InternalIsSystemEndpoint(serviceDescription))
                { 
                    foreach (OperationDescription opDescription in endpoint.Contract.Operations) 
                    {
                        if (!opDescription.Behaviors.Contains(typeof(DurableOperationAttribute))) 
                        {
                            opDescription.Behaviors.Add(DurableOperationAttribute.DefaultInstance);
                        }
                    } 
                }
            } 
        } 

        void IWmiInstanceProvider.FillInstance(IWmiInstance wmiInstance) 
        {
            wmiInstance.SetProperty("SaveStateInOperationTransaction", this.saveStateInOperationTransaction);
        }
 
        string IWmiInstanceProvider.GetInstanceType()
        { 
            return "DurableServiceAttribute"; 
        }
 
        public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
        {
            if (serviceDescription == null)
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("serviceDescription");
            } 
 
            ContextBindingElement.ValidateContextBindingElementOnAllEndpointsWithSessionfulContract(serviceDescription, this);
 
            if (serviceDescription.Behaviors != null)
            {
                ServiceBehaviorAttribute serviceBehavior = serviceDescription.Behaviors.Find();
 
                if (serviceBehavior != null)
                { 
                    if (serviceBehavior.InstanceContextMode != InstanceContextMode.PerSession) 
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( 
                            new InvalidOperationException(
                            SR2.GetString(SR2.InstanceContextModeMustBePerSession, serviceBehavior.InstanceContextMode)));
                    }
 
                    if (serviceBehavior.ConcurrencyMode == ConcurrencyMode.Multiple)
                    { 
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( 
                            new InvalidOperationException(
                            SR2.GetString(SR2.ConcurrencyMultipleNotSupported))); 
                    }

                    if (serviceBehavior.ConcurrencyMode == ConcurrencyMode.Reentrant
                        && this.UnknownExceptionAction == UnknownExceptionAction.AbortInstance) 
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( 
                            new InvalidOperationException( 
                            SR2.GetString(SR2.ConcurrencyReentrantAndAbortNotSupported)));
                    } 
                }
            }

            bool foundSessionfulContract = false; 

            foreach (ServiceEndpoint serviceEndpoint in serviceDescription.Endpoints) 
            { 
                if (serviceEndpoint != null && !serviceEndpoint.InternalIsSystemEndpoint(serviceDescription))
                { 
                    if (serviceEndpoint.Contract.SessionMode != SessionMode.NotAllowed)
                    {
                        foundSessionfulContract = true;
                    } 

                    foreach (OperationDescription operation in serviceEndpoint.Contract.Operations) 
                    { 
                        DurableOperationAttribute durableBehavior =
                            operation.Behaviors.Find(); 

                        if (durableBehavior == null)
                        {
                            durableBehavior = defaultDurableOperationBehavior; 
                        }
 
                        if (serviceEndpoint.Contract.SessionMode == SessionMode.NotAllowed) 
                        {
                            if (!durableBehavior.CanCreateInstanceForOperation(operation.IsOneWay)) 
                            {
                                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                                    new InvalidOperationException(
                                    SR2.GetString( 
                                    SR2.CanCreateInstanceMustBeTrue,
                                    serviceEndpoint.Contract.Name, 
                                    operation.Name))); 
                            }
                        } 
                        else
                        {
                            if (operation.IsOneWay &&
                                durableBehavior.CanCreateInstanceForOperation(operation.IsOneWay)) 
                            {
                                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( 
                                    new InvalidOperationException( 
                                    SR2.GetString(
                                    SR2.CanCreateInstanceMustBeTwoWay, 
                                    serviceEndpoint.Contract.Name,
                                    serviceEndpoint.Contract.SessionMode,
                                    operation.Name)));
                            } 
                        }
 
                        if (this.saveStateInOperationTransaction) 
                        {
                            bool hasTransaction = false; 

                            OperationBehaviorAttribute operationBehavior = operation.Behaviors.Find();

                            if (operationBehavior != null) 
                            {
                                if (operationBehavior.TransactionScopeRequired) 
                                { 
                                    hasTransaction = true;
                                } 
                            }

                            TransactionFlowAttribute transactionBehavior = operation.Behaviors.Find();
 
                            if (transactionBehavior != null)
                            { 
                                if (transactionBehavior.Transactions == TransactionFlowOption.Mandatory) 
                                {
                                    hasTransaction = true; 
                                }
                            }

                            if (!hasTransaction) 
                            {
                                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( 
                                    new InvalidOperationException( 
                                    SR2.GetString(
                                    SR2.SaveStateInTransactionValidationFailed, 
                                    operation.Name,
                                    serviceEndpoint.ListenUri)));
                            }
                        } 
                    }
                } 
            } 

            if (!foundSessionfulContract) 
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                    new InvalidOperationException(
                    SR2.GetString(SR2.SessionfulContractNotFound))); 
            }
        } 
    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK