Reface.AppStarter 基本示例

使用 IOC 容器 往往分为两个阶段

配置阶段
使用阶段
在 配置阶段 我们可能会选择 配置文件 、对所有依赖的程序集反射 、 对指定程序反射 、 硬编码 等方式对组件进行 注册 。

对所有依赖的程序集反射 ,怎么看都是一种即笨重又有些呆板的方法。

然而另外几个方案在多模块化的项目里中 ,
也无法很好的工作,
它们各自需要在系统启动时,明确一些信息 :

一共需要读取哪些配置文件,这些文件在各个子模块的哪儿
一共需要对哪些程序集进行反射
那些负责硬编码注册的类型都在哪儿
如果上述的信息没有被收集完整,那么程序会因为没有注册全部组件而无法正确运行。

事实上

在大多数情况下,开发者在编写一个 接口 和一个 实现 时,就已经确定 注册关系 。
只有那些可能面临 策略模式 ,或者存在多客户端适配的情况下,这种 注册关系 无法确定。

所以通过 Attribute 加 扫描,是一种很好的 自动化注册 手段。

假定我们需要实现下面的接口

// Services/IUserService.cs
public interface IUserService
{
void CreateUser(User user);
}
实现过程大致如下

// Services/DefaultUserService.cs
public class DefaultUserService : IUserService
{
private readonly IRepository userRepo ;

public DefaultUserService(IRepository<User> userRepo)
{
    this.userRepo = userRepo;
}

public void CreateUser(User user)
{
    this.userRepo.Insert(user);
}

}
使用 Reface.AppStarter ,你不再需要编写额外的代码将这个 DefaultUserService 注册到 IUserService 上。
你只需要为 DefaultUserService 添加一个 ComponentAttribute 。

// Services/DefaultUserService.cs
[Component]
public class DefaultUserService : IUserService
{
// …
}
这个 特征 就是通知 Reface.AppStarter 将该类型注册到 IOC 容器 中,并注册到它所有实现的接口类型上。

在由 Reface.AppStarter 构建的系统中,程序不是单纯的由 程序集 组成,而是由 应用模块 组成。
应用模块 不仅包含了 程序集 原有的功能,还能够体系与其它 应用模块 的依赖关系。

现在我们为刚才 DefaultUserService 所在的 程序集 编写一个 应用模块 的类型。

// UserAppModule.cs
[ComponentScanAppModule]
public class UserAppModule : AppModule
{

}
这就是一个 用户应用模块 ( 所有的 应用模块 应当从 AppModule 继承 ),
它依赖了一个 ComponentScanAppModule 的 应用模块 。

ComponentScanAppModule 会将 目标应用模块 中标记了 ComponentAttribute 的类型注册到 IOC 容器中。

运行程序

public static void Main(String[] args)
{
var app = AppSetup.Start();
IUserService service = app.CreateComponent();
// you can use service now;
}
除了直接启动 UserAppModule ,
也可以将 UserAppModule 加到别的 应用模块 上,这个 自动注册 同样有效。
基于这样的方式, UserAppModule 完全可以开箱即用。

也可以说,任何一个 应用模块 都可以开箱即用。

自动映射配置文件
配置文件总是存在的, .NetFramework 提供了一整套 Configuration 方案。
但是这个方案略显笨重,并且在配置过程完全没有提示,必须依赖大量的文档说明。

很明显 JSON 比 XML 轻巧很多,
并且还有 JsonSchema 可以向 IDE 提供提示功能。

所以 Reface.AppStarter 选择了 JSON 作为配置文件的格式 ,
Reface.AppStarter 会读取一个包含了所有配置的 JSON 文件,
将配置中的值映射的 对应 的类型和属性中,
并将这些 类型 以单例的模式注册到 IOC 容器中。

以 UserAppModule 为例,我们为其开发一个 配置类,
配置类 就是 Reface.AppStarter 在解析 JSON 文件后反序列化的目标类型。

为一个类型添加 ConfigAttribute 就会通知 Reface.AppStarter : “嘿,这有一个配置类”。

下面的例子表示,我们可以通过配置文件指定 根用户的信息

// Configs/UserConfig
[Config(“User”)]
public class UserConfig
{
public string RootUserName { get; set; } = “admin”;
public string RootUserPassword { get; set; } = “888888”;
}
ConfigAttribute 的构造函数中指定的 User 表示从配置文件的 User 节点中读取配置,配置文件大至如下:

{
“User” : {
“RootUserName” : “ROOT”,
“RootUserPassword” : “123456789”
}
}
如果没有配置文件,或者配置文件中没有编写 User 则会使用属性中指定的默认值将配置类实例注册到 IOC 容器 中。

通过构造函数注入配置类就可以使用它们。

// Services/DefaultUserService.cs
public class DefaultUserService : IUserService
{
private readonly IRepository userRepo;
private readonly UserConfig userConfig;

public DefaultUserService(IRepository<User> userRepo, UserConfig userConfig)
{
    this.userRepo = userRepo;
    this.userConfig = userConfig;
}

public void CreateUser(User user)
{
    if(user.Name == userConfig.RootUserName)
        throw new SomeException("无效的用户名,不能创建该用户");
    this.userRepo.Insert(user);
}

}
与 ComponentScanAppModule 一样,需要为 UserAppModule 添加一样依赖来开启 自动映射配置文件 的功能。

// UserAppModule.cs
[ComponentScanAppModule] // 开启自动扫描注册组件
[AutoConfigAppModule] // 开启自动映射配置文件
public class UserAppModule : AppModule
{

}
现在启动 UserAppModule
或者将 UserAppModule 添加到其它 应用模块 的依赖项中,
这些功能都会被启用。

AppSetup.Start() 默认读取 app.json 文件,
若配置文件不存在,则直接使用 配置类 的默认属性值。

关于配置智能提示
通过 AppSetup.Start() 运行程序后,会在输出目录下产生一个 app.schema.json 文件。

为你的 app.json 添加 $schema 属性,值指向 app.schema.json 文件,就可以得到智能提示功能:

TS1

TS2

你也可以通过上图显示的属性关闭生成 app.schema.json 的功能。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值