Внедрение помощника в DbContext в .NET Core

Я использую 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));
    }
}

С DI вам не нужно создавать MyDbContext, дело в том, чтобы он был создан кем-то другим (в данном случае asp.net), поэтому это не проблема.

Alex Sikilinda 22.10.2018 21:02

Почему мне не нужно создавать DbContext и как? Можете объяснить поподробнее? @AlexSikilinda

realist 22.10.2018 21:07

Вы вводите MyDbContext в контроллеры так же, как вы вводите IAuditHelper в MyDbContext.

Alex Sikilinda 22.10.2018 21:10

Но у меня нет интерфейса IMyDbContext. Стоит ли создавать интерфейс? Потому что для его внедрения мне нужен интерфейс. @AlexSikilinda

realist 22.10.2018 21:14

Интерфейс создавать не нужно, проверьте Using DbContext with dependency injection из docs.microsoft.com/en-us/ef/core/miscellaneous/…

Alex Sikilinda 22.10.2018 21:18

Эта ссылка предназначена для классической инъекции dbContext. Но в MyDbContext.cs есть зависимость auditHelper. Моя проблема в том. @AlexSikilinda

realist 22.10.2018 21:26

@HasanOzdemir, как только контекст зарегистрирован в контейнере, нам не нужно инициализировать его вручную. контейнер создаст граф объекта при разрешении контекста для инъекции.

Nkosi 22.10.2018 22:38

Спасибо за ответы как @Nkosi, так и AlexSikilinka.

realist 22.10.2018 22:50

Есть ли конкретная причина наличия параметра options в конструкторе, но вызова GetOptions для base?

Nkosi 22.10.2018 22:55

У меня есть 20 разных API-сервисов. И я не хочу писать строку подключения 20 раз. Итак, я написал на MyDbContext.cs только один раз. Если есть способ получше, я могу его изменить. Потому что я не знаю, это неправильно? @Nkosi

realist 22.10.2018 23:22
Стоит ли изучать 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 называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
10
396
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

После регистрации контекста и его зависимостей в контейнере

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. Этот ответ проясняет мне вопрос о зависимости.

realist 22.10.2018 23:27

Но таким образом я должен писать connectionString 20 раз для каждого проекта службы API. Какой из них правильный @Nkosi?

realist 22.10.2018 23:37

@HasanOzdemir Вы можете иметь строку подключения в файле конфигурации и загружать ее при запуске. не нужно ничего переписывать.

Nkosi 22.10.2018 23:38

Моя структура такая. У меня есть 20 проектов Web Api и один проект библиотеки классов. У проектов Web Api есть startup.cs. Но в библиотеке классов нет startup.cs. Какой из проектов мне написать в строке подключения и где? Поскольку в библиотеке классов нет app.config или startup.cs. @Nkosi

realist 22.10.2018 23:50

@HasanOzdemir, это начинает распространяться в новый домен. Задайте новый вопрос, который демонстрирует то, что вы объяснили в последнем комментарии. Должен быть в состоянии получить больше возможностей от сообщества.

Nkosi 23.10.2018 00:20

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