Skip to content

Commit 8e3e867

Browse files
committed
The callback of AddOrUpdateExtension should return the modified extension in case the extension is cloned.
1 parent d9eca37 commit 8e3e867

File tree

8 files changed

+81
-27
lines changed

8 files changed

+81
-27
lines changed

src/Thinktecture.EntityFrameworkCore.Relational/EntityFrameworkCore/Infrastructure/RelationalDbContextOptionsExtension.cs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ public void Validate(IDbContextOptions options)
156156
/// <param name="initialCapacity">Initial capacity of a new <see cref="StringBuilder"/>.</param>
157157
/// <param name="maximumRetainedCapacity">Instances of <see cref="StringBuilder"/> with greater capacity are not reused.</param>
158158
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="initialCapacity"/> or <paramref name="maximumRetainedCapacity"/> are negative.</exception>
159-
public void ConfigureStringBuilderPool(int initialCapacity, int maximumRetainedCapacity)
159+
public RelationalDbContextOptionsExtension ConfigureStringBuilderPool(int initialCapacity, int maximumRetainedCapacity)
160160
{
161161
if (initialCapacity < 0)
162162
throw new ArgumentOutOfRangeException(nameof(initialCapacity), "Initial capacity cannot be negative.");
@@ -166,21 +166,25 @@ public void ConfigureStringBuilderPool(int initialCapacity, int maximumRetainedC
166166

167167
_stringBuilderPolicy.InitialCapacity = initialCapacity;
168168
_stringBuilderPolicy.MaximumRetainedCapacity = maximumRetainedCapacity;
169+
170+
return this;
169171
}
170172

171173
/// <summary>
172174
/// Adds provided <paramref name="type"/> to dependency injection.
173175
/// </summary>
174176
/// <param name="type">An implementation of <see cref="IRelationalTypeMappingSourcePlugin"/>.</param>
175177
/// <exception cref="ArgumentNullException"><paramref name="type"/> is <c>null</c>.</exception>
176-
public void AddRelationalTypeMappingSourcePlugin(Type type)
178+
public RelationalDbContextOptionsExtension AddRelationalTypeMappingSourcePlugin(Type type)
177179
{
178180
ArgumentNullException.ThrowIfNull(type);
179181

180182
if (!typeof(IRelationalTypeMappingSourcePlugin).IsAssignableFrom(type))
181183
throw new ArgumentException($"The provided type '{type.ShortDisplayName()}' must implement '{nameof(IRelationalTypeMappingSourcePlugin)}'.", nameof(type));
182184

183185
Register(typeof(IRelationalTypeMappingSourcePlugin), type, ServiceLifetime.Singleton);
186+
187+
return this;
184188
}
185189

186190
/// <summary>
@@ -218,13 +222,15 @@ public void Register(Type serviceType, object implementationInstance)
218222
/// Adds an <see cref="IEvaluatableExpressionFilterPlugin"/> to the dependency injection.
219223
/// </summary>
220224
/// <typeparam name="T">Type of the plugin.</typeparam>
221-
public void AddEvaluatableExpressionFilterPlugin<T>()
225+
public RelationalDbContextOptionsExtension AddEvaluatableExpressionFilterPlugin<T>()
222226
where T : IEvaluatableExpressionFilterPlugin
223227
{
224228
var type = typeof(T);
225229

226230
if (!_evaluatableExpressionFilterPlugins.Contains(type))
227231
_evaluatableExpressionFilterPlugins.Add(type);
232+
233+
return this;
228234
}
229235

230236
private class RelationalDbContextOptionsExtensionInfo : DbContextOptionsExtensionInfo

src/Thinktecture.EntityFrameworkCore.Relational/Extensions/RelationalDbContextOptionsBuilderExtensions.cs

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,11 @@ public static DbContextOptionsBuilder AddSchemaRespectingComponents(
6868
this DbContextOptionsBuilder builder,
6969
bool addDefaultSchemaRespectingComponents = true)
7070
{
71-
builder.AddOrUpdateExtension<RelationalDbContextOptionsExtension>(extension => extension.AddSchemaRespectingComponents = addDefaultSchemaRespectingComponents);
71+
builder.AddOrUpdateExtension<RelationalDbContextOptionsExtension>(extension =>
72+
{
73+
extension.AddSchemaRespectingComponents = addDefaultSchemaRespectingComponents;
74+
return extension;
75+
});
7276
return builder;
7377
}
7478

@@ -129,7 +133,11 @@ public static DbContextOptionsBuilder AddNestedTransactionSupport(
129133
this DbContextOptionsBuilder builder,
130134
bool addNestedTransactionsSupport = true)
131135
{
132-
builder.AddOrUpdateExtension<RelationalDbContextOptionsExtension>(extension => extension.AddNestedTransactionsSupport = addNestedTransactionsSupport);
136+
builder.AddOrUpdateExtension<RelationalDbContextOptionsExtension>(extension =>
137+
{
138+
extension.AddNestedTransactionsSupport = addNestedTransactionsSupport;
139+
return extension;
140+
});
133141
return builder;
134142
}
135143

@@ -184,7 +192,7 @@ public static TExtension TryAddExtension<TExtension>(this DbContextOptionsBuilde
184192
/// </exception>
185193
public static TExtension AddOrUpdateExtension<TExtension>(
186194
this DbContextOptionsBuilder optionsBuilder,
187-
Action<TExtension> callback,
195+
Func<TExtension, TExtension> callback,
188196
bool ensureDatabaseProviderRegistered = true)
189197
where TExtension : class, IDbContextOptionsExtension, new()
190198
{
@@ -209,7 +217,7 @@ public static TExtension AddOrUpdateExtension<TExtension>(
209217
/// </exception>
210218
public static TExtension AddOrUpdateExtension<TExtension>(
211219
this DbContextOptionsBuilder optionsBuilder,
212-
Action<TExtension> callback,
220+
Func<TExtension, TExtension> callback,
213221
Func<TExtension> extensionFactory,
214222
bool ensureDatabaseProviderRegistered = true
215223
)
@@ -224,7 +232,7 @@ public static TExtension AddOrUpdateExtension<TExtension>(
224232

225233
var extension = optionsBuilder.Options.FindExtension<TExtension>() ?? extensionFactory();
226234

227-
callback(extension);
235+
extension = callback(extension);
228236

229237
var builder = (IDbContextOptionsBuilderInfrastructure)optionsBuilder;
230238
builder.AddOrUpdateExtension(extension);

src/Thinktecture.EntityFrameworkCore.SqlServer/EntityFrameworkCore/Infrastructure/SqlServerDbContextOptionsExtension.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,10 +187,12 @@ public void Register(Type serviceType, object implementationInstance)
187187
/// <summary>
188188
/// Enables and disables support for queryable parameters.
189189
/// </summary>
190-
public void AddCollectionParameterSupport(bool addCollectionParameterSupport, JsonSerializerOptions? jsonSerializerOptions)
190+
public SqlServerDbContextOptionsExtension AddCollectionParameterSupport(bool addCollectionParameterSupport, JsonSerializerOptions? jsonSerializerOptions)
191191
{
192192
_addCollectionParameterSupport = addCollectionParameterSupport;
193193
_collectionParameterJsonSerializerOptions = jsonSerializerOptions;
194+
195+
return this;
194196
}
195197

196198
/// <inheritdoc />

src/Thinktecture.EntityFrameworkCore.SqlServer/Extensions/SqlServerDbContextOptionsBuilderExtensions.cs

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,11 @@ public static SqlServerDbContextOptionsBuilder AddBulkOperationSupport(
2424
this SqlServerDbContextOptionsBuilder sqlServerOptionsBuilder,
2525
bool addBulkOperationSupport = true)
2626
{
27-
return AddOrUpdateExtension(sqlServerOptionsBuilder, extension => extension.AddBulkOperationSupport = addBulkOperationSupport);
27+
return AddOrUpdateExtension(sqlServerOptionsBuilder, extension =>
28+
{
29+
extension.AddBulkOperationSupport = addBulkOperationSupport;
30+
return extension;
31+
});
2832
}
2933

3034
/// <summary>
@@ -52,7 +56,11 @@ public static SqlServerDbContextOptionsBuilder AddCustomQueryableMethodTranslati
5256
this SqlServerDbContextOptionsBuilder builder,
5357
bool addCustomQueryableMethodTranslatingExpressionVisitorFactory = true)
5458
{
55-
builder.AddOrUpdateExtension(extension => extension.AddCustomQueryableMethodTranslatingExpressionVisitorFactory = addCustomQueryableMethodTranslatingExpressionVisitorFactory);
59+
builder.AddOrUpdateExtension(extension =>
60+
{
61+
extension.AddCustomQueryableMethodTranslatingExpressionVisitorFactory = addCustomQueryableMethodTranslatingExpressionVisitorFactory;
62+
return extension;
63+
});
5664
return builder;
5765
}
5866

@@ -66,7 +74,11 @@ public static SqlServerDbContextOptionsBuilder AddRowNumberSupport(
6674
this SqlServerDbContextOptionsBuilder builder,
6775
bool addRowNumberSupport = true)
6876
{
69-
builder.AddOrUpdateExtension(extension => extension.AddRowNumberSupport = addRowNumberSupport);
77+
builder.AddOrUpdateExtension(extension =>
78+
{
79+
extension.AddRowNumberSupport = addRowNumberSupport;
80+
return extension;
81+
});
7082
return builder;
7183
}
7284

@@ -80,7 +92,11 @@ public static SqlServerDbContextOptionsBuilder AddTableHintSupport(
8092
this SqlServerDbContextOptionsBuilder builder,
8193
bool addTableHintSupport = true)
8294
{
83-
builder.AddOrUpdateExtension(extension => extension.AddTableHintSupport = addTableHintSupport);
95+
builder.AddOrUpdateExtension(extension =>
96+
{
97+
extension.AddTableHintSupport = addTableHintSupport;
98+
return extension;
99+
});
84100
return builder;
85101
}
86102

@@ -101,6 +117,8 @@ public static SqlServerDbContextOptionsBuilder AddTenantDatabaseSupport<TTenantD
101117
{
102118
extension.AddTenantDatabaseSupport = addTenantSupport;
103119
extension.Register(typeof(ITenantDatabaseProviderFactory), typeof(TTenantDatabaseProviderFactory), databaseProviderLifetime);
120+
121+
return extension;
104122
});
105123
return builder;
106124
}
@@ -115,11 +133,15 @@ public static SqlServerDbContextOptionsBuilder UseThinktectureSqlServerMigration
115133
this SqlServerDbContextOptionsBuilder sqlServerOptionsBuilder,
116134
bool useSqlGenerator = true)
117135
{
118-
return AddOrUpdateExtension(sqlServerOptionsBuilder, extension => extension.UseThinktectureSqlServerMigrationsSqlGenerator = useSqlGenerator);
136+
return AddOrUpdateExtension(sqlServerOptionsBuilder, extension =>
137+
{
138+
extension.UseThinktectureSqlServerMigrationsSqlGenerator = useSqlGenerator;
139+
return extension;
140+
});
119141
}
120142

121143
private static SqlServerDbContextOptionsBuilder AddOrUpdateExtension(this SqlServerDbContextOptionsBuilder sqlServerOptionsBuilder,
122-
Action<SqlServerDbContextOptionsExtension> callback)
144+
Func<SqlServerDbContextOptionsExtension, SqlServerDbContextOptionsExtension> callback)
123145
{
124146
ArgumentNullException.ThrowIfNull(sqlServerOptionsBuilder);
125147

src/Thinktecture.EntityFrameworkCore.Sqlite/Extensions/SqliteDbContextOptionsBuilderExtensions.cs

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,11 @@ public static class SqliteDbContextOptionsBuilderExtensions
1818
public static SqliteDbContextOptionsBuilder AddBulkOperationSupport(this SqliteDbContextOptionsBuilder sqliteOptionsBuilder,
1919
bool addBulkOperationSupport = true)
2020
{
21-
return AddOrUpdateExtension(sqliteOptionsBuilder, extension => extension.AddBulkOperationSupport = addBulkOperationSupport);
21+
return AddOrUpdateExtension(sqliteOptionsBuilder, extension =>
22+
{
23+
extension.AddBulkOperationSupport = addBulkOperationSupport;
24+
return extension;
25+
});
2226
}
2327

2428
/// <summary>
@@ -31,7 +35,11 @@ public static SqliteDbContextOptionsBuilder AddCustomQueryableMethodTranslatingE
3135
this SqliteDbContextOptionsBuilder builder,
3236
bool addCustomQueryableMethodTranslatingExpressionVisitorFactory = true)
3337
{
34-
builder.AddOrUpdateExtension(extension => extension.AddCustomQueryableMethodTranslatingExpressionVisitorFactory = addCustomQueryableMethodTranslatingExpressionVisitorFactory);
38+
builder.AddOrUpdateExtension(extension =>
39+
{
40+
extension.AddCustomQueryableMethodTranslatingExpressionVisitorFactory = addCustomQueryableMethodTranslatingExpressionVisitorFactory;
41+
return extension;
42+
});
3543
return builder;
3644
}
3745

