Правильный способ внедрения зависимости в DBContext - PullRequest
0 голосов
/ 20 июня 2020

Я пытаюсь создать проект, используя подход DDD и микросервис, и у меня есть небольшой вопрос об отправке событий домена в другой сервис. Я использую EF Core для связи с базой данных и MassTransit для отправки событий.

Прямо сейчас у меня есть переопределенный метод SaveChangesAsyn c в моем DBConetxt, где я отправляю событие домена через шину, которую я создал в Startup.cs, используя MassTransit.

DBContext:

private readonly IBus _bus;

public StudentsDbContext(DbContextOptions options, IBus bus) : base(options)
{
    _bus = bus;
}

...

public override async Task<int> SaveChangesAsync(CancellationToken cancellationToken = new CancellationToken())
{
    var aggregates = ChangeTracker.Entries<IAggregateRoot>().ToList();

    foreach (var aggregate in aggregates)
    {
        foreach (var domainEvent in aggregate.Entity.DomainEvents)
        {
            await _bus.Publish(domainEvent, domainEvent.GetType(), cancellationToken);
        }
        aggregate.Entity.ClearEvents();
    }

    return await base.SaveChangesAsync(cancellationToken);
}

Как видите, мне нужно вставить IBus в конструктор DbContext, и из-за этого у меня возникли проблемы. Например, я не могу зарегистрировать свой DbContext в файле Startup.cs с помощью метода AddDbContext из-за моего конструктора, поэтому мне нужно сделать это следующим образом:

services.AddSingleton<IBus>(bus);

services.AddTransient<StudentsDbContext>(provider =>
{
    var options = new DbContextOptionsBuilder()
        .UseSqlServer(Configuration.GetConnectionString("Default"))
        .Options;

    return new StudentsDbContext(options, provider.GetService<IBus>());
});

Из-за этого у меня проблемы с миграциями.

Unable to create an object of type 'StudentsDbContext'. For the different patterns supported at design time, see https://go.microsoft.com/fwlink/?linkid=851728

А также я хочу использовать объединенный DbContext, например, с AddDbContextPool.

Итак, у меня есть 2 вопроса:

  1. Как правильно ввести зависимость в DbContext? Это хорошая или плохая практика?
  2. Это вообще хороший подход - отправлять события домена из DbContext? Может есть способ получше?

1 Ответ

0 голосов
/ 22 июня 2020

Вы делаете неправильный путь. Я думаю, вам нужно исправить свой код на:

public StudentsDbContext(DbContextOptions<OrderingContext> options, IBus bus) : base(options)
        {
            _bus = bus ?? throw new ArgumentNullException(nameof(bus));

        }

и в вашем запуске:

services.AddDbContext<StudentsDbContext>(options =>
            {
                options.UseSqlServer(Configuration["ConnectionString"]);
            });     
...