MessageHeaderT.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 / MessageHeaderT.cs / 1 / MessageHeaderT.cs

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

namespace System.ServiceModel 
{
    using System.Collections.Generic; 
    using System.ServiceModel.Channels; 
    using System.Threading;
 
    public class MessageHeader
    {
        string actor;
        bool mustUnderstand; 
        bool relay;
        T content; 
 
        public MessageHeader()
        { 
        }

        public MessageHeader(T content)
            : this(content, false, "", false) 
        {
        } 
 
        public MessageHeader(T content, bool mustUnderstand, string actor, bool relay)
        { 
            this.content = content;
            this.mustUnderstand = mustUnderstand;
            this.actor = actor;
            this.relay = relay; 
        }
 
        public string Actor 
        {
            get { return this.actor; } 
            set { this.actor = value; }
        }

        public T Content 
        {
            get { return this.content; } 
            set { this.content = value; } 
        }
 
        public bool MustUnderstand
        {
            get { return this.mustUnderstand; }
            set { this.mustUnderstand = value; } 
        }
 
        public bool Relay 
        {
            get { return this.relay; } 
            set { this.relay = value; }
        }

        internal Type GetGenericArgument() 
        {
            return typeof(T); 
        } 

        public MessageHeader GetUntypedHeader(string name, string ns) 
        {
            return MessageHeader.CreateHeader(name, ns, this.content, this.mustUnderstand, this.actor, this.relay);
        }
    } 

    // problem: creating / getting content / settings content on a MessageHeader given the type at runtime 
    // require reflection. 
    // solution: This class creates a cache of adapters that provide an untyped wrapper over a particular
    // MessageHeader instantiation. 
    // better solution: implement something like "IUntypedTypedHeader" that has a "object Content" property,
    // privately implement this on TypedHeader, and then just use that iface to operation on the header (actually
    // you'd still have the creation problem...).  the issue with that is you now have a new public interface
    internal abstract class TypedHeaderManager 
    {
        static Dictionary cache = new Dictionary(); 
        static ReaderWriterLock cacheLock = new ReaderWriterLock(); 
        static Type GenericAdapterType = typeof(GenericAdapter<>);
 
        internal static object Create(Type t, object content, bool mustUnderstand, bool relay, string actor)
        {
            return GetTypedHeaderManager(t).Create(content, mustUnderstand, relay, actor);
        } 

        internal static object GetContent(Type t, object typedHeaderInstance, out bool mustUnderstand, out bool relay, out string actor) 
        { 
            return GetTypedHeaderManager(t).GetContent(typedHeaderInstance, out mustUnderstand, out relay, out actor);
        } 

        internal static Type GetMessageHeaderType(Type contentType)
        {
            return GetTypedHeaderManager(contentType).GetMessageHeaderType(); 
        }
        internal static Type GetHeaderType(Type headerParameterType) 
        { 
            if (headerParameterType.IsGenericType && headerParameterType.GetGenericTypeDefinition() == typeof(MessageHeader<>))
                return  headerParameterType.GetGenericArguments()[0]; 
            return headerParameterType;
        }

        static TypedHeaderManager GetTypedHeaderManager(Type t) 
        {
            TypedHeaderManager result = null; 
 
            bool lockHeld = false;
            try 
            {
                try { }
                finally
                { 
                    cacheLock.AcquireReaderLock(int.MaxValue);
                    lockHeld = true; 
                } 
                if (!cache.TryGetValue(t, out result))
                { 
                    cacheLock.UpgradeToWriterLock(int.MaxValue);
                    result = (TypedHeaderManager)Activator.CreateInstance(GenericAdapterType.MakeGenericType(t));
                    cache.Add(t, result);
                } 
            }
            finally 
            { 
                if (lockHeld)
                { 
                    cacheLock.ReleaseLock();
                }
            }
 
            return result;
        } 
 
        protected abstract object Create(object content, bool mustUnderstand, bool relay, string actor);
        protected abstract object GetContent(object typedHeaderInstance, out bool mustUnderstand, out bool relay, out string actor); 
        protected abstract Type GetMessageHeaderType();

        class GenericAdapter : TypedHeaderManager
        { 
            protected override object Create(object content, bool mustUnderstand, bool relay, string actor)
            { 
                MessageHeader header = new MessageHeader(); 
                header.Content = (T)content;
                header.MustUnderstand = mustUnderstand; 
                header.Relay = relay;
                header.Actor = actor;
                return header;
            } 

            protected override object GetContent(object typedHeaderInstance, out bool mustUnderstand, out bool relay, out string actor) 
            { 
                mustUnderstand = false;
                relay = false; 
                actor = null;
                if (typedHeaderInstance == null)
                    return null;
 
                MessageHeader header = typedHeaderInstance as MessageHeader;
                if (header == null) 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException("typedHeaderInstance")); 
                mustUnderstand = header.MustUnderstand;
                relay = header.Relay; 
                actor = header.Actor;
                return header.Content;
            }
 
            protected override Type GetMessageHeaderType()
            { 
                return typeof(MessageHeader); 
            }
        } 
    }
}

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