Пул DbContext с одноэлементными зависимостями - PullRequest
1 голос
/ 14 июля 2020

Я использую следующую реализацию 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 в разных запросах не является проблемой, потому что это синглтон, так есть ли способ сделать это?

1 Ответ

1 голос
/ 14 июля 2020

Совместное использование и повторное использование IDateTimeOffset в разных запросах не является проблемой, потому что это синглтон, есть ли способ сделать это?

public class MyDbContext : DbContext
{
    public static IDateTimeOffset _dateTime;

И ставить при запуске.

...