Reface.AppStarter 框架初探

Reface.AppStarter 是一種基於 .NetFramework 的應用程式啟動模式,使用該啟動模式,你可以輕鬆的得到以下功能 : 

  • IOC / DI 自動註冊與裝配
  • 簡化配置
  • 垂直模組化你的程式碼
  • 事件匯流排功能
  • 命令匯流排 功能
  • 定義模組的依賴項
  • 對模組內的類型進行掃描並分類管理

1 安裝

通過 Nuget 你可以很輕鬆的安裝並使用它。

2 設計理念

2.1 模組化

模組是系統組成的最小顆粒,

每一個模組都應當向系統提供一個單一的功能或業務,比如 Excel導出,快取,用戶管理等等。

原則上,我們建議你的每一個 Library 都是一個模組。

在 Reface.AppStarter 中,每一個模組都應當申明一個 AppModule 作為提供給外部依賴的類型。

public class MyAppModule : AppModule  {  }

 

 

2.2 模組依賴

模組與模組之間存在依賴關係,

如上圖,啟動模組依賴模組A,啟動模組就可以得到模組A中的功能,模組A也可以增加啟動模組的功能。

整個系統只能有一個啟動模組,由它作為 ROOT 向下展開。

例如

一個用戶模組可能依賴 Excel導入導出、日誌、快取模組,一個快取模組可能依賴 AOP、日誌模組等等。

 

在 Reface.AppStarter 中,當 A 模組依賴 B 模組時,我們把 B 稱作為的 DependentModule,將 A 稱作 B 的 TargetModule,

我們可以利用 Attribute 輕鬆的實現模組依賴的定義,下面的例子就是一個依賴了 用戶、訂單 的模組。

[UserAppModule]  [OrderAppModule]  public class MyAppModule  {  }

 

2.3 類型掃描與分類

當我們使用模組以樹狀的形式構建了系統後,

Reface.AppStarter 就可以對這個樹狀圖中的模組進行自頂向下的掃描,

掃描每一個模組中的類型,並將一切標有 ScannableAttribute(或繼承) 特徵的類型收集,允許被依賴的模組訪問這些被收集的類型,並對這些類型進行增強的操作。

[Scannable]  public class MyClass  {  }

形如上面的類型,就可以被依賴的 AppModule 獲取,並對其做出額外的增強,比如 IOC / DI ,AOP的代理類生成等等。

Reface.AppStarter 所提供的 IOC / DI 的自動註冊和自動裝置就是基於此功能實現的。

 

2.4 應用程式構建

Reface.AppStarter 分為配置與啟動兩個階段。

配置階段你需要聲明一個 AppSetup ,並讓它啟動你的取頂層模組即可。

AppSetup setup = new AppSetup();  App app = setup.Start(new MyAppModule());

 

App 實例承載了 Reface.AppStarter 中的所有容器,有關容器會在以後的文章中做詳解。

最簡單的用法,是從 app 中得到 IComponentContainer 並用它創建 IOC / DI 組件。

var container = app.GetAppContainer<IComponentContainer>();  ITestService service = container.CreateComponent<ITestService>();  service.Do();

 

3 使用方法

3.1 為你的所有 Library 創建 AppModule

  • 你可以通過 AppModule 實現以下功能
  • 創建一個可以由外部依賴的 AppModule
  • 定義自己所依賴的其它 AppModule
  • 增強依賴自己的 TargetModule 的功能
  • 註冊額外的組件至 IOC / DI 容器
  • 替換  IOC / DI 容器中已註冊的組件

下面的示例中展示了上述所的大部分常用功能

    [AutoConfigAppModule]      [ComponentScanAppModule]      [UserAppModule]      public class TestAppModule : AppModule      {          [ComponentCreator]          public IUserService GetUserService(ILangProvider provider)          {              return new DefaultUserService(provider);          }            [ReplaceCreator]          public ITestService GetTestService()          {              return new SecondTestService();          }      }

 

程式碼解釋

  • 所有  AppModule 都要實現 IAppModule 的介面,IAppModule 的一個簡便的實現就是 AppModule,它允許開發者直接通過 Attribute 來定義依賴項
  • 通過 Attribute,TestAppModule 依賴了三個其它模組
    • AppConfigAppModule,是一個自動配置模組,這是 Reface.AppStarter 自帶的
    • ComponentScanAppModule,是一個 IOC / DI 組件掃描的模組,這也是 Reface.AppStarter 自帶的
    • UserAppModule,這是一個關於用戶的業務模組,這是一個示例模組
  • 標記了 ComponentCreator 的方法會將 DefaultUserService 註冊到 IUserService 上,並使用 IOC / DI 中已註冊的 ILangProvider 作為構造函數
  • 標記了 ReplaceCreator 的方法會將 IOC / DI 中已有的 ITestService 替換,並重新使用 SecondTestService 進行註冊

 

