public async Task <TDocument> GetOrCreateMutableAsync(Func <Task <TDocument> > factoryAsync = null) { TDocument document = null; if (!_isVolatile) { document = await DocumentStore.GetOrCreateMutableAsync(factoryAsync); if (_memoryCache.TryGetValue <TDocument>(_options.CacheKey, out var cached) && document == cached) { throw new InvalidOperationException("Can't load for update a cached object"); } } else { var volatileCache = ShellScope.Get <TDocument>(typeof(TDocument)); if (volatileCache != null) { document = volatileCache; } else { document = await GetFromDistributedCacheAsync() ?? await(factoryAsync?.Invoke() ?? Task.FromResult((TDocument)null)) ?? new TDocument(); ShellScope.Set(typeof(TDocument), document); } } document.Identifier = IdGenerator.GenerateId(); return(document); }
public async Task UpdateAsync(TDocument document, Func <TDocument, Task> afterUpdateAsync = null) { if (_isDistributed) { try { _ = await _distributedCache.GetStringAsync(_options.CacheIdKey); } catch { await DocumentStore.CancelAsync(); throw new InvalidOperationException($"Can't update the '{typeof(TDocument).Name}' if not able to access the distributed cache"); } } if (_memoryCache.TryGetValue <TDocument>(_options.CacheKey, out var cached) && document == cached) { throw new InvalidOperationException("Can't update a cached object"); } document.Identifier ??= IdGenerator.GenerateId(); if (!_isVolatile) { await DocumentStore.UpdateAsync(document, async document => { await SetInternalAsync(document); if (afterUpdateAsync != null) { await afterUpdateAsync(document); } }, _options.CheckConcurrency.Value); return; } // Set the scoped cache in case of multiple updates. ShellScope.Set(typeof(TDocument), document); // But still update the shared cache after committing. DocumentStore.AfterCommitSuccess <TDocument>(async() => { await SetInternalAsync(document); if (afterUpdateAsync != null) { await afterUpdateAsync(document); } }); return; }
/// <inheritdoc /> public async Task <T> GetOrCreateMutableAsync <T>(Func <Task <T> > factoryAsync = null) where T : class, new() { var loaded = ShellScope.Get <T>(typeof(T)); if (loaded != null) { return(loaded); } var document = await GetDocumentAsync <T>() ?? await(factoryAsync?.Invoke() ?? Task.FromResult((T)null)) ?? new T(); ShellScope.Set(typeof(T), document); return(document); }
public Task UpdateAsync(TDocument document, Func <TDocument, Task> afterUpdateAsync = null) { if (_memoryCache.TryGetValue <TDocument>(_options.CacheKey, out var cached) && document == cached) { throw new InvalidOperationException("Can't update a cached object"); } document.Identifier ??= IdGenerator.GenerateId(); if (!_isVolatile) { return(DocumentStore.UpdateAsync(document, async document => { await SetInternalAsync(document); if (afterUpdateAsync != null) { await afterUpdateAsync(document); } }, _options.CheckConcurrency.Value)); } // Set the scoped cache in case of multiple updates. ShellScope.Set(typeof(TDocument), document); // But still update the shared cache after committing. DocumentStore.AfterCommitSuccess <TDocument>(async() => { await SetInternalAsync(document); if (afterUpdateAsync != null) { await afterUpdateAsync(document); } }); return(Task.CompletedTask); }