Skip to content

Commit

Permalink
Clean.Architecture.Web/Program.cs configuration over all clean up
Browse files Browse the repository at this point in the history
  • Loading branch information
Tadeh Boghosian committed Sep 16, 2024
1 parent fad553f commit a72f36e
Show file tree
Hide file tree
Showing 7 changed files with 175 additions and 104 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
using Clean.Architecture.Core.Services;
using Clean.Architecture.Infrastructure.Data;
using Clean.Architecture.Infrastructure.Data.Queries;
using Clean.Architecture.Infrastructure.Email;
using Clean.Architecture.UseCases.Contributors.List;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
Expand All @@ -24,12 +23,11 @@ public static IServiceCollection AddInfrastructureServices(
services.AddDbContext<AppDbContext>(options =>
options.UseSqlite(connectionString));

services.AddScoped(typeof(IRepository<>), typeof(EfRepository<>));
services.AddScoped(typeof(IReadRepository<>), typeof(EfRepository<>));
services.AddScoped<IListContributorsQueryService, ListContributorsQueryService>();
services.AddScoped<IDeleteContributorService, DeleteContributorService>();
services.AddScoped(typeof(IRepository<>), typeof(EfRepository<>))
.AddScoped(typeof(IReadRepository<>), typeof(EfRepository<>))
.AddScoped<IListContributorsQueryService, ListContributorsQueryService>()
.AddScoped<IDeleteContributorService, DeleteContributorService>();

services.Configure<MailserverConfiguration>(config.GetSection("Mailserver"));

logger.LogInformation("{Project} services registered", "Infrastructure");

Expand Down
14 changes: 14 additions & 0 deletions src/Clean.Architecture.Web/Configurations/LoggerConfigs.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using Serilog;

namespace Clean.Architecture.Web.Configurations;

public static class LoggerConfigs
{
public static WebApplicationBuilder AddLoggerConfigs(this WebApplicationBuilder builder)
{

builder.Host.UseSerilog((_, config) => config.ReadFrom.Configuration(builder.Configuration));

return builder;
}
}
25 changes: 25 additions & 0 deletions src/Clean.Architecture.Web/Configurations/MediatrConfigs.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using Ardalis.SharedKernel;
using Clean.Architecture.Core.ContributorAggregate;
using Clean.Architecture.UseCases.Contributors.Create;
using MediatR;
using System.Reflection;

namespace Clean.Architecture.Web.Configurations;

public static class MediatrConfigs
{
public static IServiceCollection AddMediatrConfigs(this IServiceCollection services)
{
var mediatRAssemblies = new[]
{
Assembly.GetAssembly(typeof(Contributor)), // Core
Assembly.GetAssembly(typeof(CreateContributorCommand)) // UseCases
};

services.AddMediatR(cfg => cfg.RegisterServicesFromAssemblies(mediatRAssemblies!))
.AddScoped(typeof(IPipelineBehavior<,>), typeof(LoggingBehavior<,>))
.AddScoped<IDomainEventDispatcher, MediatRDomainEventDispatcher>();

return services;
}
}
34 changes: 34 additions & 0 deletions src/Clean.Architecture.Web/Configurations/OptionConfigs.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using Ardalis.ListStartupServices;
using Clean.Architecture.Infrastructure.Email;

namespace Clean.Architecture.Web.Configurations;

public static class OptionConfigs
{
public static IServiceCollection AddOptionConfigs(this IServiceCollection services,IConfiguration configuration,ILogger logger, WebApplicationBuilder builder)
{
services.Configure<MailserverConfiguration>(configuration.GetSection("Mailserver"))
// Configure Web Behavior
.Configure<CookiePolicyOptions>(options =>
{
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});

if (builder.Environment.IsDevelopment())
{
// add list services for diagnostic purposes - see https://github.com/ardalis/AspNetCoreStartupServices
services.Configure<ServiceConfig>(config =>
{
config.Services = new List<ServiceDescriptor>(builder.Services);
// optional - default path to view services is /listallservices - recommended to choose your own path
config.Path = "/listservices";
});
}

logger.LogInformation("{Project} were configured", "Options");

return services;
}
}
36 changes: 36 additions & 0 deletions src/Clean.Architecture.Web/Configurations/ServiceConfigs.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using Clean.Architecture.Core.Interfaces;
using Clean.Architecture.Infrastructure;
using Clean.Architecture.Infrastructure.Email;

namespace Clean.Architecture.Web.Configurations;

public static class ServiceConfigs
{
public static IServiceCollection AddServiceConfigs(this IServiceCollection services, ILogger logger, WebApplicationBuilder builder)
{
services.AddInfrastructureServices(builder.Configuration, logger)
.AddMediatrConfigs();


if (builder.Environment.IsDevelopment())
{
// Use a local test email server
// See: https://ardalis.com/configuring-a-local-test-email-server/
services.AddScoped<IEmailSender, MimeKitEmailSender>();

// Otherwise use this:
//builder.Services.AddScoped<IEmailSender, FakeEmailSender>();

}
else
{
services.AddScoped<IEmailSender, MimeKitEmailSender>();
}

logger.LogInformation("{Project} services registered", "Mediatr and Email Sender");

return services;
}


}
53 changes: 53 additions & 0 deletions src/Clean.Architecture.Web/Configurations/WebApplicatonConfigs.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
using Ardalis.ListStartupServices;
using Clean.Architecture.Infrastructure.Data;
using FastEndpoints;
using FastEndpoints.Swagger;

namespace Clean.Architecture.Web.Configurations;

public static class WebApplicatonConfigs
{
public static async Task<IApplicationBuilder> UseWebApplicationConfigs(this WebApplication app)
{
if (app.Environment.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseShowAllServicesMiddleware(); // see https://github.com/ardalis/AspNetCoreStartupServices
}
else
{
app.UseDefaultExceptionHandler(); // from FastEndpoints
app.UseHsts();
}

app.UseFastEndpoints()
.UseSwaggerGen(); // Includes AddFileServer and static files middleware


app.UseHttpsRedirection();

await SeedDatabase(app);

return app;

}

static async Task SeedDatabase(WebApplication app)
{
using var scope = app.Services.CreateScope();
var services = scope.ServiceProvider;

try
{
var context = services.GetRequiredService<AppDbContext>();
// context.Database.Migrate();
context.Database.EnsureCreated();
await SeedData.InitializeAsync(context);
}
catch (Exception ex)
{
var logger = services.GetRequiredService<ILogger<Program>>();
logger.LogError(ex, "An error occurred seeding the DB. {exceptionMessage}", ex.Message);
}
}
}
107 changes: 9 additions & 98 deletions src/Clean.Architecture.Web/Program.cs
Original file line number Diff line number Diff line change
@@ -1,129 +1,40 @@
using System.Reflection;
using Ardalis.ListStartupServices;
using Ardalis.SharedKernel;
using Clean.Architecture.Core.ContributorAggregate;
using Clean.Architecture.Core.Interfaces;
using Clean.Architecture.Infrastructure;
using Clean.Architecture.Infrastructure.Data;
using Clean.Architecture.Infrastructure.Email;
using Clean.Architecture.UseCases.Contributors.Create;
using Clean.Architecture.Web.Configurations;
using FastEndpoints;
using FastEndpoints.Swagger;
using MediatR;
using Serilog;
using Serilog.Extensions.Logging;


var builder = WebApplication.CreateBuilder(args);

var logger = Log.Logger = new LoggerConfiguration()
.Enrich.FromLogContext()
.WriteTo.Console()
.CreateLogger();

logger.Information("Starting web host");

var builder = WebApplication.CreateBuilder(args);
builder.AddLoggerConfigs();

builder.Host.UseSerilog((_, config) => config.ReadFrom.Configuration(builder.Configuration));
var microsoftLogger = new SerilogLoggerFactory(logger)
.CreateLogger<Program>();

// Configure Web Behavior
builder.Services.Configure<CookiePolicyOptions>(options =>
{
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
builder.Services.AddOptionConfigs(builder.Configuration, microsoftLogger, builder);
builder.Services.AddServiceConfigs(microsoftLogger, builder);

builder.Services.AddFastEndpoints()
.SwaggerDocument(o =>
{
o.ShortSchemaNames = true;
});

ConfigureMediatR();

builder.Services.AddInfrastructureServices(builder.Configuration, microsoftLogger);

if (builder.Environment.IsDevelopment())
{
// Use a local test email server
// See: https://ardalis.com/configuring-a-local-test-email-server/
builder.Services.AddScoped<IEmailSender, MimeKitEmailSender>();

// Otherwise use this:
//builder.Services.AddScoped<IEmailSender, FakeEmailSender>();
AddShowAllServicesSupport();
}
else
{
builder.Services.AddScoped<IEmailSender, MimeKitEmailSender>();
}

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseShowAllServicesMiddleware(); // see https://github.com/ardalis/AspNetCoreStartupServices
}
else
{
app.UseDefaultExceptionHandler(); // from FastEndpoints
app.UseHsts();
}

app.UseFastEndpoints()
.UseSwaggerGen(); // Includes AddFileServer and static files middleware
await app.UseWebApplicationConfigs();

app.UseHttpsRedirection();

await SeedDatabase(app);

app.Run();

static async Task SeedDatabase(WebApplication app)
{
using var scope = app.Services.CreateScope();
var services = scope.ServiceProvider;

try
{
var context = services.GetRequiredService<AppDbContext>();
// context.Database.Migrate();
context.Database.EnsureCreated();
await SeedData.InitializeAsync(context);
}
catch (Exception ex)
{
var logger = services.GetRequiredService<ILogger<Program>>();
logger.LogError(ex, "An error occurred seeding the DB. {exceptionMessage}", ex.Message);
}
}

void ConfigureMediatR()
{
var mediatRAssemblies = new[]
{
Assembly.GetAssembly(typeof(Contributor)), // Core
Assembly.GetAssembly(typeof(CreateContributorCommand)) // UseCases
};
builder.Services.AddMediatR(cfg => cfg.RegisterServicesFromAssemblies(mediatRAssemblies!));
builder.Services.AddScoped(typeof(IPipelineBehavior<,>), typeof(LoggingBehavior<,>));
builder.Services.AddScoped<IDomainEventDispatcher, MediatRDomainEventDispatcher>();
}

void AddShowAllServicesSupport()
{
// add list services for diagnostic purposes - see https://github.com/ardalis/AspNetCoreStartupServices
builder.Services.Configure<ServiceConfig>(config =>
{
config.Services = new List<ServiceDescriptor>(builder.Services);
// optional - default path to view services is /listallservices - recommended to choose your own path
config.Path = "/listservices";
});
}

// Make the implicit Program.cs class public, so integration tests can reference the correct assembly for host building
public partial class Program
{
}
public partial class Program { }

0 comments on commit a72f36e

Please sign in to comment.