Я использую следующую реализацию DbContext
.
public class MyDbContext : DbContext
{
private readonly IDateTimeOffset? _dateTime;
public MyDbContext(DbContextOptions<MyDbContext> options)
: base(options)
{
}
public MyDbContext(
DbContextOptions<MyDbContext> options,
IDateTimeOffset dateTime)
: base(options)
{
_dateTime = dateTime;
}
// entities
public override Task<int> SaveChangesAsync(CancellationToken cancellationToken = default)
{
// set CreatedAt to DateTime.Now for all new entries
foreach (var entry in ChangeTracker.Entries<AuditableEntity>())
{
if (entry.State == EntityState.Added)
{
entry.Entity.CreatedAt = _dateTime!.Now;
}
}
return base.SaveChangesAsync(cancellationToken);
}
}
Класс зависит от IDateTimeOffset
, который является простой оболочкой для методов stati c из DateTimeOffset
, что позволяет мне протестировать метод SaveChangesAsync
.
interface IDateTimeOffset { DateTimeOffset Now { get; } }
class MachineDateTimeOffset : IDateTimeOffset { public DateTimeOffset Now => DateTimeOffset.Now; }
Теперь предположим, что мы находимся в сценарии с высоким трафиком c где создание DbContext
для каждого запроса оказывает слишком большое давление на G C, и этот AddDbContextPool
решит эту проблему. Использование этого метода приведет к выдаче System.InvalidOperationException: The DbContext of type 'MyDbContext' cannot be pooled because it does not have a single public constructor accepting a single parameter of type DbContextOptions
, потому что MyDbContext
имеет два конструктора, включая один с двумя параметрами. Совместное использование и повторное использование IDateTimeOffset
в разных запросах не является проблемой, потому что это синглтон, так есть ли способ сделать это?