Source/Tx.Core/PartitionKeyDeserializer.cs (52 lines of code) (raw):

// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. using System.Collections.Generic; namespace System.Reactive { public sealed class PartitionKeyDeserializer<TInput, TKey> : IDeserializer<TInput> { private readonly Dictionary<TKey, Type> _knownTypes; private readonly Func<TInput, DateTimeOffset> _timeFunction; private readonly Dictionary<TKey, Func<TInput, object>> _transforms; private readonly IPartitionableTypeMap<TInput, TKey> _typeMap; /// <summary> /// Initializes a new instance of the <see cref="PartitionKeyDeserializer{TInput, TKey}"/> class. /// </summary> /// <param name="typeMap">The instance of type map that will be used to deserialize the input of type <see> /// <cref>TInput</cref> /// </see>.</param> public PartitionKeyDeserializer(IPartitionableTypeMap<TInput, TKey> typeMap) { _typeMap = typeMap; _transforms = new Dictionary<TKey, Func<TInput, object>>(_typeMap.Comparer); _timeFunction = _typeMap.TimeFunction; _knownTypes = new Dictionary<TKey, Type>(_typeMap.Comparer); } public void AddKnownType(Type type) { TKey key = _typeMap.GetTypeKey(type); if (key == null || key.Equals(default(TKey))) return; // this deserializer does not recognize the type if (_knownTypes.ContainsKey(key)) return; // adding types is idempotent operation _knownTypes.Add(key, type); _transforms.Add(key, null); // postpone the compilation until event occurence } public bool TryDeserialize(TInput value, out Timestamped<object> ts) { TKey key = _typeMap.GetInputKey(value); ts = default(Timestamped<object>); Func<TInput, object> transform; if (key == null || !_transforms.TryGetValue(key, out transform)) return false; if (transform == null) { Type type = _knownTypes[key]; transform = _typeMap.GetTransform(type); if (transform == null) return false; _transforms[key] = transform; } object o = transform(value); if (o != null) { ts = new Timestamped<object>(o, _timeFunction(value)); return true; } return false; } } }