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





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