Skip to content

Commit 84ab0e4

Browse files
TadehB7Tadeh Boghosianardalis
authored
Clean.Architecture.Web/Program.cs configuration over all clean up (ardalis#821)
Co-authored-by: Tadeh Boghosian <[email protected]> Co-authored-by: Steve Smith <[email protected]>
1 parent c086d30 commit 84ab0e4

File tree

7 files changed

+175
-104
lines changed

7 files changed

+175
-104
lines changed

src/Clean.Architecture.Infrastructure/InfrastructureServiceExtensions.cs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
using Clean.Architecture.Core.Services;
55
using Clean.Architecture.Infrastructure.Data;
66
using Clean.Architecture.Infrastructure.Data.Queries;
7-
using Clean.Architecture.Infrastructure.Email;
87
using Clean.Architecture.UseCases.Contributors.List;
98
using Microsoft.EntityFrameworkCore;
109
using Microsoft.Extensions.Configuration;
@@ -24,12 +23,11 @@ public static IServiceCollection AddInfrastructureServices(
2423
services.AddDbContext<AppDbContext>(options =>
2524
options.UseSqlite(connectionString));
2625

27-
services.AddScoped(typeof(IRepository<>), typeof(EfRepository<>));
28-
services.AddScoped(typeof(IReadRepository<>), typeof(EfRepository<>));
29-
services.AddScoped<IListContributorsQueryService, ListContributorsQueryService>();
30-
services.AddScoped<IDeleteContributorService, DeleteContributorService>();
26+
services.AddScoped(typeof(IRepository<>), typeof(EfRepository<>))
27+
.AddScoped(typeof(IReadRepository<>), typeof(EfRepository<>))
28+
.AddScoped<IListContributorsQueryService, ListContributorsQueryService>()
29+
.AddScoped<IDeleteContributorService, DeleteContributorService>();
3130

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

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
using Serilog;
2+
3+
namespace Clean.Architecture.Web.Configurations;
4+
5+
public static class LoggerConfigs
6+
{
7+
public static WebApplicationBuilder AddLoggerConfigs(this WebApplicationBuilder builder)
8+
{
9+
10+
builder.Host.UseSerilog((_, config) => config.ReadFrom.Configuration(builder.Configuration));
11+
12+
return builder;
13+
}
14+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
using Ardalis.SharedKernel;
2+
using Clean.Architecture.Core.ContributorAggregate;
3+
using Clean.Architecture.UseCases.Contributors.Create;
4+
using MediatR;
5+
using System.Reflection;
6+
7+
namespace Clean.Architecture.Web.Configurations;
8+
9+
public static class MediatrConfigs
10+
{
11+
public static IServiceCollection AddMediatrConfigs(this IServiceCollection services)
12+
{
13+
var mediatRAssemblies = new[]
14+
{
15+
Assembly.GetAssembly(typeof(Contributor)), // Core
16+
Assembly.GetAssembly(typeof(CreateContributorCommand)) // UseCases
17+
};
18+
19+
services.AddMediatR(cfg => cfg.RegisterServicesFromAssemblies(mediatRAssemblies!))
20+
.AddScoped(typeof(IPipelineBehavior<,>), typeof(LoggingBehavior<,>))
21+
.AddScoped<IDomainEventDispatcher, MediatRDomainEventDispatcher>();
22+
23+
return services;
24+
}
25+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
using Ardalis.ListStartupServices;
2+
using Clean.Architecture.Infrastructure.Email;
3+
4+
namespace Clean.Architecture.Web.Configurations;
5+
6+
public static class OptionConfigs
7+
{
8+
public static IServiceCollection AddOptionConfigs(this IServiceCollection services,IConfiguration configuration,ILogger logger, WebApplicationBuilder builder)
9+
{
10+
services.Configure<MailserverConfiguration>(configuration.GetSection("Mailserver"))
11+
// Configure Web Behavior
12+
.Configure<CookiePolicyOptions>(options =>
13+
{
14+
options.CheckConsentNeeded = context => true;
15+
options.MinimumSameSitePolicy = SameSiteMode.None;
16+
});
17+
18+
if (builder.Environment.IsDevelopment())
19+
{
20+
// add list services for diagnostic purposes - see https://github.com/ardalis/AspNetCoreStartupServices
21+
services.Configure<ServiceConfig>(config =>
22+
{
23+
config.Services = new List<ServiceDescriptor>(builder.Services);
24+
25+
// optional - default path to view services is /listallservices - recommended to choose your own path
26+
config.Path = "/listservices";
27+
});
28+
}
29+
30+
logger.LogInformation("{Project} were configured", "Options");
31+
32+
return services;
33+
}
34+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
using Clean.Architecture.Core.Interfaces;
2+
using Clean.Architecture.Infrastructure;
3+
using Clean.Architecture.Infrastructure.Email;
4+
5+
namespace Clean.Architecture.Web.Configurations;
6+
7+
public static class ServiceConfigs
8+
{
9+
public static IServiceCollection AddServiceConfigs(this IServiceCollection services, ILogger logger, WebApplicationBuilder builder)
10+
{
11+
services.AddInfrastructureServices(builder.Configuration, logger)
12+
.AddMediatrConfigs();
13+
14+
15+
if (builder.Environment.IsDevelopment())
16+
{
17+
// Use a local test email server
18+
// See: https://ardalis.com/configuring-a-local-test-email-server/
19+
services.AddScoped<IEmailSender, MimeKitEmailSender>();
20+
21+
// Otherwise use this:
22+
//builder.Services.AddScoped<IEmailSender, FakeEmailSender>();
23+
24+
}
25+
else
26+
{
27+
services.AddScoped<IEmailSender, MimeKitEmailSender>();
28+
}
29+
30+
logger.LogInformation("{Project} services registered", "Mediatr and Email Sender");
31+
32+
return services;
33+
}
34+
35+
36+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
using Ardalis.ListStartupServices;
2+
using Clean.Architecture.Infrastructure.Data;
3+
using FastEndpoints;
4+
using FastEndpoints.Swagger;
5+
6+
namespace Clean.Architecture.Web.Configurations;
7+
8+
public static class WebApplicatonConfigs
9+
{
10+
public static async Task<IApplicationBuilder> UseWebApplicationConfigs(this WebApplication app)
11+
{
12+
if (app.Environment.IsDevelopment())
13+
{
14+
app.UseDeveloperExceptionPage();
15+
app.UseShowAllServicesMiddleware(); // see https://github.com/ardalis/AspNetCoreStartupServices
16+
}
17+
else
18+
{
19+
app.UseDefaultExceptionHandler(); // from FastEndpoints
20+
app.UseHsts();
21+
}
22+
23+
app.UseFastEndpoints()
24+
.UseSwaggerGen(); // Includes AddFileServer and static files middleware
25+
26+
27+
app.UseHttpsRedirection();
28+
29+
await SeedDatabase(app);
30+
31+
return app;
32+
33+
}
34+
35+
static async Task SeedDatabase(WebApplication app)
36+
{
37+
using var scope = app.Services.CreateScope();
38+
var services = scope.ServiceProvider;
39+
40+
try
41+
{
42+
var context = services.GetRequiredService<AppDbContext>();
43+
// context.Database.Migrate();
44+
context.Database.EnsureCreated();
45+
await SeedData.InitializeAsync(context);
46+
}
47+
catch (Exception ex)
48+
{
49+
var logger = services.GetRequiredService<ILogger<Program>>();
50+
logger.LogError(ex, "An error occurred seeding the DB. {exceptionMessage}", ex.Message);
51+
}
52+
}
53+
}
Lines changed: 9 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -1,129 +1,40 @@
1-
using System.Reflection;
2-
using Ardalis.ListStartupServices;
3-
using Ardalis.SharedKernel;
4-
using Clean.Architecture.Core.ContributorAggregate;
5-
using Clean.Architecture.Core.Interfaces;
6-
using Clean.Architecture.Infrastructure;
7-
using Clean.Architecture.Infrastructure.Data;
8-
using Clean.Architecture.Infrastructure.Email;
9-
using Clean.Architecture.UseCases.Contributors.Create;
1+
using Clean.Architecture.Web.Configurations;
102
using FastEndpoints;
113
using FastEndpoints.Swagger;
12-
using MediatR;
134
using Serilog;
145
using Serilog.Extensions.Logging;
156

7+
8+
var builder = WebApplication.CreateBuilder(args);
9+
1610
var logger = Log.Logger = new LoggerConfiguration()
1711
.Enrich.FromLogContext()
1812
.WriteTo.Console()
1913
.CreateLogger();
2014

2115
logger.Information("Starting web host");
2216

23-
var builder = WebApplication.CreateBuilder(args);
17+
builder.AddLoggerConfigs();
2418

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

29-
// Configure Web Behavior
30-
builder.Services.Configure<CookiePolicyOptions>(options =>
31-
{
32-
options.CheckConsentNeeded = context => true;
33-
options.MinimumSameSitePolicy = SameSiteMode.None;
34-
});
22+
builder.Services.AddOptionConfigs(builder.Configuration, microsoftLogger, builder);
23+
builder.Services.AddServiceConfigs(microsoftLogger, builder);
3524

3625
builder.Services.AddFastEndpoints()
3726
.SwaggerDocument(o =>
3827
{
3928
o.ShortSchemaNames = true;
4029
});
4130

42-
ConfigureMediatR();
43-
44-
builder.Services.AddInfrastructureServices(builder.Configuration, microsoftLogger);
45-
46-
if (builder.Environment.IsDevelopment())
47-
{
48-
// Use a local test email server
49-
// See: https://ardalis.com/configuring-a-local-test-email-server/
50-
builder.Services.AddScoped<IEmailSender, MimeKitEmailSender>();
51-
52-
// Otherwise use this:
53-
//builder.Services.AddScoped<IEmailSender, FakeEmailSender>();
54-
AddShowAllServicesSupport();
55-
}
56-
else
57-
{
58-
builder.Services.AddScoped<IEmailSender, MimeKitEmailSender>();
59-
}
60-
6131
var app = builder.Build();
6232

63-
if (app.Environment.IsDevelopment())
64-
{
65-
app.UseDeveloperExceptionPage();
66-
app.UseShowAllServicesMiddleware(); // see https://github.com/ardalis/AspNetCoreStartupServices
67-
}
68-
else
69-
{
70-
app.UseDefaultExceptionHandler(); // from FastEndpoints
71-
app.UseHsts();
72-
}
73-
74-
app.UseFastEndpoints()
75-
.UseSwaggerGen(); // Includes AddFileServer and static files middleware
33+
await app.UseWebApplicationConfigs();
7634

77-
app.UseHttpsRedirection();
78-
79-
await SeedDatabase(app);
8035

8136
app.Run();
8237

83-
static async Task SeedDatabase(WebApplication app)
84-
{
85-
using var scope = app.Services.CreateScope();
86-
var services = scope.ServiceProvider;
87-
88-
try
89-
{
90-
var context = services.GetRequiredService<AppDbContext>();
91-
// context.Database.Migrate();
92-
context.Database.EnsureCreated();
93-
await SeedData.InitializeAsync(context);
94-
}
95-
catch (Exception ex)
96-
{
97-
var logger = services.GetRequiredService<ILogger<Program>>();
98-
logger.LogError(ex, "An error occurred seeding the DB. {exceptionMessage}", ex.Message);
99-
}
100-
}
101-
102-
void ConfigureMediatR()
103-
{
104-
var mediatRAssemblies = new[]
105-
{
106-
Assembly.GetAssembly(typeof(Contributor)), // Core
107-
Assembly.GetAssembly(typeof(CreateContributorCommand)) // UseCases
108-
};
109-
builder.Services.AddMediatR(cfg => cfg.RegisterServicesFromAssemblies(mediatRAssemblies!));
110-
builder.Services.AddScoped(typeof(IPipelineBehavior<,>), typeof(LoggingBehavior<,>));
111-
builder.Services.AddScoped<IDomainEventDispatcher, MediatRDomainEventDispatcher>();
112-
}
113-
114-
void AddShowAllServicesSupport()
115-
{
116-
// add list services for diagnostic purposes - see https://github.com/ardalis/AspNetCoreStartupServices
117-
builder.Services.Configure<ServiceConfig>(config =>
118-
{
119-
config.Services = new List<ServiceDescriptor>(builder.Services);
120-
121-
// optional - default path to view services is /listallservices - recommended to choose your own path
122-
config.Path = "/listservices";
123-
});
124-
}
12538

12639
// Make the implicit Program.cs class public, so integration tests can reference the correct assembly for host building
127-
public partial class Program
128-
{
129-
}
40+
public partial class Program { }

0 commit comments

Comments
 (0)