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