Неожиданное поведение ILoggerFactory в EF Core

Мне нужно добавить регистратор для определенного dbContext. Например, у меня есть следующий код:

var dbContextOptionsBuilder1 = new DbContextOptionsBuilder();
dbContextOptionsBuilder1.UseSqlServer("Data Source=localhost;Initial Catalog=DataBase;Integrated Security=True");
var dbContext1 = new DbContext(dbContextOptionsBuilder1.Options);
var loggerFactory1 = dbContext1.GetService<ILoggerFactory>();
loggerFactory1.AddProvider(new CustomLoggerProvider());

var dbContextOptionsBuilder2 = new DbContextOptionsBuilder();
dbContextOptionsBuilder2.UseSqlServer("Data Source=localhost;Initial Catalog=DataBase;Integrated Security=True");
var dbContext2 = new DbContext(dbContextOptionsBuilder2.Options);
var loggerFactory2 = dbContext2.GetService<ILoggerFactory>();

Если я разверну непубличных членов loggerFactory1, я увижу добавленный мною CustomLoggerProvider (_providerRegistrations = Count = 1). Но если я разверну непубличных членов loggerFactory2, я увижу тот же CustomLoggerProvider (_providerRegistrations = Count = 1), хотя я не добавлял его в dbContext2.

Также я получил еще одно неожиданное поведение в следующем коде:

public class MyDbContext : DbContext
{
    private readonly IDbService dbService;
    public MyDbContext(IDbService dbService, DbContextOptions options) : base(options)
    {

    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {

    }
}

var dbContextOptionsBuilder1 = new DbContextOptionsBuilder();
dbContextOptionsBuilder1.UseSqlServer("Data Source=localhost;Initial Catalog=DataBase;Integrated Security=True");
var dbContext1 = new DbContext(dbContextOptionsBuilder1.Options);
var loggerFactory1 = dbContext1.GetService<ILoggerFactory>();
loggerFactory1.AddProvider(new CustomLoggerProvider());

var dbContextOptionsBuilder2 = new DbContextOptionsBuilder();
dbContextOptionsBuilder2.UseSqlServer("Data Source=localhost;Initial Catalog=DataBase;Integrated Security=True");
var dbContext2 = new DbContext(dbContextOptionsBuilder2.Options);
var loggerFactory2 = dbContext2.GetService<ILoggerFactory>();

var dbContextOptionsBuilder3 = new DbContextOptionsBuilder();
dbContextOptionsBuilder3.UseSqlServer("Data Source=localhost;Initial Catalog=DataBase;Integrated Security=True");
var dbContext3 = new MyDbContext(new DbService(), dbContextOptionsBuilder3.Options);
var loggerFactory3 = dbContext3.GetService<ILoggerFactory>();
loggerFactory3.AddProvider(new CustomLoggerProvider());

var dbContextOptionsBuilder4 = new DbContextOptionsBuilder();
dbContextOptionsBuilder4.UseSqlServer("Data Source=localhost;Initial Catalog=DataBase;Integrated Security=True");
var dbContext4 = new MyDbContext(new DbService(), dbContextOptionsBuilder4.Options);
var loggerFactory4 = dbContext4.GetService<ILoggerFactory>();

В данном случае я получил 1 CustomLoggerProvider в dbContext3 (_providerRegistrations = Count = 1) и такой же регистратор в dbContext4 (_providerRegistrations = Count = 1). Таким образом, нет никакой связи между dbContext1, dbContext2 и dbContext3, dbContext4. Итак, если я добавлю еще один CustomLoggerProvider в dbContext1, я получу следующий результат:

dbContext1: 2 CustomLoggerProvider (_providerRegistrations = Count = 2)
dbContext2: 2 CustomLoggerProvider (_providerRegistrations = Count = 2)
dbContext3: 1 CustomLoggerProvider (_providerRegistrations = Count = 1)
dbContext4: 1 CustomLoggerProvider (_providerRegistrations = Count = 1)

Как правильно работать с ILoggerFactory?

Все это будет иметь смысл, если вы прочитаете это. Фабрика логгера является синглтоном (то есть, если вы инициализировали ее как рекомендуется).

Gert Arnold 19.01.2019 17:24

См. документацию по EF Core — логирование. В нем явно указано, что ILoggerFactory является одноэлементным и содержит предупреждение «Очень важно, чтобы приложения не создавали новый экземпляр ILoggerFactory для каждого экземпляра контекста. Это приведет к утечке памяти и снижению производительности.». Другими словами, ведение журнала для контекста БД не поддерживается.

Ivan Stoev 19.01.2019 17:25
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
2
43
0

Другие вопросы по теме