-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathBinaryDeserializerContext.cs
79 lines (68 loc) · 2.92 KB
/
BinaryDeserializerContext.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
using CK.Core;
using System;
using System.Collections.Generic;
using System.Text;
namespace CK.BinarySerialization;
/// <summary>
/// Mutable cache of deserialization drivers and known objects/keys association that should be
/// reused for multiple, non concurrent, deserialization sessions of the same objects family.
/// <para>
/// This is absolutely not thread safe and can be used at any time by only one <see cref="IBinaryDeserializer"/>
/// that must be disposed to free the context (otherwise a <see cref="InvalidOperationException"/> is raised).
/// </para>
/// </summary>
public class BinaryDeserializerContext
{
readonly Dictionary<string, object> _knownObjects;
readonly SharedBinaryDeserializerContext _shared;
// Avoids a lookup in the shared concurrent dictionary. Is this clever?
readonly Dictionary<Type, IDeserializationDriver> _abstractDrivers;
readonly SimpleServiceContainer _services;
BinaryDeserializerImpl? _deserializer;
/// <summary>
/// Initializes a new <see cref="BinaryDeserializerContext"/>.
/// </summary>
/// <param name="shared">The shared context to use. Defaults to <see cref="BinaryDeserializer.DefaultSharedContext"/>.</param>
/// <param name="services">Optional base services.</param>
public BinaryDeserializerContext( SharedBinaryDeserializerContext? shared = null, IServiceProvider? services = null )
{
_knownObjects = new Dictionary<string, object>();
_shared = shared ?? BinaryDeserializer.DefaultSharedContext;
_abstractDrivers = new Dictionary<Type, IDeserializationDriver>();
_services = new SimpleServiceContainer( services );
}
internal void Acquire( BinaryDeserializerImpl d )
{
if( _deserializer != null )
{
Throw.InvalidOperationException( "This BinaryDeserializerContext is already used by an existing BinaryDeserializer. The existing BinaryDeserializer must be disposed first." );
}
_deserializer = d;
}
internal void Release()
{
_deserializer = null;
}
/// <summary>
/// Gets the shared deserializer context used by this context.
/// </summary>
public SharedBinaryDeserializerContext Shared => _shared;
/// <summary>
/// Gets a mutable service container.
/// </summary>
public SimpleServiceContainer Services => _services;
internal IDeserializationDriver GetAbstractDriver( Type t ) => _abstractDrivers.GetOrSet( t, SharedBinaryDeserializerContext.GetAbstractDriver );
internal IDeserializationDriver? TryFindDriver( ref DeserializerResolverArg info )
{
return _shared.TryFindDriver( ref info );
}
internal object? GetKnownObject( string instanceKey )
{
if( !_knownObjects.TryGetValue( instanceKey, out var r ) )
{
r = _shared.KnownObjects.GetKnownObject( instanceKey );
if( r != null ) _knownObjects.Add( instanceKey, r );
}
return r;
}
}