我有两种POCO类型,A和B.我有一个存储库,每个,Rep <A
&gt;和Rep <B
&gt;,两者都实现了IRep <A
&gt;和IRep <B
&gt;由IoC容器(在这种情况下为AutoFac)提供。
有几种存储库 - 来自数据库(或其他)的按需加载,延迟加载的内存中集合,缓存的Web服务结果等。调用者无法区分它们。 Rep <A
&gt;和Rep <B
&gt;恰好是内存中的集合,因为A和B的变化并不会很长,而且很长一段时间。
B的一个属性是A.我现在要做的是,当B要求其A时,B得到IRep <A
&gt;找到它的A并返回它。它每次都这样做 - 每次请求B的A都涉及IRep <A
&gt; .Find()。好处是B从不持有A,每个请求都考虑到Rep的状态。缺点是很多IoC / IRep <A
&gt;流失。
我正在考虑使用Lazy <T
&gt;这里模式,以便B要求IRep <A
&gt;曾经坚持到底。但是如果A从其存储库中删除会发生什么?
我正在为Rep <A
&gt;寻找一种干净的方式。在变更时通知有兴趣的人。在我的示例中,某个B的A可能会被删除,所以我希望Rep <A
&gt;在删除或添加某些内容时举起活动等.Res <B
&gt;可能会订阅此事件来清理任何引用现在已经消失的A的B,等等。如何连接它?
理想情况下,在实例化Rep <A
&gt;时不会发生任何变化。它应该不知道谁会倾听,A可能会被整天操纵而不会激活一个众议员。
但是当Rep <B
&gt;天生就需要一种方式来订阅Rep <A
&gt;的事件。可能没有Rep <A
&gt;还活着,但肯定会有一个B被要求它的A,所以似乎可以启动一个Rep <A
&gt ;.
在本质上,当Rep <B
&gt;实例化,它希望它与Rep <A
&gt;注册自己。用于事件通知。我不想污染IRep <T
&gt;界面因为这对于Repository层之外的任何人都无关紧要。其他类型的存储库可能根本不用担心这一点。
这有意义吗?
答案 0 :(得分:3)
如果你使Rep<A>
返回一个可以评估为A的“可观察”对象,并且还有一个可订阅的事件,当有关该事件的某些内容发生变化时,该怎么办?只是一个想法。这样,您就不必检查处理程序以确保他们的 A已更改;如果他们正在侦听的事件被解雇,则涉及他们的实例而不是其他事件。
您可以按如下方式对其进行编码:
public class Observable<T>:IDisposable
{
private T instance;
public T Instance
{
get{return instance;}
set{
instance = value;
var handlers = ReferenceChanged;
if(handlers != null) handlers(this, instance);
}
public static implicit operator T(Observable<T> obs)
{
return obs.Instance;
}
//DO NOT attach anonymous delegates or lambdas to this event, or you'll cause a leak
public event EventHandler<T> ReferenceChanged;
public void Dispose()
{
var handlers = ReferenceChanged;
if(handlers != null) handlers(this, null);
foreach(var handler in handlers) ReferenceChanged -= handler;
}
}
public class Rep<T>
{
private Dictionary<T, Observable<T>> observableDictionary = new Dictionary<T, Observable<T>>();
...
public Observable<T> GetObservableFactory(Predicate<T> criteria)
{
//criteria should test only uniquely-identifying information
if(observableDictionary.Keys.Any(criteria))
return observableDictionary[observableDictionary.Keys.First(criteria)];
else
{
//TODO: get object from source according to criteria and set to variable queryResult
var observable = new Observable<T>{Instance = queryResult};
observableDictionary.Add(queryResult, observable);
return observable;
}
}
}
...
var observableA = myRepA.GetObservable(myCriteria);
observableA.ReferenceChanged += DoSomethingWhenReferenceChanges;
现在,如果更改了内部引用,或者处理了observable(也处理了内部引用),将通知使用代码。要让observable也通知消费代码,如果子引用为As的变化,A本身必须是可观察的,则触发由Observable<T>
处理的事件,该事件将通过ReferenceChanged或更具体的处理程序(例如InstanceDataChanged)将其“冒泡”(或者你想称之为什么。)