2013-07-05 84 views
0

DBContexts是短暫的,創建和銷燬每個請求。我有很多我希望在保存前和保存後執行的任務,我想用某種事件模型來處理這些任務。我想知道RX是正確的路線。如何從多個DBContexts創建一個熱的RX觀察值

是否有某種方式創建一個單一的「樞紐」,然後導致我的DBContext提高BeforeChange(SavingChanges事件)和後保存(沒有適用的事件)觀察,並將它們「推」到長期居住的樞紐。

實際上我想做到這一點在我的「樞紐」單身

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

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

,但這樣的方式AttachContext簡單地養活自己產生可觀測到exisitng保存observabe,而不是取代它(所有的訂閱)?

回答

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永遠不會完成。所以這實際上是一個編碼的內存泄漏。

如果您知道的分貝範圍內將被用於單個保存,那麼你可以在通話的末尾添加.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; 
} 
+0

我認爲IDisposable的解決方案應該工作,但我對於它到底在做什麼感覺有點失落。我會圍繞它做一些閱讀,但如果您有任何像樣的文章可以指向我,我會很感激! – Andiih

相關問題