Beispiel #1
0
        /// <inheritdoc/>
        public ValueTask <TScope?> FindByIdAsync(string identifier, CancellationToken cancellationToken)
        {
            if (string.IsNullOrEmpty(identifier))
            {
                throw new ArgumentException(SR.GetResourceString(SR.ID0195), nameof(identifier));
            }

            var parameters = new
            {
                Method     = nameof(FindByIdAsync),
                Identifier = identifier
            };

            if (_cache.TryGetValue(parameters, out TScope? scope))
            {
                return(new ValueTask <TScope?>(scope));
            }

            return(new ValueTask <TScope?>(ExecuteAsync()));

            async Task <TScope?> ExecuteAsync()
            {
                if ((scope = await _store.FindByIdAsync(identifier, cancellationToken)) is not null)
                {
                    await AddAsync(scope, cancellationToken);
                }

                await CreateEntryAsync(parameters, scope, cancellationToken);

                return(scope);
            }
        }
Beispiel #2
0
        /// <summary>
        /// Retrieves a scope using its unique identifier.
        /// </summary>
        /// <param name="identifier">The unique identifier associated with the scope.</param>
        /// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
        /// <returns>
        /// A <see cref="ValueTask{TResult}"/> that can be used to monitor the asynchronous operation,
        /// whose result returns the scope corresponding to the identifier.
        /// </returns>
        public ValueTask <TScope> FindByIdAsync([NotNull] string identifier, CancellationToken cancellationToken)
        {
            if (string.IsNullOrEmpty(identifier))
            {
                throw new ArgumentException("The identifier cannot be null or empty.", nameof(identifier));
            }

            var parameters = new
            {
                Method     = nameof(FindByIdAsync),
                Identifier = identifier
            };

            if (_cache.TryGetValue(parameters, out TScope scope))
            {
                return(new ValueTask <TScope>(scope));
            }

            async Task <TScope> ExecuteAsync()
            {
                if ((scope = await _store.FindByIdAsync(identifier, cancellationToken)) != null)
                {
                    await AddAsync(scope, cancellationToken);
                }

                await CreateEntryAsync(parameters, scope, cancellationToken);

                return(scope);
            }

            return(new ValueTask <TScope>(ExecuteAsync()));
        }
Beispiel #3
0
        /// <summary>
        /// Retrieves a scope using its unique identifier.
        /// </summary>
        /// <param name="identifier">The unique identifier associated with the scope.</param>
        /// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
        /// <returns>
        /// A <see cref="ValueTask{TResult}"/> that can be used to monitor the asynchronous operation,
        /// whose result returns the scope corresponding to the identifier.
        /// </returns>
        public ValueTask <TScope> FindByIdAsync([NotNull] string identifier, CancellationToken cancellationToken)
        {
            if (string.IsNullOrEmpty(identifier))
            {
                throw new ArgumentException("The identifier cannot be null or empty.", nameof(identifier));
            }

            var parameters = new
            {
                Method     = nameof(FindByIdAsync),
                Identifier = identifier
            };

            if (_cache.TryGetValue(parameters, out TScope scope))
            {
                return(new ValueTask <TScope>(scope));
            }

            async Task <TScope> ExecuteAsync()
            {
                if ((scope = await _store.FindByIdAsync(identifier, cancellationToken)) != null)
                {
                    await AddAsync(scope, cancellationToken);
                }

                using (var entry = _cache.CreateEntry(parameters))
                {
                    if (scope != null)
                    {
                        var signal = await CreateExpirationSignalAsync(scope, cancellationToken);

                        if (signal == null)
                        {
                            throw new InvalidOperationException("An error occurred while creating an expiration signal.");
                        }

                        entry.AddExpirationToken(signal);
                    }

                    entry.SetSize(1L);
                    entry.SetValue(scope);
                }

                return(scope);
            }

            return(new ValueTask <TScope>(ExecuteAsync()));
        }