1- using EFCore . Audit . Extensions ;
1+ using System . Reflection ;
2+ using EFCore . Audit . Extensions ;
23using EFCore . AuditBase . Extensions ;
34using EFCore . PostgresExtensions . Extensions ;
45using EntityFramework . Exceptions . PostgreSQL ;
56using Microsoft . AspNetCore . Builder ;
67using Microsoft . EntityFrameworkCore ;
78using Microsoft . Extensions . DependencyInjection ;
9+ using Npgsql . EntityFrameworkCore . PostgreSQL . Infrastructure ;
810
911namespace SharedKernel . Postgres . Extensions ;
1012
1113public static class WebAppExtensions
1214{
15+ // -------- AddPostgresContext (no pool) --------
16+
17+ public static WebApplicationBuilder AddPostgresContext < TContext > ( this WebApplicationBuilder builder ,
18+ string connectionString )
19+ where TContext : DbContext =>
20+ builder . AddPostgresContext < TContext > ( connectionString , ( Action < NpgsqlDbContextOptionsBuilder > ? ) null ) ;
21+
1322 public static WebApplicationBuilder AddPostgresContext < TContext > ( this WebApplicationBuilder builder ,
23+ string connectionString ,
24+ string migrationsAssembly )
25+ where TContext : DbContext =>
26+ builder . AddPostgresContext < TContext > ( connectionString , x => x . MigrationsAssembly ( migrationsAssembly ) ) ;
27+
28+ public static WebApplicationBuilder AddPostgresContext < TContext > ( this WebApplicationBuilder builder ,
29+ string connectionString ,
30+ Assembly migrationsAssembly )
31+ where TContext : DbContext =>
32+ builder . AddPostgresContext < TContext > ( connectionString ,
33+ migrationsAssembly . GetName ( )
34+ . Name ! ) ;
35+
36+ public static WebApplicationBuilder AddPostgresContext < TContext , TMigrationsMarker > (
37+ this WebApplicationBuilder builder ,
1438 string connectionString )
39+ where TContext : DbContext =>
40+ builder . AddPostgresContext < TContext > ( connectionString , typeof ( TMigrationsMarker ) . Assembly ) ;
41+
42+ public static WebApplicationBuilder AddPostgresContext < TContext > ( this WebApplicationBuilder builder ,
43+ string connectionString ,
44+ Action < NpgsqlDbContextOptionsBuilder > ? npgsql )
1545 where TContext : DbContext
1646 {
17- builder . Services . AddDbContext < TContext > ( options =>
18- {
19- options
20- . AddStandardOptions ( connectionString ) ;
21- } ) ;
22-
47+ builder . Services . AddDbContext < TContext > ( options => options . AddStandardOptions ( connectionString , npgsql ) ) ;
2348 builder . AddPostgresHealthCheck ( connectionString ) ;
24-
2549 return builder ;
2650 }
2751
52+ // -------- AddPostgresContextPool --------
53+
2854 public static WebApplicationBuilder AddPostgresContextPool < TContext > ( this WebApplicationBuilder builder ,
2955 string connectionString )
56+ where TContext : DbContext =>
57+ builder . AddPostgresContextPool < TContext > ( connectionString , ( Action < NpgsqlDbContextOptionsBuilder > ? ) null ) ;
58+
59+ public static WebApplicationBuilder AddPostgresContextPool < TContext > ( this WebApplicationBuilder builder ,
60+ string connectionString ,
61+ string migrationsAssembly )
62+ where TContext : DbContext =>
63+ builder . AddPostgresContextPool < TContext > ( connectionString , x => x . MigrationsAssembly ( migrationsAssembly ) ) ;
64+
65+ public static WebApplicationBuilder AddPostgresContextPool < TContext > ( this WebApplicationBuilder builder ,
66+ string connectionString ,
67+ Assembly migrationsAssembly )
68+ where TContext : DbContext =>
69+ builder . AddPostgresContextPool < TContext > ( connectionString ,
70+ migrationsAssembly . GetName ( )
71+ . Name ! ) ;
72+
73+ public static WebApplicationBuilder AddPostgresContextPool < TContext , TMigrationsMarker > (
74+ this WebApplicationBuilder builder ,
75+ string connectionString )
76+ where TContext : DbContext =>
77+ builder . AddPostgresContextPool < TContext > ( connectionString , typeof ( TMigrationsMarker ) . Assembly ) ;
78+
79+ public static WebApplicationBuilder AddPostgresContextPool < TContext > ( this WebApplicationBuilder builder ,
80+ string connectionString ,
81+ Action < NpgsqlDbContextOptionsBuilder > ? npgsql )
3082 where TContext : DbContext
3183 {
32- builder . Services . AddDbContextPool < TContext > ( options =>
33- {
34- options . AddStandardOptions ( connectionString ) ;
35- } ) ;
36-
84+ builder . Services . AddDbContextPool < TContext > ( options => options . AddStandardOptions ( connectionString , npgsql ) ) ;
3785 builder . AddPostgresHealthCheck ( connectionString ) ;
38-
3986 return builder ;
4087 }
4188
89+ // -------- WithAuditTrail (no pool) --------
90+
91+ public static WebApplicationBuilder AddPostgresContextWithAuditTrail < TContext > ( this WebApplicationBuilder builder ,
92+ string connectionString )
93+ where TContext : DbContext =>
94+ builder . AddPostgresContextWithAuditTrail < TContext > ( connectionString ,
95+ ( Action < NpgsqlDbContextOptionsBuilder > ? ) null ) ;
96+
97+ public static WebApplicationBuilder AddPostgresContextWithAuditTrail < TContext > ( this WebApplicationBuilder builder ,
98+ string connectionString ,
99+ string migrationsAssembly )
100+ where TContext : DbContext =>
101+ builder . AddPostgresContextWithAuditTrail < TContext > ( connectionString ,
102+ x => x . MigrationsAssembly ( migrationsAssembly ) ) ;
103+
104+ public static WebApplicationBuilder AddPostgresContextWithAuditTrail < TContext > ( this WebApplicationBuilder builder ,
105+ string connectionString ,
106+ Assembly migrationsAssembly )
107+ where TContext : DbContext =>
108+ builder . AddPostgresContextWithAuditTrail < TContext > ( connectionString ,
109+ migrationsAssembly . GetName ( )
110+ . Name ! ) ;
111+
112+ public static WebApplicationBuilder AddPostgresContextWithAuditTrail < TContext , TMigrationsMarker > (
113+ this WebApplicationBuilder builder ,
114+ string connectionString )
115+ where TContext : DbContext =>
116+ builder . AddPostgresContextWithAuditTrail < TContext > ( connectionString , typeof ( TMigrationsMarker ) . Assembly ) ;
117+
42118 public static WebApplicationBuilder AddPostgresContextWithAuditTrail < TContext > ( this WebApplicationBuilder builder ,
43- string connectionString ) where TContext : DbContext
119+ string connectionString ,
120+ Action < NpgsqlDbContextOptionsBuilder > ? npgsql )
121+ where TContext : DbContext
44122 {
45123 builder . Services . AddDbContext < TContext > ( ( sp , options ) =>
46124 {
47- options . AddStandardOptions ( connectionString )
125+ options . AddStandardOptions ( connectionString , npgsql )
48126 . AddAuditTrailInterceptors ( sp ) ;
49127 } ) ;
50128
51129 builder . AddPostgresHealthCheck ( connectionString ) ;
52-
53130 return builder ;
54131 }
55132
56- public static WebApplicationBuilder AddPostgresContextPoolWithAuditTrail < TContext > ( this WebApplicationBuilder builder ,
57- string connectionString ) where TContext : DbContext
133+ // -------- Pool + WithAuditTrail --------
134+
135+ public static WebApplicationBuilder AddPostgresContextPoolWithAuditTrail < TContext > (
136+ this WebApplicationBuilder builder ,
137+ string connectionString )
138+ where TContext : DbContext =>
139+ builder . AddPostgresContextPoolWithAuditTrail < TContext > ( connectionString ,
140+ ( Action < NpgsqlDbContextOptionsBuilder > ? ) null ) ;
141+
142+ public static WebApplicationBuilder AddPostgresContextPoolWithAuditTrail < TContext > (
143+ this WebApplicationBuilder builder ,
144+ string connectionString ,
145+ string migrationsAssembly )
146+ where TContext : DbContext =>
147+ builder . AddPostgresContextPoolWithAuditTrail < TContext > ( connectionString ,
148+ x => x . MigrationsAssembly ( migrationsAssembly ) ) ;
149+
150+ public static WebApplicationBuilder AddPostgresContextPoolWithAuditTrail < TContext > (
151+ this WebApplicationBuilder builder ,
152+ string connectionString ,
153+ Assembly migrationsAssembly )
154+ where TContext : DbContext =>
155+ builder . AddPostgresContextPoolWithAuditTrail < TContext > ( connectionString ,
156+ migrationsAssembly . GetName ( )
157+ . Name ! ) ;
158+
159+ public static WebApplicationBuilder AddPostgresContextPoolWithAuditTrail < TContext , TMigrationsMarker > (
160+ this WebApplicationBuilder builder ,
161+ string connectionString )
162+ where TContext : DbContext =>
163+ builder . AddPostgresContextPoolWithAuditTrail < TContext > ( connectionString , typeof ( TMigrationsMarker ) . Assembly ) ;
164+
165+ public static WebApplicationBuilder AddPostgresContextPoolWithAuditTrail < TContext > (
166+ this WebApplicationBuilder builder ,
167+ string connectionString ,
168+ Action < NpgsqlDbContextOptionsBuilder > ? npgsql )
169+ where TContext : DbContext
58170 {
59171 builder . Services . AddDbContextPool < TContext > ( ( sp , options ) =>
60172 {
61- options . AddStandardOptions ( connectionString )
173+ options . AddStandardOptions ( connectionString , npgsql )
62174 . AddAuditTrailInterceptors ( sp ) ;
63175 } ) ;
64176
65177 builder . AddPostgresHealthCheck ( connectionString ) ;
66-
67178 return builder ;
68179 }
69180
181+ // -------- Migration helpers --------
182+
70183 public static WebApplication MigrateDatabase < TContext > ( this WebApplication app )
71184 where TContext : DbContext
72185 {
@@ -76,11 +189,23 @@ public static WebApplication MigrateDatabase<TContext>(this WebApplication app)
76189 return app ;
77190 }
78191
192+ public static Task MigrateDatabaseAsync < TContext > ( this WebApplication app ,
193+ CancellationToken cancellationToken = default )
194+ where TContext : DbContext
195+ {
196+ using var scope = app . Services . CreateScope ( ) ;
197+ var dbContext = scope . ServiceProvider . GetRequiredService < TContext > ( ) ;
198+ return dbContext . Database . MigrateAsync ( cancellationToken ) ;
199+ }
200+
201+ // -------- Standard options (with Npgsql hook) --------
202+
79203 private static DbContextOptionsBuilder AddStandardOptions ( this DbContextOptionsBuilder optionsBuilder ,
80- string connectionString )
204+ string connectionString ,
205+ Action < NpgsqlDbContextOptionsBuilder > ? npgsql = null )
81206 {
82207 return optionsBuilder
83- . UseNpgsql ( connectionString )
208+ . UseNpgsql ( connectionString , x => npgsql ? . Invoke ( x ) )
84209 . UseQueryLocks ( )
85210 . UseAuditBaseValidatorInterceptor ( )
86211 . UseSnakeCaseNamingConvention ( )
0 commit comments