Exemplo n.º 1
0
        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);
        }
Exemplo n.º 2
0
        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;
        }
Exemplo n.º 3
0
        /// <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);
        }
Exemplo n.º 4
0
        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);
        }