Share via


計算及自訂儲存區屬性

特定領域語言 (DSL) 中的所有領域屬性都可以在圖表上和語言總管中對使用者顯示,並可由程式碼存取。 不過,屬性與其值的儲存方式不同。

領域屬性的種類

在 DSL 定義中,您可以設定領域屬性的「種類」,如下表所列:

領域屬性種類 描述
標準 (預設) 儲存在「存放區」並序列化為檔案的領域屬性。
計算 不儲存在存放區但會從其他值計算的唯讀領域屬性。 例如,可以從 Person.BirthDate 計算 Person.Age。 您必須提供可執行計算的程式碼。 一般而言,您會從其他領域屬性計算值。 但是,您也可以使用外部資源。
自訂儲存體 未直接儲存在存放區但可取得和設定的領域屬性。 您必須提供取得和設定值的方法。 例如,Person.FullAddress 可以儲存在 Person.StreetAddressPerson.CityPerson.PostalCode 中。 您也可以存取外部資源,例如從資料庫取得和設定值。 當 Store.InUndoRedoOrRollback 為 true 時,您的程式碼不應該在存放區中設定值。 請參閱交易和自訂 Setter

提供儲存體屬性的程式碼

如果您將領域屬性的種類設定為 [計算] 或 [自訂儲存體],則必須提供存取方法。 當您建置解決方案時,錯誤報表會告訴您需要什麼。

定義計算或自訂自訂儲存區屬性

  1. DslDefinition.dsl 中,選取圖表或 [DSL 總管] 中的領域屬性。

  2. 在 [屬性] 視窗中,將 [種類] 欄位設定為 [計算] 或 [自訂儲存體]

    請確定您也已將其 [類型] 設為您想要的內容。

  3. 在 [方案總管] 的工具列中選取 [轉換所有範本]

  4. 在 [建置] 功能表上,選取 [建置方案]

    您收到下列錯誤訊息:「<YourClass> 不包含 Get<YourProperty> 的定義」。

  5. 按兩下錯誤訊息。

    Dsl\GeneratedCode\DomainClasses.csDomainRelationships.cs opens. 在醒目提示的方法呼叫上方,註解會提示您提供 Get<YourProperty>() 的實作。

    注意

    此檔案是從 DslDefinition.dsl 產生。 如果您編輯此檔案,下次選取 [轉換所有範本] 時,您的變更會遺失。 相反地,請在個別的檔案中新增必要的方法。

  6. 在個別資料夾中建立或開啟類別檔案,例如 CustomCode\<YourDomainClass>.cs。

    請確定命名空間在產生的程式碼中相同。

  7. 在類別檔案中,撰寫領域類別的部分實作。 在此類別中,為遺漏的 Get 方法撰寫定義,其類似下列範例:

    namespace Company.FamilyTree
    {  
      public partial class Person
      {
        int GetAgeValue()
        {
          return System.DateTime.Today.Year - this.BirthYear;
        }
      }
    }
    
  8. 如果您將 [種類] 設定為 [自訂儲存體],您也必須提供 Set 方法。 例如:

    void SetAgeValue(int value)
    {
      if (!Store.InUndoRedoOrRollback) this.BirthYear = System.DateTime.Today.Year - value;
    }
    

    Store.InUndoRedoOrRollback 為 true 時,您的程式碼不應該在存放區中設定值。 請參閱交易和自訂 Setter

  9. 建置並執行方案。

  10. 測試屬性。 應請確定您嘗試 [復原] 和 [重做]

交易和自訂 Setter

在自訂儲存體屬性的 set 方法中,您不需要開啟交易。 此方法通常會在作用中交易內呼叫。

不過,如果使用者叫用 [復原] 或 [重做],或者正在回復交易,也可能呼叫 set 方法。 當 InUndoRedoOrRollback 為 true 時,您的 set 方法的行為應該如下所示:

  • 其不得在存放區中進行變更,例如將值指派給其他領域屬性。 復原管理員會設定其值。

  • 不過,應該更新任何外部資源,例如資料庫或檔案內容,或存放區外部的物件。 此方法可確保外部資源與存放區中的值保持同步。

    例如:

    void SetAgeValue(int value)
    {
      // If we are in Undo, no changes to Store objects:
      if (!this.Store.InUndoRedoOrRollback)
      {
        this.BirthYear = System.DateTime.Today.Year - value;
      }
      // But always update external objects:
      System.IO.File.WriteAllText(AgeFile, value);
    }
    

如需交易的詳細資訊,請參閱在程式碼中巡覽和更新模型