var builder = WebApplication.CreateBuilder(args); builder.AddServiceDefaults(); builder.Services.AddGrpc(); builder.Services.AddControllers(); builder.Services.AddHealthChecks(builder.Configuration); builder.Services.AddDbContexts(builder.Configuration); builder.Services.AddApplicationOptions(builder.Configuration); builder.Services.AddIntegrationServices(); var services = builder.Services; services.AddMediatR(cfg => { cfg.RegisterServicesFromAssemblyContaining(typeof(Program)); cfg.AddOpenBehavior(typeof(LoggingBehavior<,>)); cfg.AddOpenBehavior(typeof(ValidatorBehavior<,>)); cfg.AddOpenBehavior(typeof(TransactionBehavior<,>)); }); // Register the command validators for the validator behavior (validators based on FluentValidation library) services.AddSingleton, CancelOrderCommandValidator>(); services.AddSingleton, CreateOrderCommandValidator>(); services.AddSingleton>, IdentifiedCommandValidator>(); services.AddSingleton, ShipOrderCommandValidator>(); services.AddScoped(sp => new OrderQueries(builder.Configuration.GetConnectionString("OrderingDB"))); services.AddScoped(); services.AddScoped(); services.AddScoped(); // Add integration event handlers. services.AddTransient, GracePeriodConfirmedIntegrationEventHandler>(); services.AddTransient, OrderPaymentFailedIntegrationEventHandler>(); services.AddTransient, OrderPaymentSucceededIntegrationEventHandler>(); services.AddTransient, OrderStockConfirmedIntegrationEventHandler>(); services.AddTransient, OrderStockRejectedIntegrationEventHandler>(); services.AddTransient, UserCheckoutAcceptedIntegrationEventHandler>(); var app = builder.Build(); app.UseServiceDefaults(); app.MapGrpcService(); app.MapControllers(); var eventBus = app.Services.GetRequiredService(); eventBus.Subscribe>(); eventBus.Subscribe>(); eventBus.Subscribe>(); eventBus.Subscribe>(); eventBus.Subscribe>(); eventBus.Subscribe>(); using (var scope = app.Services.CreateScope()) { var context = scope.ServiceProvider.GetRequiredService(); var env = app.Services.GetService(); var settings = app.Services.GetService>(); var logger = app.Services.GetService>(); await context.Database.MigrateAsync(); await new OrderingContextSeed().SeedAsync(context, env, settings, logger); var integEventContext = scope.ServiceProvider.GetRequiredService(); await integEventContext.Database.MigrateAsync(); } await app.RunAsync();