Plugins per-context (meta-issue)
See original GitHub issueThis is a meta-issue to track a number of challenges related to using plugins on a per-context basis.
Plugin registration overridden with multiple contexts (#654)
Per https://github.com/npgsql/Npgsql.EntityFrameworkCore.PostgreSQL/issues/654#issuecomment-425555810:
INpgsqlOptions
(e.g.opts
in your snippet) is a singleton service, so it’s likely that this is caused by the first configuration delegate being replaced (instead of wrapped by) the second configuration delegate.
Can we scope plugin registration by type of DbContext
to avoid interfering with context-specific configurations?
Can’t mix BCL and NodaTime types (#747)
Per https://github.com/npgsql/Npgsql.EntityFrameworkCore.PostgreSQL/issues/568#issuecomment-412329701:
Long story short, when you set up the ADO NodaTime plugin, it “hijacks”
NpgsqlDbType.Timestamp
and routes it to the NodaTime type handler, instead of the built-inDateTime
type handler. The NodaTime type hander doesn’t know how to writeDateTime
, so you get the above exception. EF Core, at its level, always setsNpgsqlDbType
on parameters to unambiguously determine which PostgreSQL type it wants to send.This unfortunately means that you can’t mix both regular
DateTime
and NodaTime types in the same application.
Can we improve the per-connection plugin handling, such that it might be possible to support BCL and NodaTime types, as long as they are not mixed on the same DbContext
?
// Keep BCL types for some entities and contexts
class LegacyEntity
{
public DateTime SomeTimestamp { get; set; }
}
class LegacyDbContext : DbContext
{
public DbSet<LegacyEntity> LegacyEntities { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> base.OnConfiguring(optionsBuilder);
}
// While using NodaTime types for other entities and contexts
class FutureEntity
{
public Instant SomeTimestamp { get; set; }
}
class FutureDbContext : DbContext
{
public DbSet<FutureEntity> FutureEntities { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder.UseNodaTime();
}
Related
Issue Analytics
- State:
- Created 5 years ago
- Comments:8 (6 by maintainers)
@roji The mental model isn’t that simple, so no worries. You have a better understanding than most. 😃
@roji It’s not quite like that. Typically, an application will have one service provider even for multiple types of context. That is, using a different context type does not in of itself result in a new service provider.
However, each context instance also creates a D.I. scope. This means each context instance (and hence also each context type) has its own set of scoped services. But will use the same singleton services. This is one of the reasons why singleton services are a more efficient.
This is coupled with the model cache, which is, by default, keyed off the context type. So each context type will have a different model. This is exposed via the IModel scoped service.
Now it’s possibly that some configuration of a context instance of any type may result in a new service provider being created. For example, using a context with a different database provider configured, or changing sensitive data logging, will trigger a new service provider to be created. This is because these things need to change the behavior of singleton services. Ideally, a typical application won’t do this more than a few times at most.