天天看點

ABP領域層知識回顧之---實體

标題:重溫ABP領域層

1. 前言

最近一段時間一直在看

《ABP的開發指南》(基于DDD的經典分層架構思想)

。因為之前一段時間剛看完

《領域驅動設計:軟體核心複雜性應對之道》

,概念比較多,看着有點空。于是拿起了這本書。應該說是不是書, 隻是一個PDF版的開發指南。于是乎,就開始了。好了,廢話不多說,首先是ABP領域層的結構介紹,如下圖所示:

ABP領域層知識回顧之---實體

從圖中可以看到,

ABP

的領域層分為

實體

倉儲

工作單元

資料過濾器

,以及

領域事件

五個部分。這五個部分的功能作用,如果看過了解過

DDD

的應該不會陌生。接下來我将一一介紹這五個部分的詳情,每個部分具體作用,以及實作。順便給自己溫習溫習。附加一點自己粗淺的了解,如有不正确的地方,歡迎指正,交流。

2. 各個子產品

2.1 ABP領域層-實體

很多對象不是通過它們的屬性定義的,而是通過一連串的連續性事件和辨別定義的。———摘錄自《領域驅動設計》第5章 5.2 模式:Entity(又稱為Reference Object)

在ABP的實體中,實體繼承至Entity。可以細分為下面三個部分。

1、實體類

,2、

接口約定

以及

3、IEntity接口

2.1.1 首先是第一個

實體類

檢視源碼發現如下:

namespace Abp.Domain.Entities
{
  /// <summary>
  /// A shortcut of <see cref="T:Abp.Domain.Entities.Entity`1" /> for most used primary key type (<see cref="T:System.Int32" />).
  /// </summary>
  [Serializable]
  public abstract class Entity : Entity<int>, IEntity, IEntity<int>
  {
  }
}
           

然後最後我們看下

IEntity<TPrimary>

之後就真相大白了。

namespace Abp.Domain.Entities
{
  /// <summary>
  /// Defines interface for base entity type. All entities in the system must implement this interface.
  /// </summary>
  /// <typeparam name="TPrimaryKey">Type of the primary key of the entity</typeparam>
  public interface IEntity<TPrimaryKey>
  {
    /// <summary>Unique identifier for this entity.</summary>
    TPrimaryKey Id { get; set; }

    /// <summary>
    /// Checks if this entity is transient (not persisted to database and it has not an <see cref="P:Abp.Domain.Entities.IEntity`1.Id" />).
    /// </summary>
    /// <returns>True, if this entity is transient</returns>
    bool IsTransient();
  }
}
           

相當于每個繼承于

Entity

的都有一個

Id

屬性。

Id

屬性是該實體的主鍵,是以,Id是所有繼承自

Entity

類的實體的主鍵。當然,從源碼中,我們可以發現。很顯然這個Id資料的類型可以被更改。因為是

<TPrimary>

類型的,是以,你如果想要改成

long

,或者

Guid

等等啦。隻需要向如下這樣定義:

public class ClassA : Entity<Guid>
  {
    //...
  }
           

2.1.2 第二個是

接口約定

剛開始聽到這個名字時,我覺得有點難以了解。但是在文章中,聽了一下解釋。可以幫助了解,如下:

很多實體會有像

CreationTime

用來訓示該實體是什麼時候被建立的。ABP提供了一些有用的接口來實作類似的功能,隻需要實作這些接口的實體,就能夠實作指定的功能。

接口預定

中,又分為如下三個部分:

ABP領域層知識回顧之---實體

首先是

審計(Auditing)

,這個接口主要的是

CreationTime

這個屬性。隻要實體類實作

IHasCreationTime

接口,當該實體被插入到資料庫時,ABP會自動設定該屬性的值為目前時間。

public interface IHasCreationTime{
  DateTime CreationTime{get;set;}
}
           

審計中還有一個接口

ICreationAudited

,這個接口是擴充至

IHasCreationTime

,并且該接口還有一個屬性

CreatorUserId

,可以用來記錄目前使用者的

Id

,

public interface ICreationAudited : IHasCreationTime{
  long ? CreatorUserId{get;set;}
}
           

CreationAuditedEntity

類已實作了

ICreationAudited

我們可以直接繼承來使用。

審計中還有一個實作類似修改功能的接口

IModificationAudited

public interface IModificationAudited{
  DateTime? LastModificationTime{get;set;}
  ling? LastModifierUserId{get;set;}
}
           

當然,如果你想都實作這些審計屬性,ABP也提供給你了。

IAudited

接口。

public interface IAudited : ICreationAudited, IModificationAudited{
  
}
           

可能你有點亂了,我來給你理理。大概就是如下這樣的。

ABP領域層知識回顧之---實體

這樣簡單吧。

接下來是

軟删除

, 表示标記了一個實體已經被删除了。而不是從資料庫中删除記錄。對應的接口為

ISoftDelete

public interface ISoftDelete{
  bool IsDeleted{get;set;}
}
           
來源于文中:當一個實作了軟删除的實體正在被删除,ABP會察覺到這個動作,并且阻止其删除,設定

IsDeleted

屬性值為

true

并且更新資料庫中的實體。

和審計中的

ICreationAudited

類似, 記錄誰删除了這個實體。

IDeletionAudited

public interface IDeletionAudited: ISoftDelete{
  long? DeleterUserId{get;set;}
  DateTime? DeletionTime{get;set;}
}
           

當然,如果你想要實作所有(包括,建立,修改,和删除。)那就實作這個終極接口,

IFullAudited

public interface IFullAudited: IAudited , IDeletionAudited{
  //...
}
           

實體類

FullAuditedEntity

實作了

IFullAudited

接口。可以直接繼承使用。

那麼審計的終極總結圖就如下:

ABP領域層知識回顧之---實體

很清楚了吧!

PS:詳情可以檢視源代碼

Abp.Domain.Entities.Auditing

2.1.3最後一個是IEntity接口

在2.1.1 中已經介紹了一下,這裡就不贅述。

Entity

IEntity

接口(和

Entity<TPrimaryKey>

IEntity<TPrimaryKey>

接口)。

2.2 ABP領域層-倉儲

2.3 ABP領域層-工作單元

2.4 ABP領域層-資料過濾器

2.5 ABP領域層-領域事件

3. 結語

本想一次性把這些都總結整理一下,突然發現内容有點多。還是一步一步來,慢慢整理把。這次先整理實體。好尴尬。

4.附錄

參考:Github_ABPChina

參考連結:

  • https://www.aspnetboilerplate.com/Pages/Documents
  • http://www.cnblogs.com/farb/p/ABPTheory.html
  • http://www.cnblogs.com/mienreal/p/4528470.html

繼續閱讀