Я использую asp.net Core 2.0. А мой DbContext такой, как показано ниже. AuditHelper - это класс для регистрации всех изменений базы данных. Итак, я ввел AuditHelper в MyDbContext.cs. Но я считаю, что это неправильный способ? Например, когда я создаю экземпляр MyDbContext, я должен указать вспомогательный параметр аудита, например MyDbContext context = new MyDbContext(null);.
.
Верен ли мой стиль DbContext или есть способ лучше?
public class MyDbContext : DbContext
{
private readonly IAuditHelper auditHelper;
public MyDbContext(DbContextOptions<MyDbContext> options, IAuditHelper auditHelper)
: base(GetOptions())
{
this.auditHelper = auditHelper;
}
private static DbContextOptions GetOptions()
{
return SqlServerDbContextOptionsExtensions.UseSqlServer(new DbContextOptionsBuilder(), "server=asdf; database=asdf; user id=asdf; password=asdf").Options;
}
public override async Task<int> SaveChangesAsync(CancellationToken cancellationToken = default(CancellationToken))
{
var audits = auditHelper.AddAuditLog(base.ChangeTracker);
return (await base.SaveChangesAsync(true, cancellationToken));
}
}
Почему мне не нужно создавать DbContext и как? Можете объяснить поподробнее? @AlexSikilinda
Вы вводите MyDbContext в контроллеры так же, как вы вводите IAuditHelper в MyDbContext.
Но у меня нет интерфейса IMyDbContext. Стоит ли создавать интерфейс? Потому что для его внедрения мне нужен интерфейс. @AlexSikilinda
Интерфейс создавать не нужно, проверьте Using DbContext with dependency injection из docs.microsoft.com/en-us/ef/core/miscellaneous/…
Эта ссылка предназначена для классической инъекции dbContext. Но в MyDbContext.cs есть зависимость auditHelper. Моя проблема в том. @AlexSikilinda
@HasanOzdemir, как только контекст зарегистрирован в контейнере, нам не нужно инициализировать его вручную. контейнер создаст граф объекта при разрешении контекста для инъекции.
Спасибо за ответы как @Nkosi, так и AlexSikilinka.
Есть ли конкретная причина наличия параметра options в конструкторе, но вызова GetOptions для base?
У меня есть 20 разных API-сервисов. И я не хочу писать строку подключения 20 раз. Итак, я написал на MyDbContext.cs только один раз. Если есть способ получше, я могу его изменить. Потому что я не знаю, это неправильно? @Nkosi





После регистрации контекста и его зависимостей в контейнере
services.AddScoped<IAuditHelper, AuditHelper>();
services.AddDbContext<MyDbContext>(options =>
options.UseSqlServer("server=asdf; database=asdf; user id=asdf; password=asdf")
);
тогда нет необходимости инициализировать его (DbContext) вручную.
Контейнер создаст граф объекта при разрешении контекста для внедрения.
Обратите внимание, что статическая функциональность GetOptions может быть перенесена на ConfigureServices при запуске, как показано выше.
Что позволяет контексту оставаться простым.
public class MyDbContext : DbContext {
private readonly IAuditHelper auditHelper;
public MyDbContext(DbContextOptions<MyDbContext> options, IAuditHelper auditHelper)
: base(options) {
this.auditHelper = auditHelper;
}
public override Task<int> SaveChangesAsync(CancellationToken cancellationToken = default(CancellationToken)) {
var audits = auditHelper.AddAuditLog(base.ChangeTracker);
return base.SaveChangesAsync(true, cancellationToken);
}
}
Большое спасибо за подробный ответ @Nkosi. Этот ответ проясняет мне вопрос о зависимости.
Но таким образом я должен писать connectionString 20 раз для каждого проекта службы API. Какой из них правильный @Nkosi?
@HasanOzdemir Вы можете иметь строку подключения в файле конфигурации и загружать ее при запуске. не нужно ничего переписывать.
Моя структура такая. У меня есть 20 проектов Web Api и один проект библиотеки классов. У проектов Web Api есть startup.cs. Но в библиотеке классов нет startup.cs. Какой из проектов мне написать в строке подключения и где? Поскольку в библиотеке классов нет app.config или startup.cs. @Nkosi
@HasanOzdemir, это начинает распространяться в новый домен. Задайте новый вопрос, который демонстрирует то, что вы объяснили в последнем комментарии. Должен быть в состоянии получить больше возможностей от сообщества.
С DI вам не нужно создавать
MyDbContext, дело в том, чтобы он был создан кем-то другим (в данном случае asp.net), поэтому это не проблема.