T IContextCache.GetOrAddContext <T>(ContextFactory <T> contextFactory) { try { IContextValue <T> context = null; IContextCollection currentCollection; do { T existingValue; if (_collection.TryGetContext(out existingValue)) { return(existingValue); } IContextValue <T> contextProperty = context ?? (context = new ContextValue <T>(contextFactory())); currentCollection = Volatile.Read(ref _collection); Interlocked.CompareExchange(ref _collection, currentCollection.Add(contextProperty), currentCollection); } while (currentCollection == Volatile.Read(ref _collection)); return(context.Value); } catch (Exception exception) { throw new ContextFactoryException($"The payload factory faulted: {TypeCache<T>.ShortName}", exception); } }
ArrayContextCollection(IReadOnlyContextCollection parent, IContextValue context, IContextValue[] contexts) : base(parent) { _parent = parent; _contexts = new IContextValue[contexts.Length + 1]; _contexts[0] = context; Array.Copy(contexts, 0, _contexts, 1, contexts.Length); }
T IContextCache.AddOrUpdateContext <T>(ContextFactory <T> addFactory, UpdateContextFactory <T> updateFactory) { try { T previousValue = null; IContextValue <T> context = null; IContextCollection currentCollection; do { T existingValue; if (_collection.TryGetContext(out existingValue)) { if (context == null || previousValue != existingValue) { context = new ContextValue <T>(updateFactory(existingValue)); } previousValue = existingValue; currentCollection = Volatile.Read(ref _collection); Interlocked.CompareExchange(ref _collection, currentCollection.Add(context), currentCollection); } else { if (context == null) { context = new ContextValue <T>(addFactory()); } currentCollection = Volatile.Read(ref _collection); Interlocked.CompareExchange(ref _collection, currentCollection.Add(context), currentCollection); } } while (currentCollection == Volatile.Read(ref _collection)); return(context.Value); } catch (Exception exception) { throw new ContextFactoryException($"The payload factory faulted: {TypeCache<T>.ShortName}", exception); } }
public static T GetValue <T>(this IContextValue <T, NoContext> value) { return(value.GetValue(null)); }
public override IContextCollection Add(IContextValue context) { return(new SingleContextCollection(context, Parent)); }
public override IContextCollection Add(IContextValue context) { return(new ArrayContextCollection(_parent, context, _context)); }
public SingleContextCollection(IContextValue context, IReadOnlyContextCollection parent = null) : base(parent) { _context = context; _parent = parent; }
public abstract IContextCollection Add(IContextValue context);