2019 年 2 月

第 34 卷,第 2 期

本文章是由機器翻譯。

[程式設計師雜談]

Naked 撰寫程式碼:Naked 演講者

藉由Ted Neward |2019 年 2 月

Ted Neward在最後一部分中,我介紹了以巢狀物件架構 」 (NOF) 中,尋找隱藏的架構消失的 UI 與資料持續性的物件,讓開發人員解決所有只專注於建置的方式,您一律已指示在學校的網域物件您已了解 MVC 和 Web Api 和 HTTP 與 SQL 以及資料庫連接管理和相依性插入和所有其他項目會耗用大部分的把時間和精力之前。它是個不錯,如果它的運作方式,但最後一篇文章並未完全負荷與功能。在本文中,我將深入了解您可以定義在收到的 NOF 類別和方式,將會轉譯成 UI 和資料庫的持續性。

Naked 概念

我太遠的程式碼之前,不過,讓我們熟悉的一些 NOF 術語,因為它會提供一段深入了解如何建立者和其困難之處看到 [world。

首先,完整的體驗的重心是網域的物件,代表的狀態和系統行為的物件。中收到的 NOF,任何 「 純舊C#物件 」 可以是網域物件,它會遵循一些規則,以便收到的 NOF 可以提供支援,它必須: 屬性必須為虛擬;必須初始化任何集合的成員;並收到的 NOF 建議針對建構函式,因為記憶體中的物件可能有不同的生命週期,比您習慣。我稍後將討論此更多。

並非所有功能融入也物件的範例,不過。通常會有物件上運作,但不屬於內其中一個特別的行為。而非試過,強制為物件的行為,以任意方式,收到的 NOF 提供支援服務,提供 「 外部 」 的物件,例如建立、 擷取或網域物件上的其他作業的行為。服務也可做為外部系統服務,例如電子郵件伺服器的閘道。

使用者的觀點而言,UI 需要提供行為的使用者可以觸發程序,而這些統稱為動作,這通常會對應到 UI 中的功能表。動作可以探索到的 (或 「 參與 」) 從各種來源,但是通常他們就可以找到透過反映對網域物件或服務,並顯示在 UI 中所示。您可以量身打造的大部分此探索和顯示中,當且其中有需要,而且我會檢查多個這個方式時,才使用自訂屬性。

這將所有變得更清楚,透過程式碼,因此...應我們嗎?

Naked 會議

在 MEAN 系列中,我用於簡單的網域範例 (在會議中提供討論演講者) 於背景建置程式碼,而且似乎合理地使用相同的範例,在這裡,如果基於任何其他原因,比起比較影響同類。當領域模型,它會是很簡單:主講人包括名字、 姓氏、 年齡、 主體 (C#、 VB、 Java、 JavaScript、 TypeScript 和 c + +),和平均評等 (從零到五個) 啟動。我可以在稍後加入簡報,其中將包含標題和描述,一旦您了解如何設定物件之間的關聯性的但讓我們為了簡單起見現在。

最後一篇文章所述,我會先使用收到的 NOF 範本.zip,要開始,種子,因此下載從收到的 NOF GitHub 中的連結專案讀我檔案 (bit.ly/2PMojiQ),將它解壓縮到剛產生的子目錄,並在 Visual Studio 中開啟方案。現在開啟 Template.Model 專案節點,並刪除 Student.cs 和 ExampleService.cs 檔案;您不想要儲存的學生,畢竟。您要儲存所主講人 (和更新版本的簡報,但我就留給您重構之後,即可查看程度 NakedObjects 會支援重構)。

若要清除,我要做幾件事,以做為巢狀物件專案中的網域類型支援喇叭:我需要建立的網域型別;我要確定我的存放庫物件,來取得並建立它們,我必須先確定存放庫,會提供給巢狀的物件架構,以便產生功能表而最後,我需要 (或者,老實說,想) 至某些說話者資料庫中植入。

說話者的物件

建置出演講者備忘類別是實際的最簡單的四個步驟。在 Template.Model 專案中,建立 Speaker.cs 檔案,並在 Template.Model 命名空間內的該檔案中,建立一個叫做說話者的公用類別。說話者會定義 (目前) 的名字、 姓氏和年齡,因此,建立三個屬性,但將它們標示為 「 虛擬 」;這是以便在執行階段,NakedObjects 可略過一些其他行為在沒有所需的魔力的地方 (透過子類別)。

讓我們加入一些複雜性主講人,不過。首先,您往往想非網域相關的識別碼儲存在資料庫中,可用來當做主索引鍵,不允許使用者使用或修改該識別項的物件。在 NakedObjects 系統中,我可以加上旗標 「 NakedObjectsIgnore"自訂屬性的任何的屬性,讓它不會出現在 UI 中,讓我們新增 「 識別碼 」 屬性 (一次虛擬) 具有此屬性設定旗標的整數。此外,不想要建立的 「 計算 」 使用的其他資料元素的屬性,讓我們加入 「 FullName 」 唯讀屬性,它會串連名字和姓氏不常見。NakedObjects 並不會負責編輯此 UI,因為它不需要為虛擬。

完成時,您應該得到類似如下:

public class Speaker
{
  [NakedObjectsIgnore]
  public virtual int Id { get; set; }

  public virtual string FirstName { get; set; }
  public virtual string LastName { get; set; }
  public virtual int Age { get; set; }

  [Title]
  public string FullName { get { return FirstName + " " + LastName; } }
}

目前為止都很順利。

說話者的存放庫

存放庫物件,對於不熟悉該模式,是基本上表示存取資料庫,並提供簡單的方法呼叫的標準資料庫要求的物件。在 NakedObjects 系統中,儲存機制物件是一種服務,也就是特別為物件,而不是網域物件辨識 NakedObjects 物件,但可以代表系統提供的 UI 項目和行為。在此情況下,存放庫會提供一些功能表項目開始移出資料庫,(舉例來說) 依據姓氏排序的主講人。

實際上,NakedObject 服務只是另一個類別,但它具有演講者備忘類別不: IDomainObjectContainer 物件,這是一個可依序存取其餘 NakedObjects framework 所提供的物件參考在系統中。NakedObjects 文件中有可用的系統服務的清單,但特別是我想要在兩個項目: NewTransientInstance 方法,將會建構一個新的說話者物件,然後將其對 NakedObjects 的其餘部分基礎結構為使用。 的和執行個體方法,這會從資料庫傳回一組完整的說話者的物件。因此,最少 SpeakerRepository 看起來像所示**[圖 1**。

[圖 1 SpeakerRepository 類別

public class SpeakerRepository
{
  public IDomainObjectContainer Container { set; protected get; }

  public Speaker CreateNewSpeaker()
  {
    // 'Transient' means 'unsaved' - returned to the user
    // for fields to be filled in and the object saved.
    return Container.NewTransientInstance<Speaker>();
  }

  public IQueryable<Speaker> AllSpeakers()
  {
    return Container.Instances<Speaker>();
  }
}

請注意,NewTransientInstance 和執行個體方法是泛型的函式,採用的物件跟使用的型別參數的函式呼叫的類型。(這是
因為 DomainObjectContainer 即可將用於各種不同的網域物件型別,不只是說話者。)

存放庫只會建立新的說話者,並取得一份所有人都不是特別有用,不過;您通常會想要擷取特定的已篩選掉,或以特定順序排列的物件。以下是其中運用 LINQ 與 EntityFramework NakedObjects framework 內可感受到其目前狀態。由於 AllSpeakers 方法會傳回 IQueryable,我還可以使用 LINQ 方法,來篩選及 (或) 排序傳回的物件,因此,如果我想要依姓氏找到演講者,可以只將該方法加入儲存機制類別,來篩選結果,視使用 LINQ:

public class SpeakerRepository
{
  // ... as before

  public IQueryable<Speaker> FindSpeakerByLastName(string name)
  {
    return AllSpeakers().
      Where(c => c.LastName.ToUpper().Contains(name.ToUpper()));
  }
}

任何 LINQ 可以執行的工作,您可以表示為存放庫上的方法。

說話者內容

兩個簿記詳細我要負責:我要設定將用於 NakedObject 持續性引擎,Entity Framework DbContext,我需要將 SpeakerRepository 連結到 UI,這樣我就能建立新的演講來賓,功能表項目尋找現有的演講來賓,以此類推。

第一個 Template.DataBase 專案中找到,ExampleDbContext.cs 檔案中 (您應該可以自由變更您的最重要的如果其名稱),ExampleDbContext 類別中。該類別的公用屬性,以參數化以呼叫 「 喇叭 」 的說話者類型的 DbSet 需求就像這樣:

namespace Template.DataBase
{
  public class ExampleDbContext : DbContext
  {
    public ExampleDbContext(string dbName,
      IDatabaseInitializer<ExampleDbContext> initializer) : base(dbName)
    {
      Database.SetInitializer(initializer);
    }

    public DbSet<Speaker> Speakers { get; set; }
  }
}

當多個最上層網域物件型別加入至系統時,我需要新增更多屬性這裡傳回 DbSet,但現在,這是我只需要。

如果您想要一些喇叭] 開始植入的資料庫,您需要破解的開放 Template.SeedData 專案,然後尋找 ExampleDbInitializer.cs 檔案,並新增某些演講者備忘物件時,寫入種子方法 (這已在該檔案中定義)透過說話者 DbSet,如中所示 (重構物件,我只是先前段落中) 的 ExampleDbContext [圖 2

[圖 2 將說話者的物件加入至 DbContex

public class ExampleDbInitializer : 
  DropCreateDatabaseIfModelChanges<ExampleDbContext>
{
  private ExampleDbContext Context;
  protected override void Seed(ExampleDbContext context)
    {
    this.Context = context;

    Context.Speakers.Add(new Speaker() {
      FirstName = "Ted", LastName = "Neward", Age = 47
    });
  }
}

請注意,這是直接的 Entity Framework 程式碼,因此任何進一步的討論有關如何變更資料庫的卸除/建立原則會在 Entity Framework 文件集內。

我要設定程式碼的最後一個位置是在 Template.Server 專案,在 NakedObjectsRunSettings.cs 檔案中;此程式碼會註冊 「 勾點 」 或 「 提示 」 來描述 NakedObjectsFramework 必須知道 NakedObjects 系統的集合。比方說,如果您決定 「 Template.Model"是可怕的命名空間,此會議應用程式之模型物件,然後可以自由變更它,只要此 NakedObjectsRunSettings 的 ModelNamespaces 也會反映已變更的名稱。

相對於 SpeakerRepository,我必須讓 NakedObjects 了解它,藉由新增到 「 服務 」 類型的陣列。如果我想 SpeakerRepository 方法,可透過功能表選項,我還需要告訴 NakedObjects 檢查 SpeakerRepository 動作作為功能表項目,所以我需要將它包含一維陣列的 MainMenus 方法所傳回的功能表項目如中所示**[圖 3**。

[圖 3 NakedObjects 回合設定

public class NakedObjectsRunSettings
{
  // ...

  private static Type[] Services
  {
    get
    {
      return new Type[] {
        typeof(SpeakerRepository)
      };
    }
  }

  // ...

  public static IMenu[] MainMenus(IMenuFactory factory)
  {
    return new IMenu[] {
      factory.NewMenu<SpeakerRepository>(true, "Menu")
    };
  }
}
}

一旦這些變更準備就緒之後,我可以啟動專案,啟動用戶端並建立幾個喇叭。請注意顯示 FullName 屬性、 FirstName 和 LastName,從建置,但識別碼不會出現。此外,由於 SpeakerRepository FindSpeakersByLastName 方法,可以依姓氏搜尋主講人,如果傳回多個,則用戶端就會自動得知如何呈現這些設定的清單,可以選取個別的工作。

總結

請注意,這篇文章中的任何時候未我任何項目範本。用戶端專案,這就是重點 !UI 是從具有自訂屬性 (其中您會看到更新的資料行中的多個) 所提供的補充資訊建構出來的網域物件和服務。同樣地,持續性,從結構和架構探索的中繼資料上建置,從您的型別。

您必須查看,請從現在開始,是收到的 NOF 處理更複雜的網域案例的方式 — 像是上有一份主題演講者它們可以唸出這和集合,它們可以提供的簡報,以及如何為其呈現 UI。在下一篇文章中,我將探討其中部分主題。在此同時,不過...祝各位編碼程式 !


Ted Neward是西雅圖的 polytechnology 顧問、 演說家和導師。他已撰寫了無數的文章,撰寫與合著過十幾個書籍,並在世界各地發表演說。與他連絡ted@tedneward.com或閱讀他的部落格blogs.tedneward.com


MSDN Magazine 論壇中的這篇文章的討論