3.2 為你的類型加上 Component 讓他們自動註冊到 IOC / DI 容器中

市面上有很多方便的 IOC / DI 工具庫,但他們總是依賴手動註冊。

即使我們通過反射程式集,也很難做到對系統中所有有需要的程式集做反射 ( 我們肯定不會對 System 這種庫進行反射註冊的 )。

但是通過 AppModule 以及對 ComponentScanAppModule 的依賴,我們可以很清楚的知道哪些程式集是需要進行反射註冊的。

AppSetup 會執行這些操作,

而開發者們只需要為你們的類型加上 Component 特徵即可

[Component]  public class DefaultUserService : IUserService  {  }

 

 註冊方法有兩種,通過 Component 的構造函數區分。

  • 註冊為介面。在組件創建時,你必須使用介面類型進行創建
  • 註冊為類型本身。在組件創建時,你必須使用類型進行創建

你也可以同時註冊為介面和其本身。

 

3.3 編寫你的配置類

.Net 自帶的 config 配置很好用,但是太臃腫,要寫大量的映射類。

Reface.AppStarter 簡化這些複雜的過程,它只要你寫一個配置類,然後再通過一個 json 反序列化就可以了。

3.3.1 編寫一個配置類

任何數據結構你都可以直接當作配置類,不需要繼承任何類,只要為其加上 Config 特徵即可

[Config("DbConnection")]
public
class DbConnectionConfig { public string ConnectionString { get; set; } }

 

3.3.2 編寫配製文件

默認的配置文件路徑是啟動目錄下的 app.json,

所有標有 Config 特徵的類都會從這裡讀取配置

Config 中構造函數所要提供的字元串,就是配置文件中的 屬性 名稱

{      "DbConnection" : {          "ConnectionString" : "Your Connection String Here"      }  }

 

3.3.3 在該模組中添加對自動配置的依賴

為你的 AppModule 添加特徵 AutoConfigAppModule 即可。

[AutoConfigAppModule]  public class MyAppModule  {  }

 

 3.3.4 自定義配置文件路徑 

AppSetup 的構造函數中有一個參數,該參數就是配置文件的路徑,你可以在 new AppSetup 的時候,指定一個新的配置文件路徑。

 3.3.5 使用配置

標有了 [Config] 的類型會以其自身的類型註冊到 IOC / DI 容器中,

因此,你可以通過 IOC / DI 的容器的自動裝配功能得到它的實例。

[Component]  public class DefaultTestService  {      private readonly DbConnectionConfig config;        public DefaultTestService(DbConnectionConfig config)      {          this.cofnig = config;      }  }

 

4 系統中的 Attribute

4.1 ScannableAttribute

標記了該特徵的類型將會在掃描時被記錄,

就如它的名字一樣,它只表達一種允許被掃描的用意,沒有其它任何含義,

當你需要對某些類型進行分類時,請創建更有意義的特徵,並繼承此特徵。

4.2 ComponenAttribute

標記了該特徵的類型會被註冊到 IOC / DI 容器中

4.3 ConfigAttribute

標記了該特徵的類會從配置文件中進行反序列化,並以類型本身註冊到 IOC / DI 容器中

4.4 ListenerAttribute

標記了該特徵的類會成為一個事件匯流排的監聽器

4.5 CommandHandlerAttribute

標記了該特徵的類會成為一個命令匯流排的命令處理器

4.6 ComponentCreatorAttribute

在 AppModule 中,被標記了該特徵的方法會將以方法的構建過程註冊到 IOC / DI 容器中

4.7 ReplacCreatorAttribute

在 AppModule 中,被標記了該特徵的方法會移除當前 IOC / DI 容器中的組件並重新註冊,

在一次構建中,同一個組件只可以被替換一次

 

5 系統中的 AppModule

5.1 ComponenScanAppModule

該模組會將目標模組中所有標記了 ComponentAttribute 的組件註冊到 IOC / DI 容器中

5.2 AutoConfigAppModule

該模組會將配置文件中的類型反序列化到目標模組中標記了 ConfigAttribute 的類型上,並註冊到 IOC / DI 容器中

 


後面的文章 

  • 如何使用事件匯流排
  • 如何使用命令匯流排
  • 如何編寫功能性 AppModule
  • 什麼是 AppContainer 

 


 

相關鏈接

 

本文為作者原創,轉載請註明出處 : https://www.cnblogs.com/ShimizuShiori/p/12610668.html