More clean up
This commit is contained in:
parent
4e743ef666
commit
48f640088b
@ -1,28 +0,0 @@
|
|||||||
(function ($, swaggerUi) {
|
|
||||||
$(function () {
|
|
||||||
var settings = {
|
|
||||||
authority: 'https://localhost:5105',
|
|
||||||
client_id: 'js',
|
|
||||||
popup_redirect_uri: window.location.protocol
|
|
||||||
+ '//'
|
|
||||||
+ window.location.host
|
|
||||||
+ '/tokenclient/popup.html',
|
|
||||||
|
|
||||||
response_type: 'id_token token',
|
|
||||||
scope: 'openid profile basket',
|
|
||||||
|
|
||||||
filter_protocol_claims: true
|
|
||||||
},
|
|
||||||
manager = new OidcTokenManager(settings),
|
|
||||||
$inputApiKey = $('#input_apiKey');
|
|
||||||
|
|
||||||
$inputApiKey.on('dblclick', function () {
|
|
||||||
manager.openPopupForTokenAsync()
|
|
||||||
.then(function () {
|
|
||||||
$inputApiKey.val(manager.access_token).change();
|
|
||||||
}, function (error) {
|
|
||||||
console.error(error);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
})(jQuery, window.swaggerUi);
|
|
File diff suppressed because one or more lines are too long
@ -1,13 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title></title>
|
|
||||||
<meta charset="utf-8" />
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<script type="text/javascript" src="oidc-token-manager.min.js"></script>
|
|
||||||
<script type="text/javascript">
|
|
||||||
new OidcTokenManager().processTokenPopup();
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,25 +0,0 @@
|
|||||||
namespace Microsoft.eShopOnContainers.Services.Basket.API.Auth.Server;
|
|
||||||
|
|
||||||
public class AuthorizationHeaderParameterOperationFilter : IOperationFilter
|
|
||||||
{
|
|
||||||
public void Apply(OpenApiOperation operation, OperationFilterContext context)
|
|
||||||
{
|
|
||||||
var filterPipeline = context.ApiDescription.ActionDescriptor.FilterDescriptors;
|
|
||||||
var isAuthorized = filterPipeline.Select(filterInfo => filterInfo.Filter).Any(filter => filter is AuthorizeFilter);
|
|
||||||
var allowAnonymous = filterPipeline.Select(filterInfo => filterInfo.Filter).Any(filter => filter is IAllowAnonymousFilter);
|
|
||||||
|
|
||||||
if (isAuthorized && !allowAnonymous)
|
|
||||||
{
|
|
||||||
operation.Parameters ??= new List<OpenApiParameter>();
|
|
||||||
|
|
||||||
|
|
||||||
operation.Parameters.Add(new OpenApiParameter
|
|
||||||
{
|
|
||||||
Name = "Authorization",
|
|
||||||
In = ParameterLocation.Header,
|
|
||||||
Description = "access token",
|
|
||||||
Required = true
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,8 +1,15 @@
|
|||||||
global using Autofac;
|
global using System;
|
||||||
|
global using System.Collections.Generic;
|
||||||
|
global using System.ComponentModel.DataAnnotations;
|
||||||
|
global using System.Linq;
|
||||||
|
global using System.Net;
|
||||||
|
global using System.Security.Claims;
|
||||||
|
global using System.Text.Json;
|
||||||
|
global using System.Threading.Tasks;
|
||||||
|
global using Autofac;
|
||||||
global using Basket.API.Infrastructure.ActionResults;
|
global using Basket.API.Infrastructure.ActionResults;
|
||||||
global using Basket.API.Infrastructure.Exceptions;
|
global using Basket.API.Infrastructure.Exceptions;
|
||||||
global using Basket.API.Infrastructure.Filters;
|
global using Basket.API.Infrastructure.Filters;
|
||||||
global using Basket.API.Infrastructure.Middlewares;
|
|
||||||
global using Basket.API.IntegrationEvents.EventHandling;
|
global using Basket.API.IntegrationEvents.EventHandling;
|
||||||
global using Basket.API.IntegrationEvents.Events;
|
global using Basket.API.IntegrationEvents.Events;
|
||||||
global using Basket.API.Model;
|
global using Basket.API.Model;
|
||||||
@ -12,32 +19,19 @@ global using Microsoft.AspNetCore.Authorization;
|
|||||||
global using Microsoft.AspNetCore.Builder;
|
global using Microsoft.AspNetCore.Builder;
|
||||||
global using Microsoft.AspNetCore.Hosting;
|
global using Microsoft.AspNetCore.Hosting;
|
||||||
global using Microsoft.AspNetCore.Http;
|
global using Microsoft.AspNetCore.Http;
|
||||||
global using Microsoft.AspNetCore.Mvc.Authorization;
|
|
||||||
global using Microsoft.AspNetCore.Mvc.Filters;
|
|
||||||
global using Microsoft.AspNetCore.Mvc;
|
global using Microsoft.AspNetCore.Mvc;
|
||||||
|
global using Microsoft.AspNetCore.Mvc.Filters;
|
||||||
global using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
|
global using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
|
||||||
global using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
|
global using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
|
||||||
|
global using Microsoft.eShopOnContainers.Services.Basket.API;
|
||||||
global using Microsoft.eShopOnContainers.Services.Basket.API.Infrastructure.Repositories;
|
global using Microsoft.eShopOnContainers.Services.Basket.API.Infrastructure.Repositories;
|
||||||
global using Microsoft.eShopOnContainers.Services.Basket.API.IntegrationEvents.EventHandling;
|
global using Microsoft.eShopOnContainers.Services.Basket.API.IntegrationEvents.EventHandling;
|
||||||
global using Microsoft.eShopOnContainers.Services.Basket.API.IntegrationEvents.Events;
|
global using Microsoft.eShopOnContainers.Services.Basket.API.IntegrationEvents.Events;
|
||||||
global using Microsoft.eShopOnContainers.Services.Basket.API.Model;
|
global using Microsoft.eShopOnContainers.Services.Basket.API.Model;
|
||||||
global using Microsoft.eShopOnContainers.Services.Basket.API.Services;
|
global using Microsoft.eShopOnContainers.Services.Basket.API.Services;
|
||||||
global using Microsoft.eShopOnContainers.Services.Basket.API;
|
|
||||||
global using Microsoft.Extensions.Configuration;
|
global using Microsoft.Extensions.Configuration;
|
||||||
global using Microsoft.Extensions.DependencyInjection;
|
global using Microsoft.Extensions.DependencyInjection;
|
||||||
global using Microsoft.Extensions.Hosting;
|
global using Microsoft.Extensions.Hosting;
|
||||||
global using Microsoft.Extensions.Logging;
|
global using Microsoft.Extensions.Logging;
|
||||||
global using Microsoft.OpenApi.Models;
|
|
||||||
global using Serilog.Context;
|
global using Serilog.Context;
|
||||||
global using Serilog;
|
|
||||||
global using StackExchange.Redis;
|
global using StackExchange.Redis;
|
||||||
global using Swashbuckle.AspNetCore.SwaggerGen;
|
|
||||||
global using System.Collections.Generic;
|
|
||||||
global using System.ComponentModel.DataAnnotations;
|
|
||||||
global using System.IO;
|
|
||||||
global using System.Linq;
|
|
||||||
global using System.Net;
|
|
||||||
global using System.Security.Claims;
|
|
||||||
global using System.Text.Json;
|
|
||||||
global using System.Threading.Tasks;
|
|
||||||
global using System;
|
|
||||||
|
@ -1,18 +0,0 @@
|
|||||||
namespace Basket.API.Infrastructure.Middlewares;
|
|
||||||
|
|
||||||
public static class FailingMiddlewareAppBuilderExtensions
|
|
||||||
{
|
|
||||||
public static IApplicationBuilder UseFailingMiddleware(this IApplicationBuilder builder)
|
|
||||||
{
|
|
||||||
return UseFailingMiddleware(builder, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static IApplicationBuilder UseFailingMiddleware(this IApplicationBuilder builder, Action<FailingOptions> action)
|
|
||||||
{
|
|
||||||
var options = new FailingOptions();
|
|
||||||
action?.Invoke(options);
|
|
||||||
builder.UseMiddleware<FailingMiddleware>(options);
|
|
||||||
return builder;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,29 +0,0 @@
|
|||||||
namespace Basket.API.Infrastructure.Filters;
|
|
||||||
|
|
||||||
public class AuthorizeCheckOperationFilter : IOperationFilter
|
|
||||||
{
|
|
||||||
public void Apply(OpenApiOperation operation, OperationFilterContext context)
|
|
||||||
{
|
|
||||||
// Check for authorize attribute
|
|
||||||
var hasAuthorize = context.MethodInfo.DeclaringType.GetCustomAttributes(true).OfType<AuthorizeAttribute>().Any() ||
|
|
||||||
context.MethodInfo.GetCustomAttributes(true).OfType<AuthorizeAttribute>().Any();
|
|
||||||
|
|
||||||
if (!hasAuthorize) return;
|
|
||||||
|
|
||||||
operation.Responses.TryAdd("401", new OpenApiResponse { Description = "Unauthorized" });
|
|
||||||
operation.Responses.TryAdd("403", new OpenApiResponse { Description = "Forbidden" });
|
|
||||||
|
|
||||||
var oAuthScheme = new OpenApiSecurityScheme
|
|
||||||
{
|
|
||||||
Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "oauth2" }
|
|
||||||
};
|
|
||||||
|
|
||||||
operation.Security = new List<OpenApiSecurityRequirement>
|
|
||||||
{
|
|
||||||
new()
|
|
||||||
{
|
|
||||||
[ oAuthScheme ] = new [] { "basketapi" }
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,90 +0,0 @@
|
|||||||
namespace Basket.API.Infrastructure.Middlewares;
|
|
||||||
|
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
|
|
||||||
public class FailingMiddleware
|
|
||||||
{
|
|
||||||
private readonly RequestDelegate _next;
|
|
||||||
private bool _mustFail;
|
|
||||||
private readonly FailingOptions _options;
|
|
||||||
private readonly ILogger _logger;
|
|
||||||
|
|
||||||
public FailingMiddleware(RequestDelegate next, ILogger<FailingMiddleware> logger, FailingOptions options)
|
|
||||||
{
|
|
||||||
_next = next;
|
|
||||||
_options = options;
|
|
||||||
_mustFail = false;
|
|
||||||
_logger = logger;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task Invoke(HttpContext context)
|
|
||||||
{
|
|
||||||
var path = context.Request.Path;
|
|
||||||
if (path.Equals(_options.ConfigPath, StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
await ProcessConfigRequest(context);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (MustFail(context))
|
|
||||||
{
|
|
||||||
_logger.LogInformation("Response for path {Path} will fail.", path);
|
|
||||||
context.Response.StatusCode = (int)System.Net.HttpStatusCode.InternalServerError;
|
|
||||||
context.Response.ContentType = "text/plain";
|
|
||||||
await context.Response.WriteAsync("Failed due to FailingMiddleware enabled.");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
await _next.Invoke(context);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task ProcessConfigRequest(HttpContext context)
|
|
||||||
{
|
|
||||||
var enable = context.Request.Query.Keys.Any(k => k == "enable");
|
|
||||||
var disable = context.Request.Query.Keys.Any(k => k == "disable");
|
|
||||||
|
|
||||||
if (enable && disable)
|
|
||||||
{
|
|
||||||
throw new ArgumentException("Must use enable or disable querystring values, but not both");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (disable)
|
|
||||||
{
|
|
||||||
_mustFail = false;
|
|
||||||
await SendOkResponse(context, "FailingMiddleware disabled. Further requests will be processed.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (enable)
|
|
||||||
{
|
|
||||||
_mustFail = true;
|
|
||||||
await SendOkResponse(context, "FailingMiddleware enabled. Further requests will return HTTP 500");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If reach here, that means that no valid parameter has been passed. Just output status
|
|
||||||
await SendOkResponse(context, string.Format("FailingMiddleware is {0}", _mustFail ? "enabled" : "disabled"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task SendOkResponse(HttpContext context, string message)
|
|
||||||
{
|
|
||||||
context.Response.StatusCode = (int)System.Net.HttpStatusCode.OK;
|
|
||||||
context.Response.ContentType = "text/plain";
|
|
||||||
await context.Response.WriteAsync(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool MustFail(HttpContext context)
|
|
||||||
{
|
|
||||||
var rpath = context.Request.Path.Value;
|
|
||||||
|
|
||||||
if (_options.NotFilteredPaths.Any(p => p.Equals(rpath, StringComparison.InvariantCultureIgnoreCase)))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return _mustFail &&
|
|
||||||
(_options.EndpointPaths.Any(x => x == rpath)
|
|
||||||
|| _options.EndpointPaths.Count == 0);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,10 +0,0 @@
|
|||||||
namespace Basket.API.Infrastructure.Middlewares;
|
|
||||||
|
|
||||||
public class FailingOptions
|
|
||||||
{
|
|
||||||
public string ConfigPath = "/Failing";
|
|
||||||
public List<string> EndpointPaths { get; set; } = new List<string>();
|
|
||||||
|
|
||||||
public List<string> NotFilteredPaths { get; set; } = new List<string>();
|
|
||||||
}
|
|
||||||
|
|
@ -1,20 +0,0 @@
|
|||||||
namespace Basket.API.Infrastructure.Middlewares;
|
|
||||||
|
|
||||||
public class FailingStartupFilter : IStartupFilter
|
|
||||||
{
|
|
||||||
private readonly Action<FailingOptions> _options;
|
|
||||||
public FailingStartupFilter(Action<FailingOptions> optionsAction)
|
|
||||||
{
|
|
||||||
_options = optionsAction;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Action<IApplicationBuilder> Configure(Action<IApplicationBuilder> next)
|
|
||||||
{
|
|
||||||
return app =>
|
|
||||||
{
|
|
||||||
app.UseFailingMiddleware(_options);
|
|
||||||
next(app);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
|||||||
namespace Basket.API.Infrastructure.Middlewares;
|
|
||||||
|
|
||||||
public static class WebHostBuildertExtensions
|
|
||||||
{
|
|
||||||
public static IWebHostBuilder UseFailing(this IWebHostBuilder builder, Action<FailingOptions> options)
|
|
||||||
{
|
|
||||||
builder.ConfigureServices(services =>
|
|
||||||
{
|
|
||||||
services.AddSingleton<IStartupFilter>(new FailingStartupFilter(options));
|
|
||||||
});
|
|
||||||
return builder;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -45,7 +45,6 @@
|
|||||||
<PackageReference Include="AspNetCore.HealthChecks.Rabbitmq" />
|
<PackageReference Include="AspNetCore.HealthChecks.Rabbitmq" />
|
||||||
<PackageReference Include="AspNetCore.HealthChecks.SqlServer" />
|
<PackageReference Include="AspNetCore.HealthChecks.SqlServer" />
|
||||||
<PackageReference Include="AspNetCore.HealthChecks.UI.Client" />
|
<PackageReference Include="AspNetCore.HealthChecks.UI.Client" />
|
||||||
<PackageReference Include="Autofac.Extensions.DependencyInjection" />
|
|
||||||
<PackageReference Include="Google.Protobuf" />
|
<PackageReference Include="Google.Protobuf" />
|
||||||
<PackageReference Include="Grpc.AspNetCore.Server" />
|
<PackageReference Include="Grpc.AspNetCore.Server" />
|
||||||
<PackageReference Include="Grpc.Tools" PrivateAssets="All" />
|
<PackageReference Include="Grpc.Tools" PrivateAssets="All" />
|
||||||
|
@ -1,48 +1,47 @@
|
|||||||
global using Autofac;
|
global using System;
|
||||||
global using Microsoft.eShopOnContainers.Services.Catalog.API.Extensions;
|
|
||||||
global using Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure.ActionResults;
|
|
||||||
global using Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure.Exceptions;
|
|
||||||
global using Microsoft.eShopOnContainers.Services.Catalog.API.IntegrationEvents;
|
|
||||||
global using Grpc.Core;
|
|
||||||
global using Microsoft.AspNetCore.Hosting;
|
|
||||||
global using Microsoft.AspNetCore.Http;
|
|
||||||
global using Microsoft.AspNetCore.Builder;
|
|
||||||
global using Microsoft.AspNetCore.Mvc.Filters;
|
|
||||||
global using Microsoft.AspNetCore.Mvc;
|
|
||||||
global using Microsoft.Extensions.Logging;
|
|
||||||
global using Microsoft.EntityFrameworkCore.Design;
|
|
||||||
global using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
|
||||||
global using Microsoft.EntityFrameworkCore;
|
|
||||||
global using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
|
|
||||||
global using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
|
|
||||||
global using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF.Services;
|
|
||||||
global using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF.Utilities;
|
|
||||||
global using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF;
|
|
||||||
global using Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure;
|
|
||||||
global using Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure.EntityConfigurations;
|
|
||||||
global using Microsoft.eShopOnContainers.Services.Catalog.API;
|
|
||||||
global using Microsoft.eShopOnContainers.Services.Catalog.API.IntegrationEvents.Events;
|
|
||||||
global using Microsoft.eShopOnContainers.Services.Catalog.API.Model;
|
|
||||||
global using Microsoft.eShopOnContainers.Services.Catalog.API.ViewModel;
|
|
||||||
global using Microsoft.eShopOnContainers.Services.Catalog.API.Grpc;
|
|
||||||
global using Microsoft.Extensions.Configuration;
|
|
||||||
global using Microsoft.Extensions.DependencyInjection;
|
|
||||||
global using Microsoft.Extensions.Hosting;
|
|
||||||
global using Microsoft.Extensions.Options;
|
|
||||||
global using Polly.Retry;
|
|
||||||
global using Polly;
|
|
||||||
global using Serilog.Context;
|
|
||||||
global using System.Collections.Generic;
|
global using System.Collections.Generic;
|
||||||
global using System.Data.Common;
|
global using System.Data.Common;
|
||||||
global using System.Data.SqlClient;
|
global using System.Data.SqlClient;
|
||||||
global using System.Globalization;
|
global using System.Globalization;
|
||||||
global using System.IO.Compression;
|
|
||||||
global using System.IO;
|
global using System.IO;
|
||||||
|
global using System.IO.Compression;
|
||||||
global using System.Linq;
|
global using System.Linq;
|
||||||
global using System.Net;
|
global using System.Net;
|
||||||
global using System.Text.RegularExpressions;
|
global using System.Text.RegularExpressions;
|
||||||
global using System.Threading.Tasks;
|
global using System.Threading.Tasks;
|
||||||
global using System;
|
global using Grpc.Core;
|
||||||
|
global using Microsoft.AspNetCore.Builder;
|
||||||
|
global using Microsoft.AspNetCore.Hosting;
|
||||||
|
global using Microsoft.AspNetCore.Http;
|
||||||
|
global using Microsoft.AspNetCore.Mvc;
|
||||||
|
global using Microsoft.AspNetCore.Mvc.Filters;
|
||||||
|
global using Microsoft.EntityFrameworkCore;
|
||||||
|
global using Microsoft.EntityFrameworkCore.Design;
|
||||||
|
global using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||||
|
global using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
|
||||||
|
global using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
|
||||||
|
global using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF;
|
||||||
|
global using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF.Services;
|
||||||
|
global using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF.Utilities;
|
||||||
|
global using Microsoft.eShopOnContainers.Services.Catalog.API;
|
||||||
|
global using Microsoft.eShopOnContainers.Services.Catalog.API.Extensions;
|
||||||
|
global using Microsoft.eShopOnContainers.Services.Catalog.API.Grpc;
|
||||||
|
global using Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure;
|
||||||
|
global using Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure.ActionResults;
|
||||||
|
global using Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure.EntityConfigurations;
|
||||||
|
global using Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure.Exceptions;
|
||||||
global using Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure.Filters;
|
global using Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure.Filters;
|
||||||
|
global using Microsoft.eShopOnContainers.Services.Catalog.API.IntegrationEvents;
|
||||||
global using Microsoft.eShopOnContainers.Services.Catalog.API.IntegrationEvents.EventHandling;
|
global using Microsoft.eShopOnContainers.Services.Catalog.API.IntegrationEvents.EventHandling;
|
||||||
|
global using Microsoft.eShopOnContainers.Services.Catalog.API.IntegrationEvents.Events;
|
||||||
|
global using Microsoft.eShopOnContainers.Services.Catalog.API.Model;
|
||||||
|
global using Microsoft.eShopOnContainers.Services.Catalog.API.ViewModel;
|
||||||
|
global using Microsoft.Extensions.Configuration;
|
||||||
|
global using Microsoft.Extensions.DependencyInjection;
|
||||||
global using Microsoft.Extensions.FileProviders;
|
global using Microsoft.Extensions.FileProviders;
|
||||||
|
global using Microsoft.Extensions.Hosting;
|
||||||
|
global using Microsoft.Extensions.Logging;
|
||||||
|
global using Microsoft.Extensions.Options;
|
||||||
|
global using Polly;
|
||||||
|
global using Polly.Retry;
|
||||||
|
global using Serilog.Context;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user