1 //------------------------------------------------------------ 2 // Copyright (c) Microsoft Corporation. All rights reserved. 3 //------------------------------------------------------------ 4 5 namespace System.ServiceModel.Dispatcher 6 { 7 using System; 8 using System.Collections.Generic; 9 using System.Runtime; 10 using System.Runtime.Serialization; 11 using System.ServiceModel; 12 using System.Xml; 13 using System.Xml.Serialization; 14 using DiagnosticUtility = System.ServiceModel.DiagnosticUtility; 15 16 class UnwrappedTypesXmlSerializerManager 17 { 18 Dictionary<Type, XmlTypeMapping> allTypes; 19 XmlReflectionImporter importer; 20 Dictionary<Object, IList<Type>> operationTypes; 21 bool serializersCreated; 22 Dictionary<Type, XmlSerializer> serializersMap; 23 Object thisLock; 24 UnwrappedTypesXmlSerializerManager()25 public UnwrappedTypesXmlSerializerManager() 26 { 27 this.allTypes = new Dictionary<Type, XmlTypeMapping>(); 28 this.serializersMap = new Dictionary<Type, XmlSerializer>(); 29 this.operationTypes = new Dictionary<Object, IList<Type>>(); 30 importer = new XmlReflectionImporter(); 31 this.thisLock = new Object(); 32 } 33 GetOperationSerializers(Object key)34 public TypeSerializerPair[] GetOperationSerializers(Object key) 35 { 36 if (key == null) 37 { 38 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("key"); 39 } 40 lock (thisLock) 41 { 42 if (!this.serializersCreated) 43 { 44 BuildSerializers(); 45 this.serializersCreated = true; 46 } 47 List<TypeSerializerPair> serializers = new List<TypeSerializerPair>(); 48 IList<Type> operationTypes = this.operationTypes[key]; 49 for (int i = 0; i < operationTypes.Count; ++i) 50 { 51 TypeSerializerPair pair = new TypeSerializerPair(); 52 pair.Type = operationTypes[i]; 53 pair.Serializer = new XmlSerializerXmlObjectSerializer(serializersMap[operationTypes[i]]); 54 serializers.Add(pair); 55 } 56 return serializers.ToArray(); 57 } 58 } 59 RegisterType(Object key, IList<Type> types)60 public void RegisterType(Object key, IList<Type> types) 61 { 62 if (key == null) 63 { 64 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("key"); 65 } 66 if (types == null) 67 { 68 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("types"); 69 } 70 lock (thisLock) 71 { 72 if (this.serializersCreated) 73 { 74 Fx.Assert("An xml serializer type was added after the serializers were created"); 75 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR2.GetString(SR2.XmlSerializersCreatedBeforeRegistration))); 76 } 77 for (int i = 0; i < types.Count; ++i) 78 { 79 if (!allTypes.ContainsKey(types[i])) 80 { 81 allTypes.Add(types[i], importer.ImportTypeMapping(types[i])); 82 } 83 } 84 operationTypes.Add(key, types); 85 } 86 } 87 BuildSerializers()88 void BuildSerializers() 89 { 90 List<Type> types = new List<Type>(); 91 List<XmlMapping> mappings = new List<XmlMapping>(); 92 foreach (Type type in allTypes.Keys) 93 { 94 XmlTypeMapping mapping = allTypes[type]; 95 types.Add(type); 96 mappings.Add(mapping); 97 } 98 XmlSerializer[] serializers = XmlSerializer.FromMappings(mappings.ToArray()); 99 for (int i = 0; i < types.Count; ++i) 100 { 101 serializersMap.Add(types[i], serializers[i]); 102 } 103 } 104 105 public struct TypeSerializerPair 106 { 107 public XmlObjectSerializer Serializer; 108 public Type Type; 109 } 110 111 class XmlSerializerXmlObjectSerializer : XmlObjectSerializer 112 { 113 XmlSerializer serializer; 114 XmlSerializerXmlObjectSerializer(XmlSerializer serializer)115 public XmlSerializerXmlObjectSerializer(XmlSerializer serializer) 116 { 117 if (serializer == null) 118 { 119 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("serializer"); 120 } 121 this.serializer = serializer; 122 } 123 IsStartObject(XmlDictionaryReader reader)124 public override bool IsStartObject(XmlDictionaryReader reader) 125 { 126 return this.serializer.CanDeserialize(reader); 127 } 128 ReadObject(XmlDictionaryReader reader, bool verifyObjectName)129 public override object ReadObject(XmlDictionaryReader reader, bool verifyObjectName) 130 { 131 return this.serializer.Deserialize(reader); 132 } 133 WriteEndObject(XmlDictionaryWriter writer)134 public override void WriteEndObject(XmlDictionaryWriter writer) 135 { 136 Fx.Assert("This method should never get hit"); 137 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException()); 138 } 139 WriteObject(XmlDictionaryWriter writer, object graph)140 public override void WriteObject(XmlDictionaryWriter writer, object graph) 141 { 142 this.serializer.Serialize(writer, graph); 143 } 144 WriteObjectContent(XmlDictionaryWriter writer, object graph)145 public override void WriteObjectContent(XmlDictionaryWriter writer, object graph) 146 { 147 Fx.Assert("This method should never get hit"); 148 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException()); 149 } 150 WriteStartObject(XmlDictionaryWriter writer, object graph)151 public override void WriteStartObject(XmlDictionaryWriter writer, object graph) 152 { 153 Fx.Assert("This method should never get hit"); 154 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException()); 155 } 156 } 157 } 158 } 159 160