2013-07-05 60 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

相关问题