/// <summary> /// Třída zapouzdřující základní chování (Layer Supertype) /// </summary> public abstract class BusinessObjectBase : IPersistable { #region Public constants /// <summary> /// Konstanta pro Id objektu bez perzistence v databáze /// </summary> public const int NO_ID = -1; /// <summary> /// Konstanta používaná, jestliže není nalezen objekt/sloupec atd. /// </summary> public const int NOT_FOUND = -1; #endregion Public constants #region Private variables private bool m_isDirty; private bool m_isLoaded; private bool m_isNew; private bool m_isDeleted; #endregion Private variables #region Protected fields protected int m_id; protected ObjectState m_objectState; #endregion Protected fields /// <summary> /// Konstruktor pro objekt bez perzistence v databázi /// </summary> public BusinessObjectBase() : base() { m_isDirty = false; m_id = NO_ID; setNew(); SetLoaded(); m_objectState = ObjectState.Active; } /// <summary> /// Konstruktor pro objekt, jehož data jsou perzistována v databázi /// </summary> public BusinessObjectBase(int id) : base() { m_isDirty = false; m_isLoaded = false; m_id = id; } #region Public properties /// <summary> /// Atribut udávájící, zda byla data změněna oproti datům v databázi /// </summary> public virtual bool IsDirty { get { return m_isDirty; } } /// <summary> /// Atribut udávájící, zda byla data objektu změněna oproti datům v databázi /// </summary> public virtual bool IsLoaded { get { return m_isLoaded; } } /// <summary> /// Atribut má hodnotu true, jestliže jde o objekt bez perzistence /// </summary> public virtual bool IsNew { get { return m_isNew; } } /// <summary> /// Atribut má hodnotu true, jestliže byl vymazán objekt z databáze, případně byl zapsán příznak neaktivní v databázi /// </summary> public virtual bool IsDeleted { get { return m_isDeleted; } } /// <summary> /// Id objektu /// </summary> public virtual int Id { get { return m_id; } } /// <summary> /// Stav objektu /// </summary> public virtual ObjectState ObjectState { get { return m_objectState; } } #endregion Public pproperties #region Public methods #region IPersistable members /// <summary> /// Implementace metody nahraje objekt z databáze /// </summary> public virtual void Load() { if (IsLoaded && IsDeleted) { return; } DataRow row = DataCacheHelper.Instance.GetData(this.GetType(), m_id); try { if (row == null) { DoInternalLoad(); } else { DoInternalLoad(row); } } catch (Exception e) { Trace.WriteLine(e); throw; } SetLoaded(); } /// <summary> /// Implementace metody uloží objekt do databáze /// </summary> public virtual void Save() { if ((!IsLoaded) || (IsDeleted) || ((!IsDirty) && (!IsNew))) { return; } try { DoInternalSave(); } catch (Exception e) { Trace.WriteLine(e); throw; } setClear(); if (ObjectState == ObjectState.Discarded) { SetDeleted(); } } #endregion IPersistable members /// <summary> /// Metoda převede objekt do stavu ObjectState.Discarded /// </summary> public virtual void Discard() { TriggerLoad(); if (IsDeleted) { return; } m_objectState = ObjectState.Discarded; SetDirty(); } #endregion Public methods #region Protected methods /// <summary> /// Metoda zavolá metodu Save na všech IPersistable objektech v argumentu /// </summary> /// <param name="persistableObjectsList">Kolekce objektů implementujících IPersistable </param> protected static void SaveCollection(IEnumerable persistableObjectsList) { foreach (IPersistable persistable in persistableObjectsList) { persistable.Save(); } } /// <summary> /// Metoda nahraje objekt z předaného řádku /// </summary> /// <param name="row">Řádek, z něhož mají být nahrána data</param> /// <remarks>Metoda čte z předaného řádku pouze atribut State</remarks> protected virtual void DoInternalLoad (DataRow row) { Debug.Assert(row.Table.Columns.IndexOf("State") > NOT_FOUND, "Assertion failed - method BusinessObjectBase.DoInternalLoad - Column State does not exist"); m_objectState = (ObjectState) row["State"]; } /// <summary> /// Implementace metody nahraje objekt z databáze /// </summary> /// <remarks>Prázdná implementace</remarks> protected virtual void DoInternalLoad() { } /// <summary> /// Implementace metody uloží objekt do databáze /// </summary> /// <remarks>Prázdná implementace</remarks> protected virtual void DoInternalSave() { } /// <summary> /// Metoda iniciuje nahrávání objektu /// </summary> protected virtual void TriggerLoad() { if((IsLoaded) || (IsNew) || (IsDeleted)) { return; } try { Load(); } catch(Exception e) { Trace.WriteLine(e); throw; } SetLoaded(); } /// <summary> /// Metoda přepisují odvozené třídy v případě, že potřebují inicializovat například instance kolekcí /// </summary> /// <remarks>Metoda nemá implementaci a NENÍ volána z konstruktorů tříy <see cref = "BusinessObjectBase" /> </see></remarks> protected virtual void Init() { } /// <summary> /// Metoda označí objekt jako změněný /// </summary> protected virtual void SetDirty() { if (IsNew || IsDeleted) { return; } m_isDirty = true; } /// <summary> /// Metoda zkontroluje rovnost dvou objektů - jestliže se objekty neshodují, je instance označena jako změněná (Dirty) /// </summary> /// <param name="obj1">První argument operace Equals</param> /// <param name="obj2">Druhý argument operace Equals</param> /// <remarks>Metodu používají odvozené třídy při kontrole změněných atributů</remarks> protected virtual bool CheckEquals(object obj1, object obj2) { if (!Object.Equals(obj1, obj2)) { SetDirty(); return false; } return true; } /// <summary> /// Metoda nastaví příznak, že byla nahrána data objektu /// </summary> protected virtual void SetLoaded() { m_isLoaded = true; } /// <summary> /// Metoda nastaví příznak, že proběhlo zrušení objektu v databázi /// </summary> protected virtual void SetDeleted() { m_isDeleted = true; } #endregion Protected methods #region Private methods /// <summary> /// Metoda označí objekt jako nový (neuložený v databázi) /// </summary> private void setNew() { m_isNew = true; } /// <summary> /// Metoda zruší příznak Nový a Změněný v databázi /// </summary> private void setClear() { m_isNew = false; m_isDirty = false; } #endregion Private methods } /// <summary> /// Rozhraní, které implementují všechny perzistentní objekty /// </summary> public interface IPersistable { /// <summary> /// Implementace metody nahraje objekt z databáze /// </summary> void Load(); /// <summary> /// Implementace metody uloží objekt do databáze /// </summary> void Save(); } /// <summary> /// Enumerace vyjadřující stav objektů /// </summary> public enum ObjectState : int { /// <summary> /// Neaktivní /// </summary> Inactive = 0, /// <summary> /// Aktivní /// </summary> Active = 1, /// <summary> /// Zrušený /// </summary> Discarded = 2 }