0

DBContext は存続期間が短く、リクエストごとに作成および破棄されます。保存前および保存後に実行したいタスクがいくつかあり、これらをある種のイベント モデルで処理したいと考えています。RXが正しいルートなのだろうかと思っています。

シングルトンの「ハブ」を作成し、DBContext で BeforeChange (SavingChanges イベント) を発生させ、ポスト保存 (該当するイベントなし) の Observable を発生させ、それらを長寿命のハブに「プッシュ」する方法はありますか?

実際には、「ハブ」シングルトンでこれを行いたい

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

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

しかし、AttachContext が生成されたオブザーバブルを、それ (およびそのすべてのサブスクリプション) を置き換えるのではなく、既存の Saves オブザーバブルに単純にフィードするような方法で?

4

1 に答える 1

1

はい。ネストされたオブザーバブル + マージを使用します。

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 コンテキストが 1 回の保存に使用されることがわかっている場合は、.FirstAsync()への呼び出しの最後に a を追加できます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;
}
于 2013-07-05T20:30:54.313 に答える