Skip to content

Commit 8479650

Browse files
authored
fix(EFCore): Fixed that when the configuration is changed, the data context of the current request is not affected (#442)
1 parent aa667fe commit 8479650

File tree

8 files changed

+66
-19
lines changed

8 files changed

+66
-19
lines changed

src/Contrib/Data/Orm/EFCore/Masa.Contrib.Data.EFCore.Tests/DbContextTest.cs

+47
Original file line numberDiff line numberDiff line change
@@ -315,4 +315,51 @@ public void TestUseJsonConfigurationReturnDbConnectionStringProviderIsNotNull()
315315
Assert.AreEqual(1, dbConnectionStringProvider.DbContextOptionsList.Count);
316316
Assert.AreEqual(connectionString, dbConnectionStringProvider.DbContextOptionsList[0].ConnectionString);
317317
}
318+
319+
[TestMethod]
320+
public async Task TestModifyConnectionString()
321+
{
322+
var services = new ServiceCollection();
323+
var configuration = new ConfigurationBuilder()
324+
.AddJsonFile("appsettings.json", true, true)
325+
.Build();
326+
services.AddSingleton<IConfiguration>(configuration);
327+
services.AddMasaDbContext<CustomQueryDbContext>(optionsBuilder => optionsBuilder.UseSqlite());
328+
329+
var serviceProvider = services.BuildServiceProvider();
330+
var connectionStringProvider = serviceProvider.GetService<IConnectionStringProvider>();
331+
Assert.IsNotNull(connectionStringProvider);
332+
333+
var connectionString = await connectionStringProvider.GetConnectionStringAsync();
334+
Assert.AreEqual("data source=test;", connectionString);
335+
336+
var rootPath = AppDomain.CurrentDomain.BaseDirectory;
337+
338+
var expectedNewConnectionString = "data source=test2;";
339+
var oldContent = await File.ReadAllTextAsync(Path.Combine(rootPath, "appsettings.json"));
340+
await File.WriteAllTextAsync(Path.Combine(rootPath, "appsettings.json"),
341+
System.Text.Json.JsonSerializer.Serialize(new
342+
{
343+
ConnectionStrings = new
344+
{
345+
DefaultConnection = expectedNewConnectionString
346+
}
347+
}));
348+
349+
await Task.Delay(2000);
350+
351+
connectionStringProvider = serviceProvider.GetService<IConnectionStringProvider>();
352+
Assert.IsNotNull(connectionStringProvider);
353+
354+
connectionString = await connectionStringProvider.GetConnectionStringAsync();
355+
Assert.AreEqual("data source=test;", connectionString);
356+
357+
connectionStringProvider = serviceProvider.CreateScope().ServiceProvider.GetService<IConnectionStringProvider>();
358+
Assert.IsNotNull(connectionStringProvider);
359+
360+
connectionString = await connectionStringProvider.GetConnectionStringAsync();
361+
Assert.AreEqual(expectedNewConnectionString, connectionString);
362+
363+
await File.WriteAllTextAsync(Path.Combine(rootPath, "appsettings.json"), oldContent);
364+
}
318365
}

src/Contrib/Data/Orm/EFCore/Masa.Contrib.Data.EFCore.Tests/DefaultConnectionStringProviderTest.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ public async Task TestGetConnectionStringAsyncReturnTest1()
1818
};
1919
});
2020
var serviceProvider = services.BuildServiceProvider();
21-
var options = serviceProvider.GetRequiredService<IOptionsMonitor<MasaDbConnectionOptions>>();
21+
var options = serviceProvider.GetRequiredService<IOptionsSnapshot<MasaDbConnectionOptions>>();
2222
var defaultConnectionStringProvider = new DefaultConnectionStringProvider(options);
2323
var connectionString = await defaultConnectionStringProvider.GetConnectionStringAsync();
2424
Assert.AreEqual("Test1", connectionString);
@@ -36,7 +36,7 @@ public async Task TestGetConnectionStringAsyncAndNameIsEmptyReturnTest1()
3636
};
3737
});
3838
var serviceProvider = services.BuildServiceProvider();
39-
var options = serviceProvider.GetRequiredService<IOptionsMonitor<MasaDbConnectionOptions>>();
39+
var options = serviceProvider.GetRequiredService<IOptionsSnapshot<MasaDbConnectionOptions>>();
4040
var defaultConnectionStringProvider = new DefaultConnectionStringProvider(options);
4141
var connectionString = await defaultConnectionStringProvider.GetConnectionStringAsync(string.Empty);
4242
Assert.AreEqual("Test1", connectionString);

