トピックスターターが要求するアプローチに従うオプションをクライアントに提供します。これを行うために、eXpressApp Framework(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() {}
次に、これらの部分を内部でリンクするフレームワークのコードを次に示します(以下は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;
}
この情報がお役に立てば幸いです。