You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
We want to pass the connection to our DbContext using the IDbContextFactory.CreateDbContext method. You can't pass any DbContextOptions to the CreateDbContext method.
The longer story is that we're creating dotnet templates, in a hexagonal architecture (ports & adapters). So we don't know the exact type of the DbContext and we want to have an Entity Framework adapter and an NServiceBus adapter. We want the NServiceBus endpoint configuration in the NServiceBus adapter project, not in the Program.cs (although Program.cs will call the adapter and tell it to set itself up).
As stated in their docs, "the business data has to reuse the same connection context as NServiceBus persistence."
We believe this could work with (something like) the following code:
// This code is inside our NServiceBus adapter project
endpointConfiguration.RegisterComponents(c =>
{
c.AddScoped(b => {
var session = b.GetRequiredService<ISqlStorageSession>();
// TDbContext would be provided by Program.cs, because our template doesn't know the concrete type:
var contextFactory = b.GetRequiredService<IDbContextFactory<TDbContext>>();
// This is the code recommended by NServiceBus:
// var context = new ReceiverDataContext(new DbContextOptionsBuilder<ReceiverDataContext>()
// .UseSqlServer(session.Connection)
// .Options);
// This is the code we would like to be able to use:
var options = new OptionsBuilder<TDbContext>().UseSqlService(session.Connection).Options;
var context = contextFactory.CreateDbContext(b, options);
//Use the same underlying ADO.NET transaction
context.Database.UseTransaction(session.Transaction);
//Ensure context is flushed before the transaction is committed
session.OnSaveChanges((s, token) => context.SaveChangesAsync(token));
return context;
});
});
Maybe I'm underestimating the problem or not seeing the reasons for not doing so, but I believe all we would need is to add the following code to DbContextFactory (and the interface as well of course):
public virtual TContext CreateDbContext(IServiceProvider serviceProvider, DbContextOptions<TContext> options)
=> _factory(serviceProvider, options);
I'm not sure if the serviceProvider is necessary or if it should use the one in the private field.
I can provide a PR if you're open to this change.
The text was updated successfully, but these errors were encountered:
@petermorlion Is there a reason you can't implement your own factory that has the behavior you want? (I'm not saying we can't add things to IDbContextFactory, but I want clarification if you think this is necessary. Generally, EF is agnostic to how types are registered in the application's service provider.)
We want to pass the connection to our
DbContext
using theIDbContextFactory.CreateDbContext
method. You can't pass anyDbContextOptions
to theCreateDbContext
method.The longer story is that we're creating dotnet templates, in a hexagonal architecture (ports & adapters). So we don't know the exact type of the
DbContext
and we want to have an Entity Framework adapter and an NServiceBus adapter. We want the NServiceBus endpoint configuration in the NServiceBus adapter project, not in the Program.cs (although Program.cs will call the adapter and tell it to set itself up).As stated in their docs, "the business data has to reuse the same connection context as NServiceBus persistence."
We believe this could work with (something like) the following code:
Maybe I'm underestimating the problem or not seeing the reasons for not doing so, but I believe all we would need is to add the following code to DbContextFactory (and the interface as well of course):
I'm not sure if the
serviceProvider
is necessary or if it should use the one in the private field.I can provide a PR if you're open to this change.
The text was updated successfully, but these errors were encountered: