Reface.AppStarter 框架初探

我自横刀向天笑,去留肝胆两昆仑。这篇文章主要讲述Reface.AppStarter 框架初探相关的知识,希望能为你提供帮助。
Reface.AppStarter  是一种基于 .NetFramework  的应用程序启动模式,使用该启动模式,你可以轻松的得到以下功能 : 

  • IOC / DI  自动注册与装配
  • 简化配置
  • 垂直模块化你的代码
  • 事件总线功能
  • 命令总线  功能
  • 定义模块的依赖项
  • 对模块内的类型进行扫描并分类管理
1  安装【Reface.AppStarter 框架初探】通过 Nuget  你可以很轻松的安装并使用它。
2  设计理念 2.1  模块化模块是系统组成的最小颗粒,
每一个模块都应当向系统提供一个单一的功能或业务,比如 Excel导出,缓存,用户管理等等。
原则上,我们建议你的每一个 Library  都是一个模块。
在 Reface.AppStarter  中,每一个模块都应当申明一个 AppModule  作为提供给外部依赖的类型。
public class MyAppModule : AppModule { }

 
 
2.2  模块依赖
Reface.AppStarter 框架初探

文章图片

模块与模块之间存在依赖关系,
如上图,启动模块依赖模块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   
 
相关链接
  • Github Of Reface.AppStarter
  • Demo Of Reface.AppStarter
 
本文为作者原创,转载请注明出处 :  https://www.cnblogs.com/ShimizuShiori/p/12610668.html

    推荐阅读