Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(EFCore): Fixed that when the configuration is changed, the data context of the current request is not affected #442

Merged
merged 1 commit into from
Feb 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -315,4 +315,51 @@ public void TestUseJsonConfigurationReturnDbConnectionStringProviderIsNotNull()
Assert.AreEqual(1, dbConnectionStringProvider.DbContextOptionsList.Count);
Assert.AreEqual(connectionString, dbConnectionStringProvider.DbContextOptionsList[0].ConnectionString);
}

[TestMethod]
public async Task TestModifyConnectionString()
{
var services = new ServiceCollection();
var configuration = new ConfigurationBuilder()
.AddJsonFile("appsettings.json", true, true)
.Build();
services.AddSingleton<IConfiguration>(configuration);
services.AddMasaDbContext<CustomQueryDbContext>(optionsBuilder => optionsBuilder.UseSqlite());

var serviceProvider = services.BuildServiceProvider();
var connectionStringProvider = serviceProvider.GetService<IConnectionStringProvider>();
Assert.IsNotNull(connectionStringProvider);

var connectionString = await connectionStringProvider.GetConnectionStringAsync();
Assert.AreEqual("data source=test;", connectionString);

var rootPath = AppDomain.CurrentDomain.BaseDirectory;

var expectedNewConnectionString = "data source=test2;";
var oldContent = await File.ReadAllTextAsync(Path.Combine(rootPath, "appsettings.json"));
await File.WriteAllTextAsync(Path.Combine(rootPath, "appsettings.json"),
System.Text.Json.JsonSerializer.Serialize(new
{
ConnectionStrings = new
{
DefaultConnection = expectedNewConnectionString
}
}));

await Task.Delay(2000);

connectionStringProvider = serviceProvider.GetService<IConnectionStringProvider>();
Assert.IsNotNull(connectionStringProvider);

connectionString = await connectionStringProvider.GetConnectionStringAsync();
Assert.AreEqual("data source=test;", connectionString);

connectionStringProvider = serviceProvider.CreateScope().ServiceProvider.GetService<IConnectionStringProvider>();
Assert.IsNotNull(connectionStringProvider);

connectionString = await connectionStringProvider.GetConnectionStringAsync();
Assert.AreEqual(expectedNewConnectionString, connectionString);

await File.WriteAllTextAsync(Path.Combine(rootPath, "appsettings.json"), oldContent);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public async Task TestGetConnectionStringAsyncReturnTest1()
};
});
var serviceProvider = services.BuildServiceProvider();
var options = serviceProvider.GetRequiredService<IOptionsMonitor<MasaDbConnectionOptions>>();
var options = serviceProvider.GetRequiredService<IOptionsSnapshot<MasaDbConnectionOptions>>();
var defaultConnectionStringProvider = new DefaultConnectionStringProvider(options);
var connectionString = await defaultConnectionStringProvider.GetConnectionStringAsync();
Assert.AreEqual("Test1", connectionString);
Expand All @@ -36,7 +36,7 @@ public async Task TestGetConnectionStringAsyncAndNameIsEmptyReturnTest1()
};
});
var serviceProvider = services.BuildServiceProvider();
var options = serviceProvider.GetRequiredService<IOptionsMonitor<MasaDbConnectionOptions>>();
var options = serviceProvider.GetRequiredService<IOptionsSnapshot<MasaDbConnectionOptions>>();
var defaultConnectionStringProvider = new DefaultConnectionStringProvider(options);
var connectionString = await defaultConnectionStringProvider.GetConnectionStringAsync(string.Empty);
Assert.AreEqual("Test1", connectionString);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ namespace Microsoft.EntityFrameworkCore;

