Как создать горячий RX наблюдаемый из нескольких DBC-контекстов

Вопрос:

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

Есть ли какой-то способ создания одноуровневого «хаба», после чего мой DBContext будет поднимать событие BeforeChange (событие SavingChanges) и сохранять сообщение (не применимо к событию). Наблюдаемые и «нажимают» их на долгоживущий хаб.

В сущности, я хотел бы сделать это в своем «хаб» singleton

    public IObservable<EventPattern<EventArgs>> Saves = new Subject<EventPattern<EventArgs>>();

public void AttachContext(DbContext context)
{
Saves = Observable.FromEventPattern<EventArgs>(((IObjectContextAdapter)context).ObjectContext, "SavingChanges");
}

но таким образом, что AttachContext просто передает свои сгенерированные наблюдаемые в exisitng Сохраняет наблюдение, а не заменяет его (и все его подписки)?

Лучший ответ:

Да. Используйте вложенный наблюдаемый + слияние:

private readonly Subject<IObservable<EventPattern<EventArgs>> _contexts = new Subject<IObservable<EventPattern<EventArgs>>();

private readonly IObservable<EventPattern<EventArgs>> _saves = _contexts.Merge();

public IObservable<EventPattern<EventArgs>> Saves { get { return _saves; } }

public void AttachContext(DbContext context)
{
    _contexts.OnNext(Observable.FromEventPattern<EventArgs>(((IObjectContextAdapter)context).ObjectContext, "SavingChanges"));
}

Единственная проблема заключается в том, что список наблюдаемых контекстов будет неограничен, так как Observable.FromEventPattern никогда не завершается. Таким образом, это фактически утечка памяти, как закодированная.

Если вы знаете, что контекст db будет использоваться для одного сохранения, вы можете добавить .FirstAsync() в конец вызова Observable.FromEventPattern. Это приведет к тому, что ваш объект перестанет смотреть контекст, как только он увидит событие.

Это все еще страдает от проблемы, связанной с контекстом, но его сохранение никогда не выполняется (из-за логики или ошибки или чего-то еще).

Единственный способ, который я знаю для решения проблемы, — это изменить AttachContext чтобы вернуть IDisposable который должен использовать вызывающий, когда они хотят отделить контекст:

public IDisposable AttachContext(DbContext context)
{
    var detachSignal = new AsyncSubject<Unit>();
    var disposable = Disposable.Create(() =>
    {
        detachSignal.OnNext(Unit.Default);
        detachSignal.OnCompleted();
    });
    var events = Observable.FromEventPattern<EventArgs>(((IObjectContextAdapter)context).ObjectContext, "SavingChanges");

    _contexts.OnNext(events.TakeUntil(detachSignal));
    return disposable;
}

Оцените статью
TechArks.Ru
Добавить комментарий