我们为我们的客户提供了一个选项来遵循主题启动器所要求的方法。为了做到这一点,我们甚至在我们的 eXpressApp 框架 (XAF) 产品中实现了一个类似的解决方案(ObjectMaterialized 以及 ObjectContext 和 ObjectStateManager 的其他事件)。这在大多数情况下都没有任何问题,因为实体与“上下文”具有相同的生命周期。这也有助于我们提高在设计数据模型和业务逻辑时面临同样困难的客户的可用性。
在我们的例子中,域模型没有与特定的持久性技术相结合,因为我们在 ORM 上下文上有一个特殊的“ObjectSpace”抽象(除了实体框架之外,我们的产品还支持我们内部的 ORM - eXpress Persistent Objects(XPO ))。
因此,我们为我们的客户提供了一个 IObjectSpaceLink 接口(具有单个 IObjectSpace 属性),该接口应该由需要其业务逻辑上下文的实体来实现。
此外,我们为最流行的业务规则提供了一个 IXafEntityObject 接口(带有 OnCreated、OnLoaded、OnSaving 方法)。下面是一个从我们的 BCL 实现两个接口的实体示例:
// IObjectSpaceLink
IObjectSpace IObjectSpaceLink.ObjectSpace {
get { return objectSpace; }
set { objectSpace = value; }
}
// IXafEntityObject
void IXafEntityObject.OnCreated() {
KpiInstance kpiInstance = (KpiInstance)objectSpace.CreateObject(typeof(KpiInstance));
kpiInstance.KpiDefinition = this;
KpiInstances.Add(kpiInstance);
Range = DevExpress.ExpressApp.Kpi.DateRangeRepository.FindRange("Now");
RangeToCompare = DevExpress.ExpressApp.Kpi.DateRangeRepository.FindRange("Now");
}
void IXafEntityObject.OnSaving() {}
void IXafEntityObject.OnLoaded() {}
反过来,这里是我们框架的代码,它在内部将这些部分链接在一起(下面是实体框架 6)。
private void ObjectContext_SavingChanges(Object sender, EventArgs e) {
IList modifiedObjects = GetModifiedObjects();
foreach(Object obj in modifiedObjects) {
if(obj is IXafEntityObject) {
((IXafEntityObject)obj).OnSaving();
}
}
}
private void ObjectContext_ObjectMaterialized(Object sender, ObjectMaterializedEventArgs e) {
if(e.Entity is IXafEntityObject) {
((IXafEntityObject)e.Entity).OnLoaded();
}
}
private void ObjectStateManager_ObjectStateManagerChanged(Object sender, CollectionChangeEventArgs e) {
if(e.Action == CollectionChangeAction.Add) {
if(e.Element is INotifyPropertyChanged) {
((INotifyPropertyChanged)e.Element).PropertyChanged += new PropertyChangedEventHandler(Object_PropertyChanged);
}
if(e.Element is IObjectSpaceLink) {
((IObjectSpaceLink)e.Element).ObjectSpace = this;
}
}
else if(e.Action == CollectionChangeAction.Remove) {
if(e.Element is INotifyPropertyChanged) {
((INotifyPropertyChanged)e.Element).PropertyChanged -= new PropertyChangedEventHandler(Object_PropertyChanged);
}
if(e.Element is IObjectSpaceLink) {
((IObjectSpaceLink)e.Element).ObjectSpace = null;
}
}
OnObjectStateManagerChanged(e);
}
public virtual Object CreateObject(Type type) {
Guard.ArgumentNotNull(type, "type");
CheckIsDisposed();
Object obj = CreateObjectCore(type);
if(obj is IXafEntityObject) {
((IXafEntityObject)obj).OnCreated();
}
SetModified(obj);
return obj;
}
我希望这些信息对您有所帮助。