public MemoryData <DT> GetMemoryData <DT>(DT data)
        {
            var memoryData = new MemoryData <DT>
            {
                Data    = data,
                Version = 1,
                Id      = Guid.NewGuid()
            };

            return(memoryData);
        }
        public void UpdateData <T>(IPersistanceData <T> data) where T : class, IProcessManagerData
        {
            lock (_memoryCacheLock)
            {
                string error   = null;
                var    newData = (MemoryData <T>)data;
                string key     = data.Data.CorrelationId.ToString();

                //if (Cache.Contains(key))
                if (_provider.Contains(key))
                {
                    //var currentVersion = ((MemoryData<T>)(Cache.Get(key))).Version;
                    var currentVersion = ((MemoryData <T>)(_provider.Get <string, object>(key))).Version;

                    var updatedData = new MemoryData <T>
                    {
                        Data    = data.Data,
                        Version = newData.Version + 1
                    };

                    if (currentVersion == newData.Version)
                    {
                        //Cache.Set(key, updatedData, _policy);
                        _provider.Remove(key);
                        _provider.Add(key, updatedData, _absoluteExpiry);
                    }
                    else
                    {
                        error = string.Format("Possible Concurrency Error. ProcessManagerData with CorrelationId {0} and Version {1} could not be updated.", key, currentVersion);
                    }
                }
                else
                {
                    error = string.Format("ProcessManagerData with CorrelationId {0} does not exist in memory.", key);
                }

                if (!string.IsNullOrEmpty(error))
                {
                    throw new ArgumentException(error);
                }
            }
        }
        public IPersistanceData <T> FindData <T>(IProcessManagerPropertyMapper mapper, Message message) where T : class, IProcessManagerData
        {
            lock (_memoryCacheLock)
            {
                var mapping = mapper.Mappings.FirstOrDefault(m => m.MessageType == message.GetType()) ??
                              mapper.Mappings.First(m => m.MessageType == typeof(Message));


                object msgPropValue = null;

                try
                {
                    msgPropValue = mapping.MessageProp.Invoke(message);
                }
                catch
                {
                    return(null);
                }

                if (null == msgPropValue)
                {
                    throw new ArgumentException("Message property expression evaluates to null");
                }

                //Left
                ParameterExpression pe   = Expression.Parameter(typeof(MemoryData <T>), "t");
                Expression          left = Expression.Property(pe, typeof(MemoryData <T>).GetTypeInfo().GetProperty("Data"));
                foreach (var prop in mapping.PropertiesHierarchy.Reverse())
                {
                    left = Expression.Property(left, left.Type, prop.Key);
                }

                //Right
                Expression right = Expression.Constant(msgPropValue, msgPropValue.GetType());

                Expression expression;

                try
                {
                    expression = Expression.Equal(left, right);
                }
                catch (InvalidOperationException ex)
                {
                    throw new Exception("Mapped incompatible types of ProcessManager Data and Message properties.", ex);
                }

                Expression <Func <MemoryData <T>, bool> > lambda = Expression.Lambda <Func <MemoryData <T>, bool> >(expression, pe);

                // get all the relevant cache items
                //var cacheItems = (from n in Cache.AsParallel() where n.Value.GetType() == typeof(MemoryData<IProcessManagerData>) select n.Value);

                IList <object> cacheItems = new List <object>();

                foreach (var key in _provider.Keys())
                {
                    var value = _provider.Get <string, object>(key.ToString());
                    if (value.GetType() == typeof(MemoryData <IProcessManagerData>))
                    {
                        cacheItems.Add(value);
                    }
                }

                // convert to correct generic type
                //var newCacheItems = Enumerable.ToList((from dynamic cacheItem in cacheItems select new MemoryData<T> { Data = cacheItem.Data, Version = cacheItem.Version }));
                var newCacheItems = Enumerable.ToList((from dynamic cacheItem in cacheItems select new MemoryData <T> {
                    Data = cacheItem.Data, Version = cacheItem.Version
                }));
                // filter based of mapping criteria
                MemoryData <T> retval = newCacheItems.FirstOrDefault(lambda.Compile());

                return(retval);
            }
        }