public class DbConnectionStringProvider : DbConnectionStringProviderBase
{
private readonly IOptionsMonitor<MasaDbConnectionOptions> _options;
private readonly IOptionsSnapshot<MasaDbConnectionOptions> _options;

public DbConnectionStringProvider(IOptionsMonitor<MasaDbConnectionOptions> options) => _options = options;
public DbConnectionStringProvider(IOptionsSnapshot<MasaDbConnectionOptions> options) => _options = options;

protected override List<MasaDbContextConfigurationOptions> GetDbContextOptionsList()
=> _options.CurrentValue.ConnectionStrings.Select(item => new MasaDbContextConfigurationOptions(item.Value)).Distinct().ToList();
=> _options.Value.ConnectionStrings.Select(item => new MasaDbContextConfigurationOptions(item.Value)).Distinct().ToList();
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,17 @@ namespace Microsoft.EntityFrameworkCore;

public class DefaultConnectionStringProvider : IConnectionStringProvider
{
private readonly IOptionsMonitor<MasaDbConnectionOptions> _options;
private readonly IOptionsSnapshot<MasaDbConnectionOptions> _options;

public DefaultConnectionStringProvider(IOptionsMonitor<MasaDbConnectionOptions> options) => _options = options;
public DefaultConnectionStringProvider(IOptionsSnapshot<MasaDbConnectionOptions> options) => _options = options;

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

public string GetConnectionString(string name = ConnectionStrings.DEFAULT_CONNECTION_STRING_NAME)
{
if (string.IsNullOrEmpty(name))
return _options.CurrentValue.ConnectionStrings.DefaultConnection;
return _options.Value.ConnectionStrings.DefaultConnection;

return _options.CurrentValue.ConnectionStrings.GetConnectionString(name);
return _options.Value.ConnectionStrings.GetConnectionString(name);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ private static IServiceCollection AddCoreServices<TDbContextImplementation, TUse

services.TryAddSingleton<IConcurrencyStampProvider, DefaultConcurrencyStampProvider>();
services.TryAddScoped<IConnectionStringProvider, DefaultConnectionStringProvider>();
services.TryAddSingleton<IDbConnectionStringProvider, DbConnectionStringProvider>();
services.TryAddScoped<IDbConnectionStringProvider, DbConnectionStringProvider>();

services.TryAdd(
new ServiceDescriptor(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ namespace Masa.Contrib.Data.UoW.EFCore;
public class DefaultConnectionStringProvider : IConnectionStringProvider
{
private readonly IUnitOfWorkAccessor _unitOfWorkAccessor;
private readonly IOptionsMonitor<MasaDbConnectionOptions> _options;
private readonly IOptionsSnapshot<MasaDbConnectionOptions> _options;
private readonly ILogger<DefaultConnectionStringProvider>? _logger;

public DefaultConnectionStringProvider(
IUnitOfWorkAccessor unitOfWorkAccessor,
IOptionsMonitor<MasaDbConnectionOptions> options,
IOptionsSnapshot<MasaDbConnectionOptions> options,
ILogger<DefaultConnectionStringProvider>? logger = null)
{
_unitOfWorkAccessor = unitOfWorkAccessor;
Expand All @@ -26,7 +26,7 @@ public string GetConnectionString(string name = ConnectionStrings.DEFAULT_CONNEC
if (_unitOfWorkAccessor.CurrentDbContextOptions != null)
return _unitOfWorkAccessor.CurrentDbContextOptions.ConnectionString;

var connectionStrings = _options.CurrentValue.ConnectionStrings;
var connectionStrings = _options.Value.ConnectionStrings;
var connectionString = string.IsNullOrEmpty(name) ? connectionStrings.DefaultConnection : connectionStrings.GetConnectionString(name);
if (string.IsNullOrEmpty(connectionString))
_logger?.LogError("Failed to get database connection string, please check whether the configuration of IOptionsSnapshot<MasaDbConnectionOptions> is abnormal");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public static void AddIsolation(this IServiceCollection services, Action<Isolati
services
.TryAddConfigure<IsolationDbConnectionOptions>()
.AddTransient(typeof(IEventMiddleware<>), typeof(IsolationEventMiddleware<>))
.TryAddSingleton<IDbConnectionStringProvider, IsolationDbContextProvider>();
.TryAddScoped<IDbConnectionStringProvider, IsolationDbContextProvider>();

if (services.Any(service => service.ServiceType == typeof(IConnectionStringProvider)))
services.Replace(new ServiceDescriptor(typeof(IConnectionStringProvider), typeof(DefaultDbIsolationConnectionStringProvider),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,18 @@ namespace Masa.Contrib.Isolation;

public class IsolationDbContextProvider : DbConnectionStringProviderBase
{
private readonly IOptionsMonitor<IsolationDbConnectionOptions> _options;
private readonly IOptionsSnapshot<IsolationDbConnectionOptions> _options;

public IsolationDbContextProvider(IOptionsMonitor<IsolationDbConnectionOptions> options) => _options = options;
public IsolationDbContextProvider(IOptionsSnapshot<IsolationDbConnectionOptions> options) => _options = options;

protected override List<MasaDbContextConfigurationOptions> GetDbContextOptionsList()
{
var connectionStrings = _options.CurrentValue.IsolationConnectionStrings
var connectionStrings = _options.Value.IsolationConnectionStrings
.Select(connectionString => connectionString.ConnectionString)
.Distinct()
.ToList();
if (!connectionStrings.Contains(_options.CurrentValue.ConnectionStrings.DefaultConnection))
connectionStrings.Add(_options.CurrentValue.ConnectionStrings.DefaultConnection);
if (!connectionStrings.Contains(_options.Value.ConnectionStrings.DefaultConnection))
connectionStrings.Add(_options.Value.ConnectionStrings.DefaultConnection);

return connectionStrings.Select(connectionString => new MasaDbContextConfigurationOptions(connectionString)).ToList();
}
Expand Down