Remove gRPC generated code from global usings etc
This commit is contained in:
parent
d91da03665
commit
109853983d
@ -2,7 +2,6 @@
|
||||
global using Grpc.Core.Interceptors;
|
||||
global using Grpc.Core;
|
||||
global using GrpcBasket;
|
||||
global using GrpcOrdering;
|
||||
global using HealthChecks.UI.Client;
|
||||
global using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||
global using Microsoft.AspNetCore.Authentication;
|
||||
@ -38,4 +37,4 @@ global using System.Text.Json;
|
||||
global using System.Threading.Tasks;
|
||||
global using System.Threading;
|
||||
global using System;
|
||||
global using Microsoft.IdentityModel.Tokens;
|
||||
global using Microsoft.IdentityModel.Tokens;
|
||||
|
@ -2,10 +2,10 @@
|
||||
|
||||
public class OrderingService : IOrderingService
|
||||
{
|
||||
private readonly OrderingGrpc.OrderingGrpcClient _orderingGrpcClient;
|
||||
private readonly GrpcOrdering.OrderingGrpc.OrderingGrpcClient _orderingGrpcClient;
|
||||
private readonly ILogger<OrderingService> _logger;
|
||||
|
||||
public OrderingService(OrderingGrpc.OrderingGrpcClient orderingGrpcClient, ILogger<OrderingService> logger)
|
||||
public OrderingService(GrpcOrdering.OrderingGrpc.OrderingGrpcClient orderingGrpcClient, ILogger<OrderingService> logger)
|
||||
{
|
||||
_orderingGrpcClient = orderingGrpcClient;
|
||||
_logger = logger;
|
||||
@ -48,14 +48,14 @@ public class OrderingService : IOrderingService
|
||||
return data;
|
||||
}
|
||||
|
||||
private CreateOrderDraftCommand MapToOrderDraftCommand(BasketData basketData)
|
||||
private GrpcOrdering.CreateOrderDraftCommand MapToOrderDraftCommand(BasketData basketData)
|
||||
{
|
||||
var command = new CreateOrderDraftCommand
|
||||
var command = new GrpcOrdering.CreateOrderDraftCommand
|
||||
{
|
||||
BuyerId = basketData.BuyerId,
|
||||
};
|
||||
|
||||
basketData.Items.ForEach(i => command.Items.Add(new BasketItem
|
||||
basketData.Items.ForEach(i => command.Items.Add(new GrpcOrdering.BasketItem
|
||||
{
|
||||
Id = i.Id,
|
||||
OldUnitPrice = (double)i.OldUnitPrice,
|
||||
|
@ -198,7 +198,7 @@ public static class ServiceCollectionExtensions
|
||||
|
||||
services.AddScoped<IOrderingService, OrderingService>();
|
||||
|
||||
services.AddGrpcClient<OrderingGrpc.OrderingGrpcClient>((services, options) =>
|
||||
services.AddGrpcClient<GrpcOrdering.OrderingGrpc.OrderingGrpcClient>((services, options) =>
|
||||
{
|
||||
var orderingApi = services.GetRequiredService<IOptions<UrlsConfig>>().Value.GrpcOrdering;
|
||||
options.Address = new Uri(orderingApi);
|
||||
|
@ -2,7 +2,6 @@
|
||||
global using Grpc.Core.Interceptors;
|
||||
global using Grpc.Core;
|
||||
global using GrpcBasket;
|
||||
global using GrpcOrdering;
|
||||
global using HealthChecks.UI.Client;
|
||||
global using Microsoft.AspNetCore.Authentication;
|
||||
global using Microsoft.AspNetCore.Authorization;
|
||||
@ -38,4 +37,4 @@ global using System.Threading.Tasks;
|
||||
global using System.Threading;
|
||||
global using System;
|
||||
global using Microsoft.IdentityModel.Tokens;
|
||||
global using Serilog.Context;
|
||||
global using Serilog.Context;
|
||||
|
@ -1,5 +1,4 @@
|
||||
var appName = "Web.Shopping.HttpAggregator";
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
builder.Host.UseSerilog(CreateSerilogLogger(builder.Configuration));
|
||||
builder.Services.AddHealthChecks()
|
||||
@ -197,7 +196,7 @@ public static class ServiceCollectionExtensions
|
||||
|
||||
services.AddScoped<IOrderingService, OrderingService>();
|
||||
|
||||
services.AddGrpcClient<OrderingGrpc.OrderingGrpcClient>((services, options) =>
|
||||
services.AddGrpcClient<GrpcOrdering.OrderingGrpc.OrderingGrpcClient>((services, options) =>
|
||||
{
|
||||
var orderingApi = services.GetRequiredService<IOptions<UrlsConfig>>().Value.GrpcOrdering;
|
||||
options.Address = new Uri(orderingApi);
|
||||
|
@ -2,10 +2,10 @@
|
||||
|
||||
public class OrderingService : IOrderingService
|
||||
{
|
||||
private readonly OrderingGrpc.OrderingGrpcClient _orderingGrpcClient;
|
||||
private readonly GrpcOrdering.OrderingGrpc.OrderingGrpcClient _orderingGrpcClient;
|
||||
private readonly ILogger<OrderingService> _logger;
|
||||
|
||||
public OrderingService(OrderingGrpc.OrderingGrpcClient orderingGrpcClient, ILogger<OrderingService> logger)
|
||||
public OrderingService(GrpcOrdering.OrderingGrpc.OrderingGrpcClient orderingGrpcClient, ILogger<OrderingService> logger)
|
||||
{
|
||||
_orderingGrpcClient = orderingGrpcClient;
|
||||
_logger = logger;
|
||||
@ -48,14 +48,14 @@ public class OrderingService : IOrderingService
|
||||
return data;
|
||||
}
|
||||
|
||||
private CreateOrderDraftCommand MapToOrderDraftCommand(BasketData basketData)
|
||||
private GrpcOrdering.CreateOrderDraftCommand MapToOrderDraftCommand(BasketData basketData)
|
||||
{
|
||||
var command = new CreateOrderDraftCommand
|
||||
var command = new GrpcOrdering.CreateOrderDraftCommand
|
||||
{
|
||||
BuyerId = basketData.BuyerId,
|
||||
};
|
||||
|
||||
basketData.Items.ForEach(i => command.Items.Add(new BasketItem
|
||||
basketData.Items.ForEach(i => command.Items.Add(new GrpcOrdering.BasketItem
|
||||
{
|
||||
Id = i.Id,
|
||||
OldUnitPrice = (double)i.OldUnitPrice,
|
||||
|
@ -14,7 +14,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<Content Update="appsettings.json">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="wwwroot;">
|
||||
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||
@ -25,10 +25,8 @@
|
||||
<Content Include="Setup\**\*;">
|
||||
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||
</Content>
|
||||
<Content Remove="Setup\Catalogitems - Copy.zip" />
|
||||
<None Remove="Setup\Catalogitems - Copy.zip" />
|
||||
<Compile Include="IntegrationEvents\EventHandling\AnyFutureIntegrationEventHandler.cs.txt" />
|
||||
<Content Update="web.config;">
|
||||
<None Include="IntegrationEvents\EventHandling\AnyFutureIntegrationEventHandler.cs.txt" />
|
||||
<Content Update="web.config">
|
||||
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
@ -2,15 +2,15 @@
|
||||
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
public class TransactionBehaviour<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse> where TRequest : IRequest<TResponse>
|
||||
public class TransactionBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse> where TRequest : IRequest<TResponse>
|
||||
{
|
||||
private readonly ILogger<TransactionBehaviour<TRequest, TResponse>> _logger;
|
||||
private readonly ILogger<TransactionBehavior<TRequest, TResponse>> _logger;
|
||||
private readonly OrderingContext _dbContext;
|
||||
private readonly IOrderingIntegrationEventService _orderingIntegrationEventService;
|
||||
|
||||
public TransactionBehaviour(OrderingContext dbContext,
|
||||
public TransactionBehavior(OrderingContext dbContext,
|
||||
IOrderingIntegrationEventService orderingIntegrationEventService,
|
||||
ILogger<TransactionBehaviour<TRequest, TResponse>> logger)
|
||||
ILogger<TransactionBehavior<TRequest, TResponse>> logger)
|
||||
{
|
||||
_dbContext = dbContext ?? throw new ArgumentException(nameof(OrderingContext));
|
||||
_orderingIntegrationEventService = orderingIntegrationEventService ?? throw new ArgumentException(nameof(orderingIntegrationEventService));
|
@ -10,6 +10,7 @@
|
||||
// https://docs.microsoft.com/dotnet/csharp/programming-guide/classes-and-structs/how-to-implement-a-lightweight-class-with-auto-implemented-properties
|
||||
|
||||
using Microsoft.eShopOnContainers.Services.Ordering.API.Application.Models;
|
||||
using Microsoft.eShopOnContainers.Services.Ordering.API.Extensions;
|
||||
|
||||
[DataContract]
|
||||
public class CreateOrderCommand
|
||||
@ -80,21 +81,5 @@ public class CreateOrderCommand
|
||||
CardSecurityNumber = cardSecurityNumber;
|
||||
CardTypeId = cardTypeId;
|
||||
}
|
||||
|
||||
|
||||
public record OrderItemDTO
|
||||
{
|
||||
public int ProductId { get; init; }
|
||||
|
||||
public string ProductName { get; init; }
|
||||
|
||||
public decimal UnitPrice { get; init; }
|
||||
|
||||
public decimal Discount { get; init; }
|
||||
|
||||
public int Units { get; init; }
|
||||
|
||||
public string PictureUrl { get; init; }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,6 @@ using Microsoft.eShopOnContainers.Services.Ordering.API.Application.Models;
|
||||
|
||||
public class CreateOrderDraftCommand : IRequest<OrderDraftDTO>
|
||||
{
|
||||
|
||||
public string BuyerId { get; private set; }
|
||||
|
||||
public IEnumerable<BasketItem> Items { get; private set; }
|
||||
|
@ -1,6 +1,6 @@
|
||||
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands;
|
||||
|
||||
using static Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands.CreateOrderCommand;
|
||||
using Microsoft.eShopOnContainers.Services.Ordering.API.Extensions;
|
||||
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate;
|
||||
|
||||
// Regular CommandHandler
|
||||
@ -42,5 +42,19 @@ public record OrderDraftDTO
|
||||
Total = order.GetTotal()
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
public record OrderItemDTO
|
||||
{
|
||||
public int ProductId { get; init; }
|
||||
|
||||
public string ProductName { get; init; }
|
||||
|
||||
public decimal UnitPrice { get; init; }
|
||||
|
||||
public decimal Discount { get; init; }
|
||||
|
||||
public int Units { get; init; }
|
||||
|
||||
public string PictureUrl { get; init; }
|
||||
}
|
||||
|
@ -6,7 +6,7 @@
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of the command handler that performs the operation if request is not duplicated</typeparam>
|
||||
/// <typeparam name="R">Return value of the inner command handler</typeparam>
|
||||
public class IdentifiedCommandHandler<T, R> : IRequestHandler<IdentifiedCommand<T, R>, R>
|
||||
public abstract class IdentifiedCommandHandler<T, R> : IRequestHandler<IdentifiedCommand<T, R>, R>
|
||||
where T : IRequest<R>
|
||||
{
|
||||
private readonly IMediator _mediator;
|
||||
@ -18,19 +18,17 @@ public class IdentifiedCommandHandler<T, R> : IRequestHandler<IdentifiedCommand<
|
||||
IRequestManager requestManager,
|
||||
ILogger<IdentifiedCommandHandler<T, R>> logger)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(logger);
|
||||
_mediator = mediator;
|
||||
_requestManager = requestManager;
|
||||
_logger = logger ?? throw new System.ArgumentNullException(nameof(logger));
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the result value to return if a previous request was found
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected virtual R CreateResultForDuplicateRequest()
|
||||
{
|
||||
return default(R);
|
||||
}
|
||||
protected abstract R CreateResultForDuplicateRequest();
|
||||
|
||||
/// <summary>
|
||||
/// This method handles the command. It just ensures that no other request exists with the same ID, and if this is the case
|
||||
|
@ -34,9 +34,9 @@ public class SetStockConfirmedOrderStatusCommandHandler : IRequestHandler<SetSto
|
||||
|
||||
|
||||
// Use for Idempotency in Command process
|
||||
public class SetStockConfirmedOrderStatusIdenfifiedCommandHandler : IdentifiedCommandHandler<SetStockConfirmedOrderStatusCommand, bool>
|
||||
public class SetStockConfirmedOrderStatusIdentifiedCommandHandler : IdentifiedCommandHandler<SetStockConfirmedOrderStatusCommand, bool>
|
||||
{
|
||||
public SetStockConfirmedOrderStatusIdenfifiedCommandHandler(
|
||||
public SetStockConfirmedOrderStatusIdentifiedCommandHandler(
|
||||
IMediator mediator,
|
||||
IRequestManager requestManager,
|
||||
ILogger<IdentifiedCommandHandler<SetStockConfirmedOrderStatusCommand, bool>> logger)
|
||||
|
@ -35,9 +35,9 @@ public class SetStockRejectedOrderStatusCommandHandler : IRequestHandler<SetStoc
|
||||
|
||||
|
||||
// Use for Idempotency in Command process
|
||||
public class SetStockRejectedOrderStatusIdenfifiedCommandHandler : IdentifiedCommandHandler<SetStockRejectedOrderStatusCommand, bool>
|
||||
public class SetStockRejectedOrderStatusIdentifiedCommandHandler : IdentifiedCommandHandler<SetStockRejectedOrderStatusCommand, bool>
|
||||
{
|
||||
public SetStockRejectedOrderStatusIdenfifiedCommandHandler(
|
||||
public SetStockRejectedOrderStatusIdentifiedCommandHandler(
|
||||
IMediator mediator,
|
||||
IRequestManager requestManager,
|
||||
ILogger<IdentifiedCommandHandler<SetStockRejectedOrderStatusCommand, bool>> logger)
|
||||
|
@ -1,4 +1,4 @@
|
||||
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.DomainEventHandlers.OrderCancelled;
|
||||
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.DomainEventHandlers;
|
||||
|
||||
public class OrderCancelledDomainEventHandler
|
||||
: INotificationHandler<OrderCancelledDomainEvent>
|
@ -1,4 +1,4 @@
|
||||
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.DomainEventHandlers.OrderShipped;
|
||||
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.DomainEventHandlers;
|
||||
|
||||
public class OrderShippedDomainEventHandler
|
||||
: INotificationHandler<OrderShippedDomainEvent>
|
@ -1,4 +1,4 @@
|
||||
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.DomainEventHandlers.OrderGracePeriodConfirmed;
|
||||
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.DomainEventHandlers;
|
||||
|
||||
public class OrderStatusChangedToAwaitingValidationDomainEventHandler
|
||||
: INotificationHandler<OrderStatusChangedToAwaitingValidationDomainEvent>
|
@ -1,4 +1,4 @@
|
||||
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.DomainEventHandlers.OrderPaid;
|
||||
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.DomainEventHandlers;
|
||||
|
||||
public class OrderStatusChangedToPaidDomainEventHandler
|
||||
: INotificationHandler<OrderStatusChangedToPaidDomainEvent>
|
||||
@ -10,10 +10,10 @@ public class OrderStatusChangedToPaidDomainEventHandler
|
||||
|
||||
|
||||
public OrderStatusChangedToPaidDomainEventHandler(
|
||||
IOrderRepository orderRepository, ILoggerFactory logger,
|
||||
IOrderRepository orderRepository,
|
||||
ILoggerFactory logger,
|
||||
IBuyerRepository buyerRepository,
|
||||
IOrderingIntegrationEventService orderingIntegrationEventService
|
||||
)
|
||||
IOrderingIntegrationEventService orderingIntegrationEventService)
|
||||
{
|
||||
_orderRepository = orderRepository ?? throw new ArgumentNullException(nameof(orderRepository));
|
||||
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||
@ -24,7 +24,7 @@ public class OrderStatusChangedToPaidDomainEventHandler
|
||||
public async Task Handle(OrderStatusChangedToPaidDomainEvent orderStatusChangedToPaidDomainEvent, CancellationToken cancellationToken)
|
||||
{
|
||||
_logger.CreateLogger<OrderStatusChangedToPaidDomainEventHandler>()
|
||||
.LogTrace("Order with Id: {OrderId} has been successfully updated to status {Status} ({Id})",
|
||||
.LogInformation("Order with Id: {OrderId} has been successfully updated to status {Status} ({Id})",
|
||||
orderStatusChangedToPaidDomainEvent.OrderId, nameof(OrderStatus.Paid), OrderStatus.Paid.Id);
|
||||
|
||||
var order = await _orderRepository.GetAsync(orderStatusChangedToPaidDomainEvent.OrderId);
|
@ -1,4 +1,4 @@
|
||||
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.DomainEventHandlers.OrderStockConfirmed;
|
||||
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.DomainEventHandlers;
|
||||
|
||||
public class OrderStatusChangedToStockConfirmedDomainEventHandler
|
||||
: INotificationHandler<OrderStatusChangedToStockConfirmedDomainEvent>
|
@ -1,4 +1,4 @@
|
||||
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.DomainEventHandlers.OrderStartedEvent;
|
||||
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.DomainEventHandlers;
|
||||
|
||||
public class SendEmailToCustomerWhenOrderStartedDomainEventHandler
|
||||
//: IAsyncNotificationHandler<OrderStartedDomainEvent>
|
@ -1,4 +1,4 @@
|
||||
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.DomainEventHandlers.BuyerAndPaymentMethodVerified;
|
||||
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.DomainEventHandlers;
|
||||
|
||||
public class UpdateOrderWhenBuyerAndPaymentMethodVerifiedDomainEventHandler
|
||||
: INotificationHandler<BuyerAndPaymentMethodVerifiedDomainEvent>
|
@ -1,4 +1,4 @@
|
||||
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.DomainEventHandlers.OrderStartedEvent;
|
||||
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.DomainEventHandlers;
|
||||
|
||||
public class ValidateOrAddBuyerAggregateWhenOrderStartedDomainEventHandler
|
||||
: INotificationHandler<OrderStartedDomainEvent>
|
||||
@ -22,9 +22,9 @@ public class ValidateOrAddBuyerAggregateWhenOrderStartedDomainEventHandler
|
||||
|
||||
public async Task Handle(OrderStartedDomainEvent orderStartedEvent, CancellationToken cancellationToken)
|
||||
{
|
||||
var cardTypeId = (orderStartedEvent.CardTypeId != 0) ? orderStartedEvent.CardTypeId : 1;
|
||||
var cardTypeId = orderStartedEvent.CardTypeId != 0 ? orderStartedEvent.CardTypeId : 1;
|
||||
var buyer = await _buyerRepository.FindAsync(orderStartedEvent.UserId);
|
||||
bool buyerOriginallyExisted = (buyer == null) ? false : true;
|
||||
var buyerOriginallyExisted = buyer == null ? false : true;
|
||||
|
||||
if (!buyerOriginallyExisted)
|
||||
{
|
@ -1,4 +1,4 @@
|
||||
namespace Ordering.API.Application.IntegrationEvents.EventHandling;
|
||||
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.IntegrationEvents.EventHandling;
|
||||
|
||||
public class OrderStockConfirmedIntegrationEventHandler :
|
||||
IIntegrationEventHandler<OrderStockConfirmedIntegrationEvent>
|
||||
|
@ -1,6 +1,7 @@
|
||||
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.Models;
|
||||
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Extensions;
|
||||
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.eShopOnContainers.Services.Ordering.API.Application.Models;
|
||||
using static Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands.CreateOrderCommand;
|
||||
|
||||
public static class BasketItemExtensions
|
||||
|
@ -32,16 +32,15 @@ global using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF.Se
|
||||
global using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF;
|
||||
global using Microsoft.eShopOnContainers.Services.Ordering.API.Application.Behaviors;
|
||||
global using Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands;
|
||||
global using Microsoft.eShopOnContainers.Services.Ordering.API.Application.DomainEventHandlers.OrderStartedEvent;
|
||||
global using Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure.AutofacModules;
|
||||
global using Microsoft.eShopOnContainers.Services.Ordering.API.Application.IntegrationEvents.Events;
|
||||
global using Microsoft.eShopOnContainers.Services.Ordering.API.Application.DomainEventHandlers;
|
||||
global using Microsoft.eShopOnContainers.Services.Ordering.API.Application.IntegrationEvents;
|
||||
global using Microsoft.eShopOnContainers.Services.Ordering.API.Application.IntegrationEvents.Events;
|
||||
global using Microsoft.eShopOnContainers.Services.Ordering.API.Application.IntegrationEvents.EventHandling;
|
||||
global using Microsoft.eShopOnContainers.Services.Ordering.API.Application.Models;
|
||||
global using Microsoft.eShopOnContainers.Services.Ordering.API.Application.Queries;
|
||||
global using Microsoft.eShopOnContainers.Services.Ordering.API.Application.Validations;
|
||||
global using Microsoft.eShopOnContainers.Services.Ordering.API.Controllers;
|
||||
global using Microsoft.eShopOnContainers.Services.Ordering.API.Extensions;
|
||||
global using GrpcOrdering;
|
||||
global using Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure.ActionResults;
|
||||
global using Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure.Filters;
|
||||
global using Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure.Services;
|
||||
|
@ -1,4 +1,9 @@
|
||||
namespace GrpcOrdering;
|
||||
using GrpcOrdering;
|
||||
|
||||
using OrderDraftDTO = GrpcOrdering.OrderDraftDTO;
|
||||
using CreateOrderDraftCommand = GrpcOrdering.CreateOrderDraftCommand;
|
||||
using BasketItem = GrpcOrdering.BasketItem;
|
||||
using OrderItemDTO = GrpcOrdering.OrderItemDTO;
|
||||
|
||||
public class OrderingService : OrderingGrpc.OrderingGrpcBase
|
||||
{
|
||||
@ -25,7 +30,6 @@ public class OrderingService : OrderingGrpc.OrderingGrpcBase
|
||||
createOrderDraftCommand.BuyerId,
|
||||
this.MapBasketItems(createOrderDraftCommand.Items));
|
||||
|
||||
|
||||
var data = await _mediator.Send(command);
|
||||
|
||||
if (data != null)
|
||||
|
@ -15,24 +15,6 @@ public class ApplicationModule
|
||||
protected override void Load(ContainerBuilder builder)
|
||||
{
|
||||
|
||||
builder.Register(c => new OrderQueries(QueriesConnectionString))
|
||||
.As<IOrderQueries>()
|
||||
.InstancePerLifetimeScope();
|
||||
|
||||
builder.RegisterType<BuyerRepository>()
|
||||
.As<IBuyerRepository>()
|
||||
.InstancePerLifetimeScope();
|
||||
|
||||
builder.RegisterType<OrderRepository>()
|
||||
.As<IOrderRepository>()
|
||||
.InstancePerLifetimeScope();
|
||||
|
||||
builder.RegisterType<RequestManager>()
|
||||
.As<IRequestManager>()
|
||||
.InstancePerLifetimeScope();
|
||||
|
||||
builder.RegisterAssemblyTypes(typeof(CreateOrderCommandHandler).GetTypeInfo().Assembly)
|
||||
.AsClosedTypesOf(typeof(IIntegrationEventHandler<>));
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -4,26 +4,6 @@ public class MediatorModule : Autofac.Module
|
||||
{
|
||||
protected override void Load(ContainerBuilder builder)
|
||||
{
|
||||
builder.RegisterAssemblyTypes(typeof(IMediator).GetTypeInfo().Assembly)
|
||||
.AsImplementedInterfaces();
|
||||
|
||||
// Register all the Command classes (they implement IRequestHandler) in assembly holding the Commands
|
||||
builder.RegisterAssemblyTypes(typeof(CreateOrderCommand).GetTypeInfo().Assembly)
|
||||
.AsClosedTypesOf(typeof(IRequestHandler<,>));
|
||||
|
||||
// Register the DomainEventHandler classes (they implement INotificationHandler<>) in assembly holding the Domain Events
|
||||
builder.RegisterAssemblyTypes(typeof(ValidateOrAddBuyerAggregateWhenOrderStartedDomainEventHandler).GetTypeInfo().Assembly)
|
||||
.AsClosedTypesOf(typeof(INotificationHandler<>));
|
||||
|
||||
// Register the Command's Validators (Validators based on FluentValidation library)
|
||||
builder
|
||||
.RegisterAssemblyTypes(typeof(CreateOrderCommandValidator).GetTypeInfo().Assembly)
|
||||
.Where(t => t.IsClosedTypeOf(typeof(IValidator<>)))
|
||||
.AsImplementedInterfaces();
|
||||
|
||||
builder.RegisterGeneric(typeof(LoggingBehavior<,>)).As(typeof(IPipelineBehavior<,>));
|
||||
builder.RegisterGeneric(typeof(ValidatorBehavior<,>)).As(typeof(IPipelineBehavior<,>));
|
||||
builder.RegisterGeneric(typeof(TransactionBehaviour<,>)).As(typeof(IPipelineBehavior<,>));
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
namespace Catalog.API.Infrastructure.IntegrationEventMigrations
|
||||
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure.IntegrationEventMigrations
|
||||
{
|
||||
public class IntegrationEventLogContextDesignTimeFactory : IDesignTimeDbContextFactory<IntegrationEventLogContext>
|
||||
{
|
||||
|
@ -6,7 +6,8 @@
|
||||
<AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback>
|
||||
<DockerComposeProjectPath>..\..\..\..\docker-compose.dcproj</DockerComposeProjectPath>
|
||||
<GenerateErrorForMissingTargetingPacks>false</GenerateErrorForMissingTargetingPacks>
|
||||
<IsTransformWebConfigDisabled>true</IsTransformWebConfigDisabled>
|
||||
<IsTransformWebConfigDisabled>true</IsTransformWebConfigDisabled>
|
||||
<RootNamespace>Microsoft.eShopOnContainers.Services.Ordering.API</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@ -1,15 +1,5 @@
|
||||
using Autofac.Core;
|
||||
using Microsoft.Azure.Amqp.Framing;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Logging;
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
var appName = "Ordering.API";
|
||||
var builder = WebApplication.CreateBuilder(new WebApplicationOptions
|
||||
{
|
||||
Args = args,
|
||||
ApplicationName = typeof(Program).Assembly.FullName,
|
||||
ContentRootPath = Directory.GetCurrentDirectory()
|
||||
});
|
||||
if (builder.Configuration.GetValue<bool>("UseVault", false))
|
||||
{
|
||||
TokenCredential credential = new ClientSecretCredential(
|
||||
@ -18,24 +8,22 @@ if (builder.Configuration.GetValue<bool>("UseVault", false))
|
||||
builder.Configuration["Vault:ClientSecret"]);
|
||||
builder.Configuration.AddAzureKeyVault(new Uri($"https://{builder.Configuration["Vault:Name"]}.vault.azure.net/"), credential);
|
||||
}
|
||||
builder.Configuration.SetBasePath(Directory.GetCurrentDirectory());
|
||||
builder.Configuration.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
|
||||
builder.Configuration.AddEnvironmentVariables();
|
||||
|
||||
builder.WebHost.ConfigureKestrel(options =>
|
||||
{
|
||||
var ports = GetDefinedPorts(builder.Configuration);
|
||||
options.Listen(IPAddress.Any, ports.httpPort, listenOptions =>
|
||||
var httpPort = builder.Configuration.GetValue("PORT", 80);
|
||||
options.Listen(IPAddress.Any, httpPort, listenOptions =>
|
||||
{
|
||||
listenOptions.Protocols = HttpProtocols.Http1AndHttp2;
|
||||
});
|
||||
|
||||
options.Listen(IPAddress.Any, ports.grpcPort, listenOptions =>
|
||||
var grpcPort = builder.Configuration.GetValue("GRPC_PORT", 5001);
|
||||
options.Listen(IPAddress.Any, grpcPort, listenOptions =>
|
||||
{
|
||||
listenOptions.Protocols = HttpProtocols.Http2;
|
||||
});
|
||||
|
||||
});
|
||||
builder.WebHost.CaptureStartupErrors(false);
|
||||
|
||||
builder.Host.UseSerilog(CreateSerilogLogger(builder.Configuration));
|
||||
builder.Services
|
||||
.AddGrpc(options =>
|
||||
@ -58,8 +46,81 @@ builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory());
|
||||
// Register your own things directly with Autofac here. Don't
|
||||
// call builder.Populate(), that happens in AutofacServiceProviderFactory
|
||||
// for you.
|
||||
builder.Host.ConfigureContainer<ContainerBuilder>(conbuilder => conbuilder.RegisterModule(new MediatorModule()));
|
||||
builder.Host.ConfigureContainer<ContainerBuilder>(conbuilder => conbuilder.RegisterModule(new ApplicationModule(builder.Configuration["ConnectionString"])));
|
||||
|
||||
var services = builder.Services;
|
||||
|
||||
services.AddMediatR(cfg =>
|
||||
{
|
||||
cfg.RegisterServicesFromAssemblyContaining(typeof(Program));
|
||||
|
||||
cfg.AddOpenBehavior(typeof(LoggingBehavior<,>));
|
||||
cfg.AddOpenBehavior(typeof(ValidatorBehavior<,>));
|
||||
cfg.AddOpenBehavior(typeof(TransactionBehavior<,>));
|
||||
});
|
||||
|
||||
/*
|
||||
// Register all the command handlers.
|
||||
services.AddSingleton<IRequestHandler<CancelOrderCommand, bool>, CancelOrderCommandHandler>();
|
||||
services.AddSingleton<IRequestHandler<IdentifiedCommand<CancelOrderCommand, bool>, bool>, CancelOrderIdentifiedCommandHandler>();
|
||||
|
||||
services.AddSingleton<IRequestHandler<CreateOrderCommand, bool>, CreateOrderCommandHandler>();
|
||||
services.AddSingleton<IRequestHandler<IdentifiedCommand<CreateOrderCommand, bool>, bool>, CreateOrderIdentifiedCommandHandler>();
|
||||
|
||||
services.AddSingleton<IRequestHandler<CreateOrderDraftCommand, OrderDraftDTO>, CreateOrderDraftCommandHandler>();
|
||||
|
||||
services.AddSingleton<IRequestHandler<IdentifiedCommand<SetAwaitingValidationOrderStatusCommand, bool>, bool>, SetAwaitingValidationIdentifiedOrderStatusCommandHandler>();
|
||||
services.AddSingleton<IRequestHandler<SetAwaitingValidationOrderStatusCommand, bool>, SetAwaitingValidationOrderStatusCommandHandler>();
|
||||
|
||||
services.AddSingleton<IRequestHandler<IdentifiedCommand<SetPaidOrderStatusCommand, bool>, bool>, SetPaidIdentifiedOrderStatusCommandHandler>();
|
||||
services.AddSingleton<IRequestHandler<SetPaidOrderStatusCommand, bool>, SetPaidOrderStatusCommandHandler>();
|
||||
|
||||
services.AddSingleton<IRequestHandler<IdentifiedCommand<SetStockConfirmedOrderStatusCommand, bool>, bool>, SetStockConfirmedOrderStatusIdentifiedCommandHandler>();
|
||||
services.AddSingleton<IRequestHandler<SetStockConfirmedOrderStatusCommand, bool>, SetStockConfirmedOrderStatusCommandHandler>();
|
||||
|
||||
services.AddSingleton<IRequestHandler<IdentifiedCommand<SetStockRejectedOrderStatusCommand, bool>, bool>, SetStockRejectedOrderStatusIdentifiedCommandHandler>();
|
||||
services.AddSingleton<IRequestHandler<SetStockRejectedOrderStatusCommand, bool>, SetStockRejectedOrderStatusCommandHandler>();
|
||||
|
||||
services.AddSingleton<IRequestHandler<IdentifiedCommand<ShipOrderCommand, bool>, bool>, ShipOrderIdentifiedCommandHandler>();
|
||||
services.AddSingleton<IRequestHandler<ShipOrderCommand, bool>, ShipOrderCommandHandler>();
|
||||
|
||||
// Register the DomainEventHandler classes (they implement INotificationHandler<>) in assembly holding the Domain Events
|
||||
services.AddSingleton<INotificationHandler<OrderCancelledDomainEvent>, OrderCancelledDomainEventHandler>();
|
||||
services.AddSingleton<INotificationHandler<OrderShippedDomainEvent>, OrderShippedDomainEventHandler>();
|
||||
services.AddSingleton<INotificationHandler<OrderStatusChangedToAwaitingValidationDomainEvent>, OrderStatusChangedToAwaitingValidationDomainEventHandler>();
|
||||
services.AddSingleton<INotificationHandler<OrderStatusChangedToPaidDomainEvent>, OrderStatusChangedToPaidDomainEventHandler>();
|
||||
services.AddSingleton<INotificationHandler<OrderStatusChangedToStockConfirmedDomainEvent>, OrderStatusChangedToStockConfirmedDomainEventHandler>();
|
||||
services.AddSingleton<INotificationHandler<BuyerAndPaymentMethodVerifiedDomainEvent>, UpdateOrderWhenBuyerAndPaymentMethodVerifiedDomainEventHandler>();
|
||||
services.AddSingleton<INotificationHandler<OrderStartedDomainEvent>, ValidateOrAddBuyerAggregateWhenOrderStartedDomainEventHandler>();
|
||||
*/
|
||||
|
||||
// Register the command validators for the validator behavior (validators based on FluentValidation library)
|
||||
services.AddSingleton<IValidator<CancelOrderCommand>, CancelOrderCommandValidator>();
|
||||
services.AddSingleton<IValidator<CreateOrderCommand>, CreateOrderCommandValidator>();
|
||||
services.AddSingleton<IValidator<IdentifiedCommand<CreateOrderCommand, bool>>, IdentifiedCommandValidator>();
|
||||
services.AddSingleton<IValidator<ShipOrderCommand>, ShipOrderCommandValidator>();
|
||||
|
||||
/*
|
||||
// Build the MediatR pipeline
|
||||
services.AddSingleton(typeof(IPipelineBehavior<,>), typeof(LoggingBehavior<,>));
|
||||
services.AddSingleton(typeof(IPipelineBehavior<,>), typeof(ValidatorBehavior<,>));
|
||||
services.AddSingleton(typeof(IPipelineBehavior<,>), typeof(TransactionBehavior<,>));
|
||||
*/
|
||||
|
||||
var queriesConnectionString = builder.Configuration["ConnectionString"];
|
||||
|
||||
services.AddScoped<IOrderQueries>(sp => new OrderQueries(queriesConnectionString));
|
||||
services.AddScoped<IBuyerRepository, BuyerRepository>();
|
||||
services.AddScoped<IOrderRepository, OrderRepository>();
|
||||
services.AddScoped<IRequestManager, RequestManager>();
|
||||
|
||||
// Add integration event handlers.
|
||||
services.AddSingleton<IIntegrationEventHandler<GracePeriodConfirmedIntegrationEvent>, GracePeriodConfirmedIntegrationEventHandler>();
|
||||
services.AddSingleton<IIntegrationEventHandler<OrderPaymentFailedIntegrationEvent>, OrderPaymentFailedIntegrationEventHandler>();
|
||||
services.AddSingleton<IIntegrationEventHandler<OrderPaymentSucceededIntegrationEvent>, OrderPaymentSucceededIntegrationEventHandler>();
|
||||
services.AddSingleton<IIntegrationEventHandler<OrderStockConfirmedIntegrationEvent>, OrderStockConfirmedIntegrationEventHandler>();
|
||||
services.AddSingleton<IIntegrationEventHandler<OrderStockRejectedIntegrationEvent>, OrderStockRejectedIntegrationEventHandler>();
|
||||
services.AddSingleton<IIntegrationEventHandler<UserCheckoutAcceptedIntegrationEvent>, UserCheckoutAcceptedIntegrationEventHandler>();
|
||||
|
||||
var app = builder.Build();
|
||||
if (app.Environment.IsDevelopment())
|
||||
{
|
||||
@ -166,18 +227,13 @@ Serilog.ILogger CreateSerilogLogger(IConfiguration configuration)
|
||||
.ReadFrom.Configuration(configuration)
|
||||
.CreateLogger();
|
||||
}
|
||||
(int httpPort, int grpcPort) GetDefinedPorts(IConfiguration config)
|
||||
{
|
||||
var grpcPort = config.GetValue("GRPC_PORT", 5001);
|
||||
var port = config.GetValue("PORT", 80);
|
||||
return (port, grpcPort);
|
||||
}
|
||||
|
||||
public partial class Program
|
||||
{
|
||||
|
||||
public static string Namespace = typeof(Program).Assembly.GetName().Name;
|
||||
private static string Namespace = typeof(Program).Assembly.GetName().Name;
|
||||
public static string AppName = Namespace.Substring(Namespace.LastIndexOf('.', Namespace.LastIndexOf('.') - 1) + 1);
|
||||
}
|
||||
|
||||
static class CustomExtensionsMethods
|
||||
{
|
||||
public static IServiceCollection AddApplicationInsights(this IServiceCollection services, IConfiguration configuration)
|
||||
@ -393,11 +449,10 @@ static class CustomExtensionsMethods
|
||||
{
|
||||
var serviceBusPersisterConnection = sp.GetRequiredService<IServiceBusPersisterConnection>();
|
||||
var logger = sp.GetRequiredService<ILogger<EventBusServiceBus>>();
|
||||
var eventBusSubcriptionsManager = sp.GetRequiredService<IEventBusSubscriptionsManager>();
|
||||
var eventBusSubscriptionsManager = sp.GetRequiredService<IEventBusSubscriptionsManager>();
|
||||
string subscriptionName = configuration["SubscriptionClientName"];
|
||||
|
||||
return new EventBusServiceBus(serviceBusPersisterConnection, logger,
|
||||
eventBusSubcriptionsManager, sp, subscriptionName);
|
||||
return new EventBusServiceBus(serviceBusPersisterConnection, logger, eventBusSubscriptionsManager, sp, subscriptionName);
|
||||
});
|
||||
}
|
||||
else
|
||||
@ -407,15 +462,14 @@ static class CustomExtensionsMethods
|
||||
var subscriptionClientName = configuration["SubscriptionClientName"];
|
||||
var rabbitMQPersistentConnection = sp.GetRequiredService<IRabbitMQPersistentConnection>();
|
||||
var logger = sp.GetRequiredService<ILogger<EventBusRabbitMQ>>();
|
||||
var eventBusSubcriptionsManager = sp.GetRequiredService<IEventBusSubscriptionsManager>();
|
||||
var eventBusSubscriptionsManager = sp.GetRequiredService<IEventBusSubscriptionsManager>();
|
||||
|
||||
var retryCount = 5;
|
||||
if (!string.IsNullOrEmpty(configuration["EventBusRetryCount"]))
|
||||
if (!int.TryParse(configuration["EventBusRetryCount"], out var retryCount))
|
||||
{
|
||||
retryCount = int.Parse(configuration["EventBusRetryCount"]);
|
||||
retryCount = 5;
|
||||
}
|
||||
|
||||
return new EventBusRabbitMQ(rabbitMQPersistentConnection, logger, sp, eventBusSubcriptionsManager, subscriptionClientName, retryCount);
|
||||
return new EventBusRabbitMQ(rabbitMQPersistentConnection, logger, sp, eventBusSubscriptionsManager, subscriptionClientName, retryCount);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -6,16 +6,6 @@
|
||||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="appsettings.json" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="appsettings.json">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" />
|
||||
|
@ -1,5 +1,4 @@
|
||||
var appName = "Ordering.SignalrHub";
|
||||
var builder = WebApplication.CreateBuilder(new WebApplicationOptions
|
||||
var builder = WebApplication.CreateBuilder(new WebApplicationOptions
|
||||
{
|
||||
Args = args,
|
||||
ApplicationName = typeof(Program).Assembly.FullName,
|
||||
|
@ -27,7 +27,7 @@ public class IdentifiedCommandHandlerTest
|
||||
.Returns(Task.FromResult(true));
|
||||
|
||||
//Act
|
||||
var handler = new IdentifiedCommandHandler<CreateOrderCommand, bool>(_mediator.Object, _requestManager.Object, _loggerMock.Object);
|
||||
var handler = new CreateOrderIdentifiedCommandHandler(_mediator.Object, _requestManager.Object, _loggerMock.Object);
|
||||
var cltToken = new System.Threading.CancellationToken();
|
||||
var result = await handler.Handle(fakeOrderCmd, cltToken);
|
||||
|
||||
@ -50,7 +50,7 @@ public class IdentifiedCommandHandlerTest
|
||||
.Returns(Task.FromResult(true));
|
||||
|
||||
//Act
|
||||
var handler = new IdentifiedCommandHandler<CreateOrderCommand, bool>(_mediator.Object, _requestManager.Object, _loggerMock.Object);
|
||||
var handler = new CreateOrderIdentifiedCommandHandler(_mediator.Object, _requestManager.Object, _loggerMock.Object);
|
||||
var cltToken = new System.Threading.CancellationToken();
|
||||
var result = await handler.Handle(fakeOrderCmd, cltToken);
|
||||
|
||||
|
@ -29,7 +29,7 @@ public class OrdersWebApiTest
|
||||
var actionResult = await orderController.CancelOrderAsync(new CancelOrderCommand(1), Guid.NewGuid().ToString()) as OkResult;
|
||||
|
||||
//Assert
|
||||
Assert.Equal(actionResult.StatusCode, (int)System.Net.HttpStatusCode.OK);
|
||||
Assert.Equal((int)System.Net.HttpStatusCode.OK, actionResult.StatusCode);
|
||||
|
||||
}
|
||||
|
||||
@ -45,7 +45,7 @@ public class OrdersWebApiTest
|
||||
var actionResult = await orderController.CancelOrderAsync(new CancelOrderCommand(1), String.Empty) as BadRequestResult;
|
||||
|
||||
//Assert
|
||||
Assert.Equal(actionResult.StatusCode, (int)System.Net.HttpStatusCode.BadRequest);
|
||||
Assert.Equal((int)System.Net.HttpStatusCode.BadRequest, actionResult.StatusCode);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@ -60,7 +60,7 @@ public class OrdersWebApiTest
|
||||
var actionResult = await orderController.ShipOrderAsync(new ShipOrderCommand(1), Guid.NewGuid().ToString()) as OkResult;
|
||||
|
||||
//Assert
|
||||
Assert.Equal(actionResult.StatusCode, (int)System.Net.HttpStatusCode.OK);
|
||||
Assert.Equal((int)System.Net.HttpStatusCode.OK, actionResult.StatusCode);
|
||||
|
||||
}
|
||||
|
||||
@ -76,7 +76,7 @@ public class OrdersWebApiTest
|
||||
var actionResult = await orderController.ShipOrderAsync(new ShipOrderCommand(1), String.Empty) as BadRequestResult;
|
||||
|
||||
//Assert
|
||||
Assert.Equal(actionResult.StatusCode, (int)System.Net.HttpStatusCode.BadRequest);
|
||||
Assert.Equal((int)System.Net.HttpStatusCode.BadRequest, actionResult.StatusCode);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
@ -20,12 +20,6 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="Services\Basket\appsettings.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Services\Catalog\appsettings.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Setup\CatalogBrands.csv">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
|
@ -9,6 +9,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{932D8224-11F
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{3AF739CD-81D8-428D-A08A-0A58372DEBF6}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
.editorconfig = .editorconfig
|
||||
.env = .env
|
||||
Directory.Packages.props = Directory.Packages.props
|
||||
NuGet.config = NuGet.config
|
||||
|
Loading…
x
Reference in New Issue
Block a user