src/Contrib/Data/Orm/EFCore/Masa.Contrib.Data.EFCore/DbConnectionStringProvider.cs

+3-3
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ namespace Microsoft.EntityFrameworkCore;
77

88
public class DbConnectionStringProvider : DbConnectionStringProviderBase
99
{
10-
private readonly IOptionsMonitor<MasaDbConnectionOptions> _options;
10+
private readonly IOptionsSnapshot<MasaDbConnectionOptions> _options;
1111

12-
public DbConnectionStringProvider(IOptionsMonitor<MasaDbConnectionOptions> options) => _options = options;
12+
public DbConnectionStringProvider(IOptionsSnapshot<MasaDbConnectionOptions> options) => _options = options;
1313

1414
protected override List<MasaDbContextConfigurationOptions> GetDbContextOptionsList()
15-
=> _options.CurrentValue.ConnectionStrings.Select(item => new MasaDbContextConfigurationOptions(item.Value)).Distinct().ToList();
15+
=> _options.Value.ConnectionStrings.Select(item => new MasaDbContextConfigurationOptions(item.Value)).Distinct().ToList();
1616
}

src/Contrib/Data/Orm/EFCore/Masa.Contrib.Data.EFCore/DefaultConnectionStringProvider.cs

+4-4
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,17 @@ namespace Microsoft.EntityFrameworkCore;
55

66
public class DefaultConnectionStringProvider : IConnectionStringProvider
77
{
8-
private readonly IOptionsMonitor<MasaDbConnectionOptions> _options;
8+
private readonly IOptionsSnapshot<MasaDbConnectionOptions> _options;
99

10-
public DefaultConnectionStringProvider(IOptionsMonitor<MasaDbConnectionOptions> options) => _options = options;
10+
public DefaultConnectionStringProvider(IOptionsSnapshot<MasaDbConnectionOptions> options) => _options = options;
1111

1212
public Task<string> GetConnectionStringAsync(string name = ConnectionStrings.DEFAULT_CONNECTION_STRING_NAME) => Task.FromResult(GetConnectionString(name));
1313

1414
public string GetConnectionString(string name = ConnectionStrings.DEFAULT_CONNECTION_STRING_NAME)
1515
{
1616
if (string.IsNullOrEmpty(name))
17-
return _options.CurrentValue.ConnectionStrings.DefaultConnection;
17+
return _options.Value.ConnectionStrings.DefaultConnection;
1818

19-
return _options.CurrentValue.ConnectionStrings.GetConnectionString(name);
19+
return _options.Value.ConnectionStrings.GetConnectionString(name);
2020
}
2121
}

src/Contrib/Data/Orm/EFCore/Masa.Contrib.Data.EFCore/Extensions/ServiceCollectionExtensions.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ private static IServiceCollection AddCoreServices<TDbContextImplementation, TUse
5555

5656
services.TryAddSingleton<IConcurrencyStampProvider, DefaultConcurrencyStampProvider>();
5757
services.TryAddScoped<IConnectionStringProvider, DefaultConnectionStringProvider>();
58-
services.TryAddSingleton<IDbConnectionStringProvider, DbConnectionStringProvider>();
58+
services.TryAddScoped<IDbConnectionStringProvider, DbConnectionStringProvider>();
5959