@@ -45,12 +53,16 @@ public static SqliteDbContextOptionsBuilder AddRowNumberSupport(
4553
this SqliteDbContextOptionsBuilder builder,
4654
bool addRowNumberSupport = true)
4755
{
48-
builder.AddOrUpdateExtension(extension => extension.AddRowNumberSupport = addRowNumberSupport);
56+
builder.AddOrUpdateExtension(extension =>
57+
{
58+
extension.AddRowNumberSupport = addRowNumberSupport;
59+
return extension;
60+
});
4961
return builder;
5062
}
5163

5264
private static SqliteDbContextOptionsBuilder AddOrUpdateExtension(this SqliteDbContextOptionsBuilder sqliteOptionsBuilder,
53-
Action<SqliteDbContextOptionsExtension> callback)
65+
Func<SqliteDbContextOptionsExtension, SqliteDbContextOptionsExtension> callback)
5466
{
5567
ArgumentNullException.ThrowIfNull(sqliteOptionsBuilder);
5668

tests/Thinktecture.EntityFrameworkCore.Relational.Tests/EntityFrameworkCore/Infrastructure/DefaultSchemaModelCustomizerTests/Customize.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,11 @@ public Customize(ITestOutputHelper testOutputHelper)
1111
{
1212
ConfigureOptionsBuilder = builder =>
1313
{
14-
builder.AddOrUpdateExtension<RelationalDbContextOptionsExtension>(extension => extension.Register(typeof(ModelCustomizer), typeof(ModelCustomizer), ServiceLifetime.Singleton));
14+
builder.AddOrUpdateExtension<RelationalDbContextOptionsExtension>(extension =>
15+
{
16+
extension.Register(typeof(ModelCustomizer), typeof(ModelCustomizer), ServiceLifetime.Singleton);
17+
return extension;
18+
});
1519
builder.ReplaceService<IModelCustomizer, DefaultSchemaModelCustomizer<ModelCustomizer>>();
1620
};
1721
}

tests/Thinktecture.EntityFrameworkCore.Relational.Tests/Extensions/DbContextOptionsBuilderTests/AddOrUpdateExtension.cs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,7 @@ public class AddOrUpdateExtension
99
public void Should_throw_if_database_provider_not_registered()
1010
{
1111
new DbContextOptionsBuilder<DbContextWithoutSchema>()
12-
.Invoking(b => b.AddOrUpdateExtension<RelationalDbContextOptionsExtension>(_ =>
13-
{
14-
}))
12+
.Invoking(b => b.AddOrUpdateExtension<RelationalDbContextOptionsExtension>(extension => extension))
1513
.Should().Throw<InvalidOperationException>().WithMessage("Please register the database provider first (via 'UseSqlServer' or 'UseSqlite' etc).");
1614
}
1715

@@ -20,9 +18,7 @@ public void Should_not_throw_if_database_provider_is_registered_already()
2018
{
2119
new DbContextOptionsBuilder<DbContextWithoutSchema>()
2220
.UseSqlite("DataSource=:memory:")
23-
.Invoking(b => b.AddOrUpdateExtension<RelationalDbContextOptionsExtension>(_ =>
24-
{
25-
}))
21+
.Invoking(b => b.AddOrUpdateExtension<RelationalDbContextOptionsExtension>(extension => extension))
2622
.Should().NotThrow();
2723
}
2824

tests/Thinktecture.EntityFrameworkCore.SqlServer.Tests/IntegrationTestsBase.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,11 @@ protected override void ConfigureTestDbContextProvider(SqlServerTestDbContextPro
4141
optionsBuilder.AddNestedTransactionSupport()
4242
.ConfigureWarnings(warningsBuilder => warningsBuilder.Ignore(CoreEventId.ManyServiceProvidersCreatedWarning));
4343

44-
optionsBuilder.AddOrUpdateExtension<RelationalDbContextOptionsExtension>(extension => extension.Register(typeof(Mock<ITenantDatabaseProvider>), TenantDatabaseProviderMock));
44+
optionsBuilder.AddOrUpdateExtension<RelationalDbContextOptionsExtension>(extension =>
45+
{
46+
extension.Register(typeof(Mock<ITenantDatabaseProvider>), TenantDatabaseProviderMock);
47+
return extension;
48+
});
4549
})
4650
.ConfigureSqlServerOptions((optionsBuilder, _) =>
4751
{

0 commit comments

Comments
 (0)