RequestReplyCorrelator.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / ServiceModel / System / ServiceModel / Channels / RequestReplyCorrelator.cs / 1 / RequestReplyCorrelator.cs

                            //------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------
namespace System.ServiceModel.Channels
{ 
    using System.Collections;
    using System.ServiceModel; 
    using System.Collections.Generic; 
    using System.Xml;
    using System.ServiceModel.Diagnostics; 

    class RequestReplyCorrelator : IRequestReplyCorrelator
    {
        Hashtable states; 

        internal RequestReplyCorrelator() 
        { 
            this.states = new Hashtable();
        } 

        void IRequestReplyCorrelator.Add(Message request, T state)
        {
            UniqueId messageId = request.Headers.MessageId; 
            Type stateType = typeof(T);
            Key key = new Key(messageId, stateType); 
 
            lock (states)
            { 
                states.Add(key, state);
            }
        }
 
        T IRequestReplyCorrelator.Find(Message reply, bool remove)
        { 
            UniqueId relatesTo = GetRelatesTo(reply); 
            Type stateType = typeof(T);
            Key key = new Key(relatesTo, stateType); 
            T value;

            lock (states)
            { 
                value = (T)states[key];
 
                if (remove) 
                    states.Remove(key);
            } 

            return value;
        }
 
        UniqueId GetRelatesTo(Message reply)
        { 
            UniqueId relatesTo = reply.Headers.RelatesTo; 
            if (relatesTo == null)
                throw TraceUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.SuppliedMessageIsNotAReplyItHasNoRelatesTo0)), reply); 
            return relatesTo;
        }

        internal static bool AddressReply(Message reply, Message request) 
        {
            ReplyToInfo info = RequestReplyCorrelator.ExtractReplyToInfo(request); 
            return RequestReplyCorrelator.AddressReply(reply, info); 
        }
 
        internal static bool AddressReply(Message reply, ReplyToInfo info)
        {
            EndpointAddress destination = null;
 
            if (info.HasFaultTo && (reply.IsFault))
            { 
                destination = info.FaultTo; 
            }
            else if (info.HasReplyTo) 
            {
                destination = info.ReplyTo;
            }
            else if (reply.Version.Addressing == AddressingVersion.WSAddressingAugust2004) 
            {
                if (info.HasFrom) 
                { 
                    destination = info.From;
                } 
                else
                {
                    destination = EndpointAddress.AnonymousAddress;
                } 
            }
 
            if (destination != null) 
            {
                destination.ApplyTo(reply); 
                return !destination.IsNone;
            }
            else
            { 
                return true;
            } 
        } 

        internal static ReplyToInfo ExtractReplyToInfo(Message message) 
        {
            return new ReplyToInfo(message);
        }
 
        internal static void PrepareRequest(Message request)
        { 
            MessageHeaders requestHeaders = request.Headers; 

            if (requestHeaders.MessageId == null) 
            {
                requestHeaders.MessageId = new UniqueId();
            }
 
            request.Properties.AllowOutputBatching = false;
            if (TraceUtility.PropagateUserActivity || TraceUtility.ShouldPropagateActivity) 
            { 
                TraceUtility.AddAmbientActivityToMessage(request);
            } 
        }

        internal static void PrepareReply(Message reply, UniqueId messageId)
        { 
            if (object.ReferenceEquals(messageId, null))
                throw TraceUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.MissingMessageID)), reply); 
 
            MessageHeaders replyHeaders = reply.Headers;
 
            if (object.ReferenceEquals(replyHeaders.RelatesTo, null))
            {
                replyHeaders.RelatesTo = messageId;
            } 

            if (TraceUtility.PropagateUserActivity || TraceUtility.ShouldPropagateActivity) 
            { 
                TraceUtility.AddAmbientActivityToMessage(reply);
            } 
        }

        internal static void PrepareReply(Message reply, Message request)
        { 
            UniqueId messageId = request.Headers.MessageId;
 
            if (messageId != null) 
            {
                MessageHeaders replyHeaders = reply.Headers; 

                if (object.ReferenceEquals(replyHeaders.RelatesTo, null))
                {
                    replyHeaders.RelatesTo = messageId; 
                }
            } 
 
            if (TraceUtility.PropagateUserActivity || TraceUtility.ShouldPropagateActivity)
            { 
                TraceUtility.AddAmbientActivityToMessage(reply);
            }
        }
 
        internal struct ReplyToInfo
        { 
            readonly EndpointAddress faultTo; 
            readonly EndpointAddress from;
            readonly EndpointAddress replyTo; 

            internal ReplyToInfo(Message message)
            {
                this.faultTo = message.Headers.FaultTo; 
                this.replyTo = message.Headers.ReplyTo;
                if (message.Version.Addressing == AddressingVersion.WSAddressingAugust2004) 
                { 
                    this.from = message.Headers.From;
                } 
                else
                {
                    this.from = null;
                } 
            }
 
            internal EndpointAddress FaultTo 
            {
                get { return this.faultTo; } 
            }

            internal EndpointAddress From
            { 
                get { return this.from; }
            } 
 
            internal bool HasFaultTo
            { 
                get { return !IsTrivial(this.FaultTo); }
            }

            internal bool HasFrom 
            {
                get { return !IsTrivial(this.From); } 
            } 

            internal bool HasReplyTo 
            {
                get { return !IsTrivial(this.ReplyTo); }
            }
 
            internal EndpointAddress ReplyTo
            { 
                get { return this.replyTo; } 
            }
 
            bool IsTrivial(EndpointAddress address)
            {
                // Note: even if address.IsAnonymous, it may have identity, reference parameters, etc.
                return (address == null) || (address==EndpointAddress.AnonymousAddress); 
            }
        } 
 
        class Key
        { 
            internal UniqueId MessageId;
            internal Type StateType;

            internal Key(UniqueId messageId, Type stateType) 
            {
                MessageId = messageId; 
                StateType = stateType; 
            }
 
            public override bool Equals(object obj)
            {
                Key other = obj as Key;
                if (other == null) 
                    return false;
                return other.MessageId == this.MessageId && other.StateType == this.StateType; 
            } 

            public override int GetHashCode() 
            {
                return MessageId.GetHashCode() ^ StateType.GetHashCode();
            }
 
            public override string ToString()
            { 
                return typeof(Key).ToString() + ": {" + MessageId + ", " + StateType.ToString() + "}"; 
            }
 
        }

    }
 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
                        

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