6060
services.TryAdd(
6161
new ServiceDescriptor(

src/Contrib/Data/UoW/Masa.Contrib.Data.UoW.EFCore/DefaultConnectionStringProvider.cs

+3-3
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@ namespace Masa.Contrib.Data.UoW.EFCore;
66
public class DefaultConnectionStringProvider : IConnectionStringProvider
77
{
88
private readonly IUnitOfWorkAccessor _unitOfWorkAccessor;
9-
private readonly IOptionsMonitor<MasaDbConnectionOptions> _options;
9+
private readonly IOptionsSnapshot<MasaDbConnectionOptions> _options;
1010
private readonly ILogger<DefaultConnectionStringProvider>? _logger;
1111

1212
public DefaultConnectionStringProvider(
1313
IUnitOfWorkAccessor unitOfWorkAccessor,
14-
IOptionsMonitor<MasaDbConnectionOptions> options,
14+
IOptionsSnapshot<MasaDbConnectionOptions> options,
1515
ILogger<DefaultConnectionStringProvider>? logger = null)
1616
{
1717
_unitOfWorkAccessor = unitOfWorkAccessor;
@@ -26,7 +26,7 @@ public string GetConnectionString(string name = ConnectionStrings.DEFAULT_CONNEC
2626
if (_unitOfWorkAccessor.CurrentDbContextOptions != null)
2727
return _unitOfWorkAccessor.CurrentDbContextOptions.ConnectionString;
2828

29-
var connectionStrings = _options.CurrentValue.ConnectionStrings;
29+
var connectionStrings = _options.Value.ConnectionStrings;
3030
var connectionString = string.IsNullOrEmpty(name) ? connectionStrings.DefaultConnection : connectionStrings.GetConnectionString(name);
3131
if (string.IsNullOrEmpty(connectionString))
3232
_logger?.LogError("Failed to get database connection string, please check whether the configuration of IOptionsSnapshot<MasaDbConnectionOptions> is abnormal");

src/Contrib/Isolation/Masa.Contrib.Isolation/Extensions/ServiceCollectionExtensions.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public static void AddIsolation(this IServiceCollection services, Action<Isolati
3030
services
3131
.TryAddConfigure<IsolationDbConnectionOptions>()
3232
.AddTransient(typeof(IEventMiddleware<>), typeof(IsolationEventMiddleware<>))
33-
.TryAddSingleton<IDbConnectionStringProvider, IsolationDbContextProvider>();
33+
.TryAddScoped<IDbConnectionStringProvider, IsolationDbContextProvider>();
3434

3535
if (services.Any(service => service.ServiceType == typeof(IConnectionStringProvider)))
3636
services.Replace(new ServiceDescriptor(typeof(IConnectionStringProvider), typeof(DefaultDbIsolationConnectionStringProvider),

src/Contrib/Isolation/Masa.Contrib.Isolation/IsolationDbContextProvider.cs

+5-5
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,18 @@ namespace Masa.Contrib.Isolation;
55

66
public class IsolationDbContextProvider : DbConnectionStringProviderBase
77
{
8-
private readonly IOptionsMonitor<IsolationDbConnectionOptions> _options;
8+
private readonly IOptionsSnapshot<IsolationDbConnectionOptions> _options;
99

10-
public IsolationDbContextProvider(IOptionsMonitor<IsolationDbConnectionOptions> options) => _options = options;
10+
public IsolationDbContextProvider(IOptionsSnapshot<IsolationDbConnectionOptions> options) => _options = options;
1111

1212
protected override List<MasaDbContextConfigurationOptions> GetDbContextOptionsList()
1313
{
14-
var connectionStrings = _options.CurrentValue.IsolationConnectionStrings
14+
var connectionStrings = _options.Value.IsolationConnectionStrings
1515
.Select(connectionString => connectionString.ConnectionString)
1616
.Distinct()
1717
.ToList();
18-
if (!connectionStrings.Contains(_options.CurrentValue.ConnectionStrings.DefaultConnection))
19-
connectionStrings.Add(_options.CurrentValue.ConnectionStrings.DefaultConnection);
18+
if (!connectionStrings.Contains(_options.Value.ConnectionStrings.DefaultConnection))
19+
connectionStrings.Add(_options.Value.ConnectionStrings.DefaultConnection);
2020

2121
return connectionStrings.Select(connectionString => new MasaDbContextConfigurationOptions(connectionString)).ToList();
2222
}

0 commit comments

Comments
 (0)