Ejemplo n.º 1
0
        /// <summary>Generates or gets the cached Swagger specification.</summary>
        /// <param name="context">The context.</param>
        /// <returns>The Swagger specification.</returns>
        protected virtual async Task <string> GetDocumentAsync(HttpContext context)
        {
            var documentKey = _settings.CreateDocumentCacheKey?.Invoke(context.Request) ?? string.Empty;

            Tuple <string, ExceptionDispatchInfo, DateTimeOffset> document;

            lock (_documentsCacheLock)
            {
                _documentsCache.TryGetValue(documentKey, out document);
            }

            if (document?.Item2 != null &&
                document.Item3 + _settings.ExceptionCacheTime > DateTimeOffset.UtcNow)
            {
                document.Item2.Throw();
            }

            var apiDescriptionGroups = _apiDescriptionGroupCollectionProvider.ApiDescriptionGroups;

            if (apiDescriptionGroups.Version == Volatile.Read(ref _version) &&
                document?.Item1 != null)
            {
                return(document.Item1);
            }

            try
            {
                var openApiDocument = await GenerateDocumentAsync(context);

                var data = _path.ToLowerInvariant().Contains(".yaml") ?
                           OpenApiYamlDocument.ToYaml(openApiDocument) :
                           openApiDocument.ToJson();

                XmlDocs.ClearCache();
                CachedType.ClearCache();

                _version = apiDescriptionGroups.Version;

                lock (_documentsCacheLock)
                {
                    _documentsCache[documentKey] = new Tuple <string, ExceptionDispatchInfo, DateTimeOffset>(
                        data, null, DateTimeOffset.UtcNow);
                }

                return(data);
            }
            catch (Exception exception)
            {
                lock (_documentsCacheLock)
                {
                    _documentsCache[documentKey] = new Tuple <string, ExceptionDispatchInfo, DateTimeOffset>(
                        null, ExceptionDispatchInfo.Capture(exception), DateTimeOffset.UtcNow);
                }

                throw;
            }
        }