RoutingService.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 / NetFx40 / System.ServiceModel.Routing / System / ServiceModel / Routing / RoutingService.cs / 1305376 / RoutingService.cs

                            //---------------------------------------------------------------- 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//---------------------------------------------------------------

 
[assembly : System.Diagnostics.CodeAnalysis.SuppressMessage(System.Runtime.FxCop.Category.Performance,
System.Runtime.FxCop.Rule.AvoidUncalledPrivateCode, 
Scope = "member", 
Target = "System.ServiceModel.Routing.SR.RoutingExtensionNotFound",
Justification = "gets called in RoutingService.ctor(). bug in fxcop")] 

namespace System.ServiceModel.Routing
{
    using System; 
    using System.Collections.Generic;
    using System.Configuration; 
    using System.Diagnostics.CodeAnalysis; 
    using System.Runtime;
    using System.ServiceModel; 
    using System.ServiceModel.Activation;
    using System.ServiceModel.Channels;
    using System.ServiceModel.Description;
    using System.ServiceModel.Dispatcher; 
    using System.Transactions;
    using SR2 = System.ServiceModel.Routing.SR; 
 
    // Some of the [ServiceBehavior] settings are configured in RoutingBehavior class since
    // we need to pick the options dynamically based on whether we have transactions or not 
    [SuppressMessage(FxCop.Category.Xaml, FxCop.Rule.TypesMustHaveXamlCallableConstructors)]
    [SuppressMessage(FxCop.Category.Xaml, FxCop.Rule.TypesShouldHavePublicParameterlessConstructors)]
    [ServiceBehavior(AddressFilterMode = AddressFilterMode.Any, InstanceContextMode = InstanceContextMode.PerSession,
        UseSynchronizationContext = false, ValidateMustUnderstand = false)] 
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public sealed class RoutingService : 
        ISimplexDatagramRouter, 
        ISimplexSessionRouter,
        IRequestReplyRouter, 
        IDuplexSessionRouter,
        IDisposable
    {
        SessionChannels perMessageChannels; 
        OperationContext operationContext;
 
        RoutingService() 
        {
            this.SessionMessages = new List(1); 

            //We only need to call this here if we trace in this method.  BeginXXX methods call it again.
            //FxTrace.Trace.SetAndTraceTransfer(this.ActivityID, true);
 
            this.operationContext = OperationContext.Current;
            IContextChannel channel = this.operationContext.Channel; 
 
            ServiceHostBase host = this.operationContext.Host;
            this.ChannelExtension = channel.Extensions.Find(); 
            if (this.ChannelExtension == null)
            {
                throw FxTrace.Exception.AsError(new ConfigurationErrorsException(SR2.RoutingExtensionNotFound));
            } 

            this.RoutingConfig = host.Extensions.Find().RoutingConfiguration; 
            this.RoutingConfig.VerifyConfigured(); 
            this.ChannelExtension.AttachService(this);
        } 

        [SuppressMessage(FxCop.Category.Performance, FxCop.Rule.AvoidUncalledPrivateCode, Justification = "private setter does get called")]
        internal RoutingChannelExtension ChannelExtension
        { 
            get;
            private set; 
        } 

        [SuppressMessage(FxCop.Category.Performance, FxCop.Rule.AvoidUncalledPrivateCode, Justification = "private setter does get called")] 
        internal RoutingConfiguration RoutingConfig
        {
            get;
            private set; 
        }
 
        internal CommittableTransaction RetryTransaction 
        {
            get; 
            private set;
        }

        internal Exception SessionException 
        {
            get; 
            set; 
        }
 
        [SuppressMessage(FxCop.Category.Performance, FxCop.Rule.AvoidUncalledPrivateCode, Justification = "private setter does get called")]
        internal IList SessionMessages
        {
            get; 
            private set;
        } 
 
        Transaction ReceiveTransaction
        { 
            get;
            set;
        }
 
        internal void CreateNewTransactionIfNeeded(MessageRpc messageRpc)
        { 
            if (messageRpc.Transaction != null && this.ChannelExtension.TransactedReceiveEnabled) 
            {
                if (TD.RoutingServiceUsingExistingTransactionIsEnabled()) 
                {
                    TD.RoutingServiceUsingExistingTransaction(messageRpc.Transaction.TransactionInformation.LocalIdentifier);
                }
                Fx.Assert(this.ReceiveTransaction == null, "Should only happen at the start of a session."); 
                this.ReceiveTransaction = messageRpc.Transaction;
                return; 
            } 
            else if (!this.ChannelExtension.TransactedReceiveEnabled || !this.ChannelExtension.ReceiveContextEnabled)
            { 
                return;
            }

            Fx.Assert(this.RetryTransaction == null, "Logic error, we shouldn't be calling CreateNewTransactionIfNeeded if we have a RC Transaction"); 

            ChannelDispatcher channelDispatcher = this.operationContext.EndpointDispatcher.ChannelDispatcher; 
            TimeSpan timeout = channelDispatcher.TransactionTimeout; 
            IsolationLevel isolation = channelDispatcher.TransactionIsolationLevel;
            TransactionOptions options = new TransactionOptions(); 
            if (timeout > TimeSpan.Zero)
            {
                options.Timeout = timeout;
            } 
            if (isolation != IsolationLevel.Unspecified)
            { 
                options.IsolationLevel = isolation; 
            }
 
            this.RetryTransaction = new CommittableTransaction(options);
            if (TD.RoutingServiceCreatingTransactionIsEnabled())
            {
                TD.RoutingServiceCreatingTransaction(this.RetryTransaction.TransactionInformation.LocalIdentifier); 
            }
        } 
 
        internal IRoutingClient GetOrCreateClient(RoutingEndpointTrait endpointTrait, bool impersonating)
        { 
            if (impersonating && !this.ChannelExtension.HasSession)
            {
                if (this.perMessageChannels == null)
                { 
                    this.perMessageChannels = new SessionChannels(this.ChannelExtension.ActivityID);
                } 
                return this.perMessageChannels.GetOrCreateClient(endpointTrait, this, impersonating); 
            }
            else 
            {
                return this.ChannelExtension.SessionChannels.GetOrCreateClient(endpointTrait, this, impersonating);
            }
        } 

        internal Transaction GetTransactionForSending(MessageRpc messageRpc) 
        { 
            if (messageRpc != null && messageRpc.Transaction != null)
            { 
                return messageRpc.Transaction;
            }
            if (this.ReceiveTransaction != null)
            { 
                //This is the transaction used for the receive, we cannot perform error handling since we
                //didn't create it. 
                return this.ReceiveTransaction; 
            }
            else 
            {
                //This could be null, indicating non-transactional behavior
                return this.RetryTransaction;
            } 
        }
 
        void IDisposable.Dispose() 
        {
            if (this.perMessageChannels != null) 
            {
                //This is for impersonation, thus it's supposed to complete [....]
                IAsyncResult result = this.perMessageChannels.BeginClose(this.ChannelExtension.OperationTimeout, null, null);
                this.perMessageChannels.EndClose(result); 
                this.perMessageChannels = null;
            } 
        } 

        internal void ResetSession() 
        {
            //Are we in a transactional error handling case (i.e. ReceiveContext)?
            if (this.RetryTransaction != null)
            { 
                if (this.ChannelExtension.HasSession)
                { 
                    this.ChannelExtension.SessionChannels.AbortAll(); 
                }
 
                RoutingUtilities.SafeRollbackTransaction(this.RetryTransaction);
                this.RetryTransaction = null;
            }
        } 

        [OperationBehavior(Impersonation = ImpersonationOption.Allowed)] 
        IAsyncResult ISimplexSessionRouter.BeginProcessMessage(Message message, AsyncCallback callback, object state) 
        {
            return this.BeginProcessMessage(message, callback, state); 
        }

        void ISimplexSessionRouter.EndProcessMessage(IAsyncResult result)
        { 
            this.EndProcessMessage(result);
        } 
 
        [OperationBehavior(Impersonation = ImpersonationOption.Allowed)]
        IAsyncResult IRequestReplyRouter.BeginProcessRequest(Message message, AsyncCallback callback, object state) 
        {
            return this.BeginProcessRequest(message, callback, state);
        }
 
        Message IRequestReplyRouter.EndProcessRequest(IAsyncResult result)
        { 
            return this.EndProcessRequest(result); 
        }
 
        [OperationBehavior(Impersonation=ImpersonationOption.Allowed)]
        IAsyncResult IDuplexSessionRouter.BeginProcessMessage(Message message, AsyncCallback callback, object state)
        {
            return this.BeginProcessMessage(message, callback, state); 
        }
 
        void IDuplexSessionRouter.EndProcessMessage(IAsyncResult result) 
        {
            this.EndProcessMessage(result); 
        }

        [OperationBehavior(Impersonation = ImpersonationOption.Allowed)]
        IAsyncResult ISimplexDatagramRouter.BeginProcessMessage(Message message, AsyncCallback callback, object state) 
        {
            return this.BeginProcessMessage(message, callback, state); 
        } 

        void ISimplexDatagramRouter.EndProcessMessage(IAsyncResult result) 
        {
            this.EndProcessMessage(result);
        }
 
        IAsyncResult BeginProcessMessage(Message message, AsyncCallback callback, object state)
        { 
            try 
            {
                FxTrace.Trace.SetAndTraceTransfer(this.ChannelExtension.ActivityID, true); 
                return new ProcessMessagesAsyncResult(message, this, this.ChannelExtension.OperationTimeout, callback, state);
            }
            catch (Exception exception)
            { 
                if (TD.RoutingServiceProcessingFailureIsEnabled())
                { 
                    TD.RoutingServiceProcessingFailure(OperationContext.Current.Channel.LocalAddress.ToString(), exception); 
                }
                throw; 
            }
        }

        void EndProcessMessage(IAsyncResult result) 
        {
            try 
            { 
                FxTrace.Trace.SetAndTraceTransfer(this.ChannelExtension.ActivityID, true);
                ProcessMessagesAsyncResult.End(result); 
            }
            catch (Exception exception)
            {
                if (TD.RoutingServiceProcessingFailureIsEnabled()) 
                {
                    TD.RoutingServiceProcessingFailure(OperationContext.Current.Channel.LocalAddress.ToString(), exception); 
                } 
                throw;
            } 
        }

        IAsyncResult BeginProcessRequest(Message message, AsyncCallback callback, object state)
        { 
            try
            { 
                FxTrace.Trace.SetAndTraceTransfer(this.ChannelExtension.ActivityID, true); 
                return new ProcessRequestAsyncResult(this, message, callback, state);
            } 
            catch (Exception exception)
            {
                if (TD.RoutingServiceProcessingFailureIsEnabled())
                { 
                    TD.RoutingServiceProcessingFailure(OperationContext.Current.Channel.LocalAddress.ToString(), exception);
                } 
                throw; 
            }
        } 

        Message EndProcessRequest(IAsyncResult result)
        {
            try 
            {
                FxTrace.Trace.SetAndTraceTransfer(this.ChannelExtension.ActivityID, true); 
                return ProcessRequestAsyncResult.End(result); 
            }
            catch (Exception exception) 
            {
                if (TD.RoutingServiceProcessingFailureIsEnabled())
                {
                    TD.RoutingServiceProcessingFailure(OperationContext.Current.Channel.LocalAddress.ToString(), exception); 
                }
                throw; 
            } 
        }
    } 
}

// 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