Ejemplo n.º 1
0
        /// <summary>
        /// Returns the item uniquely identified by <paramref name="id"/> from storage.
        /// The class will remember its values, so we know how to deal with a later call to <see cref="SaveAsync(TId,TModel,System.Threading.CancellationToken)"/>.
        /// </summary>
        /// <returns>The found item or null.</returns>
        public async Task <TModel> ReadAsync(TId id, CancellationToken cancellationToken = default)
        {
            var item = await _readService.ReadAsync(id, cancellationToken);

            if (item == null)
            {
                return(null);
            }
            AddOrUpdateWithCopy(id, item, true);
            return(item);
        }
        /// <summary>
        /// Read and cache the item, but only if we have an aggressive caching strategy.
        /// </summary>
        /// <param name="id">The id of the item.</param>
        /// <param name="service">A service to use for reading the item.</param>
        /// <param name="token">Propagates notification that operations should be canceled</param>
        protected async Task CacheMaybeSetAsync(TId id, IRead <TModel, TId> service, CancellationToken token = default(CancellationToken))
        {
            async Task <bool> IsAlreadyCachedAndGetIsOkToUpdate()
            {
                return(Options.DoGetToUpdate && await CacheItemExistsAsync(id, token));
            }

            var getAndSave = Options.SaveAll || await IsAlreadyCachedAndGetIsOkToUpdate();

            if (!getAndSave)
            {
                return;
            }
            var item = await service.ReadAsync(id, token);

            await CacheSetByIdAsync(id, item, token);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// If <paramref name="item"/> implements <see cref="IOptimisticConcurrencyControlByETag"/>
        /// then the old value is read using <paramref name="service"/> and the values are verified to be equal.
        /// The Etag of the item is then set to a new value.
        /// </summary>
        /// <param name="id"></param>
        /// <param name="item"></param>
        /// <param name="service"></param>
        /// <param name="token">Propagates notification that operations should be canceled</param>
        /// <returns></returns>
        protected virtual async Task <TModel> MaybeVerifyEtagForUpdateAsync(TId id, TModel item, IRead <TModel, TId> service, CancellationToken token = default(CancellationToken))
        {
            var oldItem = await service.ReadAsync(id, token);

            if (!(item is IOptimisticConcurrencyControlByETag etaggable))
            {
                return(oldItem);
            }
            if (Equals(oldItem, default(TModel)))
            {
                return(oldItem);
            }
            var oldEtag = (oldItem as IOptimisticConcurrencyControlByETag)?.Etag;

            if (oldEtag?.ToLowerInvariant() != etaggable.Etag?.ToLowerInvariant())
            {
                throw new FulcrumConflictException($"The updated item ({item}) had an old ETag value.");
            }

            return(oldItem);
        }