I propose to change the section "Cross-context transaction (relational databases only)".
Current approach as it now stands suggest to change the super class constructor signature of DbContext, this can be cumbersome since everyone who develops DbContext super classes need to change their constructors.
With my approach below it is not required to refactor your precious DbContexts which may be separated in different projects etc. The super classes of DbContext can be "regular" and have a DbContextOptions as a argument as in every other example. The trick is then to provide the connection to shared contexts using the regular AddDbContext configuration.
Create a simple DI class that wraps the shared connection e.g.
/// <summary>
/// This allows to share a DbConnection within a scope, e.g. between DbContexts so they can perform transactions
/// </summary>
public class DbContextConnectionConfiguration : IDisposable
{
private readonly DbConnection _dbConnection;
private readonly Action<DbConnection, DbContextOptionsBuilder> _configuration;
private readonly bool _dispose;
public DbContextConnectionConfiguration(DbConnection dbConnection, Action<DbConnection, DbContextOptionsBuilder> configuration, bool dispose = true)
{
_dbConnection = dbConnection;
_configuration = configuration;
_dispose = dispose;
}
public void Configure(DbContextOptionsBuilder optionsBuilder)
{
_configuration(_dbConnection, optionsBuilder);
}
public void Dispose()
{
if (_dispose) {
_dbConnection.Dispose();
}
}
}
Now only thing required is to inject this to AddDbContext calls in Startup.cs:
public void ConfigureServices(IServiceCollection services)
{
services.AddScoped(t => new DbContextConnectionConfiguration(
new SqliteConnection(Configuration.GetConnectionString("Default")),
(c, o) => o.UseSqlite(c)
));
services.AddDbContext<YourFirstDbContext>((s, o) =>
{
s.GetService<DbContextConnectionConfiguration>().Configure(o);
});
services.AddDbContext<YourSecondDbContext>((s, o) =>
{
s.GetService<DbContextConnectionConfiguration>().Configure(o);
});
}
That's it, there is no need to refactor your DbContext's just to share a connection.
Moved from aspnet/Docs#4220. Filed by @Ciantic, pertaining to the following doc: https://docs.microsoft.com/ef/core/saving/transactions
I propose to change the section "Cross-context transaction (relational databases only)".
Current approach as it now stands suggest to change the super class constructor signature of DbContext, this can be cumbersome since everyone who develops DbContext super classes need to change their constructors.
With my approach below it is not required to refactor your precious DbContexts which may be separated in different projects etc. The super classes of DbContext can be "regular" and have a DbContextOptions as a argument as in every other example. The trick is then to provide the connection to shared contexts using the regular
AddDbContext
configuration.Now only thing required is to inject this to
AddDbContext
calls in Startup.cs:That's it, there is no need to refactor your DbContext's just to share a connection.