Мы предоставляем нашим клиентам возможность следовать подходу, запрошенному инициатором темы. Чтобы сделать это, мы даже реализовали подобное решение (ObjectMaterialized и другие события ObjectContext и ObjectStateManager) в нашем продукте eXpressApp Framework (XAF). Это работает без проблем в большинстве сценариев, так как сущности имеют то же время жизни, что и «контекст». Это также помогает нам повысить удобство использования для наших клиентов, которые сталкиваются с такими же трудностями при разработке своих моделей данных и бизнес-логики.
В нашем случае модель предметной области не связана с определенной технологией персистентности, поскольку у нас есть специальная абстракция «ObjectSpace» в контексте ORM (в дополнение к Entity Framework наш продукт поддерживает наш собственный ORM - eXpress Persistent Объекты (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() {}
В свою очередь, вот код нашей платформы, которая внутренне связывает эти части (ниже для Entity Framework 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;
}
Надеюсь, эта информация поможет вам.