|
10 | 10 | using System.IO;
|
11 | 11 | using System.Reflection;
|
12 | 12 | using System.Runtime.CompilerServices;
|
| 13 | +using System.Runtime.Loader; |
13 | 14 | using System.Runtime.Versioning;
|
14 | 15 | using System.Security;
|
15 | 16 | using System.Text;
|
@@ -161,8 +162,7 @@ private static XmlSerializerNamespaces DefaultNamespaces
|
161 | 162 | internal const string TrimSerializationWarning = "Members from serialized types may be trimmed if not referenced directly";
|
162 | 163 | private const string TrimDeserializationWarning = "Members from deserialized types may be trimmed if not referenced directly";
|
163 | 164 |
|
164 |
| - private static readonly Dictionary<Type, Dictionary<XmlSerializerMappingKey, XmlSerializer>> s_xmlSerializerTable = new Dictionary<Type, Dictionary<XmlSerializerMappingKey, XmlSerializer>>(); |
165 |
| - |
| 165 | + private static readonly ContextAwareTables<Dictionary<XmlSerializerMappingKey, XmlSerializer>> s_xmlSerializerTable = new ContextAwareTables<Dictionary<XmlSerializerMappingKey, XmlSerializer>>(); |
166 | 166 | protected XmlSerializer()
|
167 | 167 | {
|
168 | 168 | }
|
@@ -235,30 +235,28 @@ public XmlSerializer(Type type, string? defaultNamespace)
|
235 | 235 | _tempAssembly = s_cache[defaultNamespace, type];
|
236 | 236 | if (_tempAssembly == null)
|
237 | 237 | {
|
| 238 | + XmlSerializerImplementation? contract = null; |
| 239 | + Assembly? assembly = TempAssembly.LoadGeneratedAssembly(type, defaultNamespace, out contract); |
| 240 | + if (assembly == null) |
238 | 241 | {
|
239 |
| - XmlSerializerImplementation? contract = null; |
240 |
| - Assembly? assembly = TempAssembly.LoadGeneratedAssembly(type, defaultNamespace, out contract); |
241 |
| - if (assembly == null) |
242 |
| - { |
243 |
| - if (Mode == SerializationMode.PreGenOnly) |
244 |
| - { |
245 |
| - AssemblyName name = type.Assembly.GetName(); |
246 |
| - var serializerName = Compiler.GetTempAssemblyName(name, defaultNamespace); |
247 |
| - throw new FileLoadException(SR.Format(SR.FailLoadAssemblyUnderPregenMode, serializerName)); |
248 |
| - } |
249 |
| - |
250 |
| - // need to reflect and generate new serialization assembly |
251 |
| - XmlReflectionImporter importer = new XmlReflectionImporter(defaultNamespace); |
252 |
| - _mapping = importer.ImportTypeMapping(type, null, defaultNamespace); |
253 |
| - _tempAssembly = GenerateTempAssembly(_mapping, type, defaultNamespace)!; |
254 |
| - } |
255 |
| - else |
| 242 | + if (Mode == SerializationMode.PreGenOnly) |
256 | 243 | {
|
257 |
| - // we found the pre-generated assembly, now make sure that the assembly has the right serializer |
258 |
| - // try to avoid the reflection step, need to get ElementName, namespace and the Key form the type |
259 |
| - _mapping = XmlReflectionImporter.GetTopLevelMapping(type, defaultNamespace); |
260 |
| - _tempAssembly = new TempAssembly(new XmlMapping[] { _mapping }, assembly, contract); |
| 244 | + AssemblyName name = type.Assembly.GetName(); |
| 245 | + var serializerName = Compiler.GetTempAssemblyName(name, defaultNamespace); |
| 246 | + throw new FileLoadException(SR.Format(SR.FailLoadAssemblyUnderPregenMode, serializerName)); |
261 | 247 | }
|
| 248 | + |
| 249 | + // need to reflect and generate new serialization assembly |
| 250 | + XmlReflectionImporter importer = new XmlReflectionImporter(defaultNamespace); |
| 251 | + _mapping = importer.ImportTypeMapping(type, null, defaultNamespace); |
| 252 | + _tempAssembly = GenerateTempAssembly(_mapping, type, defaultNamespace)!; |
| 253 | + } |
| 254 | + else |
| 255 | + { |
| 256 | + // we found the pre-generated assembly, now make sure that the assembly has the right serializer |
| 257 | + // try to avoid the reflection step, need to get ElementName, namespace and the Key form the type |
| 258 | + _mapping = XmlReflectionImporter.GetTopLevelMapping(type, defaultNamespace); |
| 259 | + _tempAssembly = new TempAssembly(new XmlMapping[] { _mapping }, assembly, contract); |
262 | 260 | }
|
263 | 261 | }
|
264 | 262 | s_cache.Add(defaultNamespace, type, _tempAssembly);
|
@@ -403,7 +401,9 @@ public void Serialize(XmlWriter xmlWriter, object? o, XmlSerializerNamespaces? n
|
403 | 401 | }
|
404 | 402 | }
|
405 | 403 | else
|
| 404 | + { |
406 | 405 | _tempAssembly.InvokeWriter(_mapping, xmlWriter, o, namespaces == null || namespaces.Count == 0 ? DefaultNamespaces : namespaces, encodingStyle, id);
|
| 406 | + } |
407 | 407 | }
|
408 | 408 | catch (Exception? e)
|
409 | 409 | {
|
@@ -629,7 +629,10 @@ public static XmlSerializer[] FromMappings(XmlMapping[]? mappings, Type? type)
|
629 | 629 | {
|
630 | 630 | XmlSerializer[] serializers = new XmlSerializer[mappings.Length];
|
631 | 631 | for (int i = 0; i < serializers.Length; i++)
|
| 632 | + { |
632 | 633 | serializers[i] = (XmlSerializer)contract!.TypedSerializers[mappings[i].Key!]!;
|
| 634 | + TempAssembly.VerifyLoadContext(serializers[i]._rootType, type!.Assembly); |
| 635 | + } |
633 | 636 | return serializers;
|
634 | 637 | }
|
635 | 638 | }
|
@@ -696,16 +699,9 @@ internal static bool GenerateSerializer(Type[]? types, XmlMapping[] mappings, St
|
696 | 699 | private static XmlSerializer[] GetSerializersFromCache(XmlMapping[] mappings, Type type)
|
697 | 700 | {
|
698 | 701 | XmlSerializer?[] serializers = new XmlSerializer?[mappings.Length];
|
699 |
| - |
700 | 702 | Dictionary<XmlSerializerMappingKey, XmlSerializer>? typedMappingTable = null;
|
701 |
| - lock (s_xmlSerializerTable) |
702 |
| - { |
703 |
| - if (!s_xmlSerializerTable.TryGetValue(type, out typedMappingTable)) |
704 |
| - { |
705 |
| - typedMappingTable = new Dictionary<XmlSerializerMappingKey, XmlSerializer>(); |
706 |
| - s_xmlSerializerTable[type] = typedMappingTable; |
707 |
| - } |
708 |
| - } |
| 703 | + |
| 704 | + typedMappingTable = s_xmlSerializerTable.GetOrCreateValue(type, () => new Dictionary<XmlSerializerMappingKey, XmlSerializer>()); |
709 | 705 |
|
710 | 706 | lock (typedMappingTable)
|
711 | 707 | {
|
|
0 commit comments