Как выполнить метод до того, как сервис scoped расположен в ядре asp.net? - PullRequest
0 голосов
/ 21 февраля 2019

У меня есть специальное промежуточное ПО, цель которого - подписаться на события Eb Core dbcontext и отслеживать изменения, которые происходят с объектами.Промежуточное программное обеспечение создает экземпляр InteractionService в качестве экземпляра с областью действия в начале каждого запроса.Вот так выглядит мое промежуточное ПО:

public static IApplicationBuilder UseDbContextActivityTracker<TContext>(this IApplicationBuilder app)
    where TContext : DbContext
{
    app.Use(async (context, next) =>
    {
        var service = context.RequestServices.GetRequiredService<InteractionService<TContext>>();
        await next.Invoke();
        service.PersistLogs();
    });

    return app;
}

, и вот как я использую промежуточное ПО в своем методе Confiure класса Startup:

options.UseDbContextActivityTracker<ApplicationDbContext>();

В конструкторе моего InteractionService Iполучить ссылку на dbcontext через DI, и я подписываюсь на события:

public InteractionService(TContext context)
{
    this.context = context;
    this.context.ChangeTracker.StateChanged += ChangeTracker_StateChanged;
}

Во время прослушивания событий, которые происходят с dbContext во время запроса, я сохраняю соответствующую информацию в своих собственных объектахи это прекрасно работает.Однако в конце запроса я хочу сохранить изменения в базе данных.Я попытался сделать свой класс InteractionService IDisposable и в методе Dispose я вызываю другой DbContext, в котором я сохраняю свои сущности.Как и ожидалось, я получил ошибку «Соединение уже закрыто». Каково правильное место для сохранения моих сущностей в БД после завершения запроса?

1 Ответ

0 голосов
/ 21 февраля 2019

@ Панагиотис Канавос указал мне верное направление.Моя проблема заключалась в том, как получить правильно ограниченный DbContext для записи изменений.В моем InteractionService вместо внедрения DbContext через конструктор я создал его вручную с помощью serviceProvider.Я изменил это:

public CampusAxessInteractionStore(MyDbContext context)
{
    this.context = context;
}

на это:

public CampusAxessInteractionStore(IServiceProvider serviceProvider)
{
    var scopeResolver = serviceProvider.GetRequiredService<IServiceScopeFactory>().CreateScope();
    this.context = scopeResolver.ServiceProvider.GetRequiredService<CampusAxessDbContext>();
}

и теперь сохранение работает. Я все еще не уверен, что это правильный подход, хотя .Если кто-то может указать мне, как это должно быть сделано правильно, сделайте это, и я удалю свой ответ и отмечу ваш ответ как правильный.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...