File: System\ServiceModel\Dispatcher\UnwrappedTypesXmlSerializerManager.cs
Project: ndp\cdf\src\NetFx35\System.ServiceModel.Web\System.ServiceModel.Web.csproj (System.ServiceModel.Web)
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation.  All rights reserved.
//------------------------------------------------------------
 
namespace System.ServiceModel.Dispatcher
{
    using System;
    using System.Collections.Generic;
    using System.Runtime;
    using System.Runtime.Serialization;
    using System.ServiceModel;
    using System.Xml;
    using System.Xml.Serialization;
    using DiagnosticUtility = System.ServiceModel.DiagnosticUtility;
 
    class UnwrappedTypesXmlSerializerManager
    {
        Dictionary<Type, XmlTypeMapping> allTypes;
        XmlReflectionImporter importer;
        Dictionary<Object, IList<Type>> operationTypes;
        bool serializersCreated;
        Dictionary<Type, XmlSerializer> serializersMap;
        Object thisLock;
 
        public UnwrappedTypesXmlSerializerManager()
        {
            this.allTypes = new Dictionary<Type, XmlTypeMapping>();
            this.serializersMap = new Dictionary<Type, XmlSerializer>();
            this.operationTypes = new Dictionary<Object, IList<Type>>();
            importer = new XmlReflectionImporter();
            this.thisLock = new Object();
        }
 
        public TypeSerializerPair[] GetOperationSerializers(Object key)
        {
            if (key == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("key");
            }
            lock (thisLock)
            {
                if (!this.serializersCreated)
                {
                    BuildSerializers();
                    this.serializersCreated = true;
                }
                List<TypeSerializerPair> serializers = new List<TypeSerializerPair>();
                IList<Type> operationTypes = this.operationTypes[key];
                for (int i = 0; i < operationTypes.Count; ++i)
                {
                    TypeSerializerPair pair = new TypeSerializerPair();
                    pair.Type = operationTypes[i];
                    pair.Serializer = new XmlSerializerXmlObjectSerializer(serializersMap[operationTypes[i]]);
                    serializers.Add(pair);
                }
                return serializers.ToArray();
            }
        }
 
        public void RegisterType(Object key, IList<Type> types)
        {
            if (key == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("key");
            }
            if (types == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("types");
            }
            lock (thisLock)
            {
                if (this.serializersCreated)
                {
                    Fx.Assert("An xml serializer type was added after the serializers were created");
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR2.GetString(SR2.XmlSerializersCreatedBeforeRegistration)));
                }
                for (int i = 0; i < types.Count; ++i)
                {
                    if (!allTypes.ContainsKey(types[i]))
                    {
                        allTypes.Add(types[i], importer.ImportTypeMapping(types[i]));
                    }
                }
                operationTypes.Add(key, types);
            }
        }
 
        void BuildSerializers()
        {
            List<Type> types = new List<Type>();
            List<XmlMapping> mappings = new List<XmlMapping>();
            foreach (Type type in allTypes.Keys)
            {
                XmlTypeMapping mapping = allTypes[type];
                types.Add(type);
                mappings.Add(mapping);
            }
            XmlSerializer[] serializers = XmlSerializer.FromMappings(mappings.ToArray());
            for (int i = 0; i < types.Count; ++i)
            {
                serializersMap.Add(types[i], serializers[i]);
            }
        }
 
        public struct TypeSerializerPair
        {
            public XmlObjectSerializer Serializer;
            public Type Type;
        }
 
        class XmlSerializerXmlObjectSerializer : XmlObjectSerializer
        {
            XmlSerializer serializer;
 
            public XmlSerializerXmlObjectSerializer(XmlSerializer serializer)
            {
                if (serializer == null)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("serializer");
                }
                this.serializer = serializer;
            }
 
            public override bool IsStartObject(XmlDictionaryReader reader)
            {
                return this.serializer.CanDeserialize(reader);
            }
 
            public override object ReadObject(XmlDictionaryReader reader, bool verifyObjectName)
            {
                return this.serializer.Deserialize(reader);
            }
 
            public override void WriteEndObject(XmlDictionaryWriter writer)
            {
                Fx.Assert("This method should never get hit");
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException());
            }
 
            public override void WriteObject(XmlDictionaryWriter writer, object graph)
            {
                this.serializer.Serialize(writer, graph);
            }
 
            public override void WriteObjectContent(XmlDictionaryWriter writer, object graph)
            {
                Fx.Assert("This method should never get hit");
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException());
            }
 
            public override void WriteStartObject(XmlDictionaryWriter writer, object graph)
            {
                Fx.Assert("This method should never get hit");
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException());
            }
        }
    }
}