我們在之前的文章提過關於物件更新深度的問題。db4o 的 Activation 則是設計用來簡化處理更新深度問題,達到 transpartent activation 的效果!
如同在物件更新深度一文中提到的,我們先將資料庫內塞滿 Article
物件。若是我們不再開啟資料庫前設定好更新深度的相關參數,則可能會造成取出的物件有部分內容是 null 值。
要讓 db4o 運行於 Transparent Activation 模式的方法很簡單:
Db4oFactory.Configure().Add(new TransparentActivationSupport());就這樣,我們不需要再擔心會遇到 null 值的問題了!實際上,當啟用 Transparent Activation 模式時,任何未實做
Db4objects.Db4o.TA.IActivatable
介面的物件被使用時將會自動的 activate。很明顯的是,這種方式會造成記憶體的大量消耗,也造成載入時間變慢。要避免這種情況,我們可以替我們的類別實做 Activatable
介面。下面是我們將 Article
物件加上 Activatable
的實做:
public class Article: IActivatable { // ... [Transient] private IActivator _activator; private Sentence title; public Sentence SentenceOfTitle { get { Activate(ActivationPurpose.Read); return title; } set { Activate(ActivationPurpose.Write); title = value; } } // 這裡假設 IsStructure 不需要 activation private bool _IsStructure; public bool IsStructure { get { // Activate(ActivationPurpose.Read); return _IsStructure; } set { // Activate(ActivationPurpose.Write); _IsStructure = value; } } private List一個_SentencesOfAbs; public List SentencesOfAbstract { get { Activate(ActivationPurpose.Read); return _SentencesOfAbs; } set { Activate(ActivationPurpose.Write); _SentencesOfAbs = value; } } public override String ToString() { Activate(ActivationPurpose.Read); return string.Format("T:{0}", title); } // implement IActivatable public void Activate(ActivationPurpose purpose) { if(_activator != null) { _activator.Activate(purpose); } } public void Bind(IActivator activator) { if (_activator == activator) { return; } if (activator != null && null != _activator) { throw new System.InvalidOperationException(); } _activator = activator; } }
IActivatable
類別必須儲存 db4o 提供給 bind
方法的Activator
物件於一個 transient 變數中(上例中的 _activator
變數),並且在預被 active 的欄位被呼叫前,呼叫 Activate()
方法。假若該物件已經被 activate,這個方法會立即回傳,否則 activation 會自動發生。
沒有留言:
張貼留言