I have two POCO types, A and B. I have a repository for each, Rep<A
> and Rep<B
>, both of which implement IRep<A
> and IRep<B
> served up by an IoC container (AutoFac in this case).
There are several kinds of repositories - load-on-demand from a DB (or whatever), lazy-loaded in-memory collections, cached web-service results, etc. Callers can't tell the difference. Both Rep<A
> and Rep<B
> happen to be in-memory collections as A's and B's don't change very much and live a long time.
One of the properties of B is an A. What I do now is, when a B is asked for its A, B gets IRep<A
> to find its A and returns it. It does this every time - every request for B's A involves IRep<A
>.Find(). The upside is B's never hold onto A's and each request takes into account whatever the state of Rep happens to be. The downside is a lot of IoC/IRep<A
> churn.
I am thinking of using the Lazy<T
> pattern here so that a B asks IRep<A
> once and holds onto what it got. But what happens if an A is deleted from its repository?
I am looking for a clean way for Rep<A
> to notify whoever is interested when it has changed. In my example, a certain B's A may be deleted, so I would like Rep<A
> to raise an event when something is deleted, or added, etc. Rep<B
> might subscribe to this event to clean up any B's that refer to A's that are now gone, etc. How to wire it up?
Ideally nothing changes when instantiating a Rep<A
>. It should have no idea who listens, and A's might be manipulated all day long without ever firing up a Rep.
But when Rep<B
> is born it needs a way to subscribe to Rep<A
>'s event. There might not be a Rep<A
> alive yet, but surely there will be once a B is asked for its A, so it seems ok to fire up a Rep<A
>.
In essense, when Rep<B
> is instantiated, it want it to register itself with Rep<A
> for the event notification. I don't want to pollute the IRep<T
> interface becaue this shouldn't matter to anyone outside the Repository layer. And other types of repositories might not have to worry about this at all.
Does this make any sense?
发布评论
评论(1)
如果您让
Rep
返回一个可以计算为 A 的“可观察”对象,并且还具有一个在 A 发生变化时引发的可订阅事件,会怎么样?只是一个想法。这样,您就不必让处理程序检查以确保它们的 A 发生了变化;如果他们正在侦听的事件被触发,则它涉及他们的实例而不是任何其他实例。您可以将其编码如下:
现在,如果内部引用发生更改,或者可观察对象被处置(也处置了内部引用),则使用代码将收到通知。为了让可观察对象在 As 的子引用发生变化时也通知消费代码,A 本身必须是可观察的,触发由
Observable
处理的事件,该事件将通过 ReferenceChanged 或更具体的方式“冒泡”它处理程序,例如 InstanceDataChanged(或任何您想要的名称)。What if you made the
Rep<A>
return an "observable" object that can evaluate to an A, and also has a subscribable event that is raised when something about that A changes? Just a thought. This way, you don't have to have the handlers check to make sure that their A changed; if the event they're listening for is fired, it concerns their instance and not any other.You might code it as follows:
Now, the consuming code will be notified if the internal reference is changed, or the observable is disposed (which also disposes of the internal reference). To have the observable also notify consuming code if child references of As change, A must itself be observable, firing an event handled by
Observable<T>
which will "bubble" it through either ReferenceChanged or a more specific handler such as InstanceDataChanged,(or whatever you want to call it).