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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM