应用程序

Application是CatLib程序的核心,也是所谓的程序入口。应用程序通过引导来加载服务提供者和其他一些必须的资源。应用程序在一般情况下只允许启动一个,且只能在主线程中启动。

在任何位置,您可以通过App全局变量访问应用程序。

启动流程

Application.Bootstrap -> Application.Register -> Application.Init

  • Application.Bootstrap 一般用于引导注册服务提供者,初始配置或者一些其他资源。
  • Application.Register 用于注册服务提供者到框架。
  • Application.Init 激活所有服务提供者的Init函数,并完成框架初始化。
建议的调用结构:
1
2
3
4
- Application.Bootstrap
- - Application.Register
- - #... more
- Application.Init

我们一般建议在Bootstrap中调用Register注册函数。

生命周期

life-cycle

创建框架实例

  • 通过Application.New来创建框架实例

    1
    Application.New();
  • 通过手动实例化创建框架实例

    1
    var application = new Application();

引导程序

引导程序必须继承自CatLib.IBootstrap接口。引导程序可以被用来引导注册服务提供者,或者其他需要在框架启动之前加载的程序。

1
2
3
4
5
6
7
public class BootstrapDebug : IBootstrap
{
public void Bootstrap()
{
Console.WriteLine("hello debug");
}
}
1
application.Bootstrap(new BootstrapDebug()); // 输出: hello debug

注意这里使用的是application这个变量,而不是App全局变量。

注册服务提供者

通过App.Register函数可以将服务提供者注册到应用程序中。服务提供者必须实现CatLib.IServiceProvider接口。

1
2
3
4
5
6
7
8
public class ProviderDebug : IServiceProvider
{
public void Init(){ }
public void Register()
{
Console.WriteLine("hello register");
}
}
1
2
application.Register(new ProviderDebug()); // 输出:hello register
// App.Register(new ProviderNetwork()); // 还可以使用App全局变量来进行注册。

初始化框架

调用application.Init函数将会初始化框架,并且激活所有已经注册到应用程序中的服务提供者的Init函数。

1
2
3
4
5
6
7
8
9
10
11
public class ProviderFileSystem : IServiceProvider
{
public void Init()
{
Console.WriteLine("hello init [ProviderFileSystem]");
}
public void Register()
{
Console.WriteLine("hello register [ProviderFileSystem]");
}
}
1
2
3
4
5
6
7
8
9
10
11
public class ProviderDebug : IServiceProvider
{
public void Init()
{
Console.WriteLine("hello init [ProviderDebug]");
}
public void Register()
{
Console.WriteLine("hello register [ProviderDebug]");
}
}
1
2
3
4
5
application.Register(new ProviderDebug());      // 输出:hello register [ProviderDebug]
application.Register(new ProviderFileSystem()); // 输出:hello register [ProviderFileSystem]

application.Init(); // 输出:hello init [ProviderDebug]
// 输出:hello init [ProviderFileSystem]

终止应用程序

当程序退出时,您需要调用App.Terminate方法来终止框架运行,这样框架中注册的服务都会被有序释放,释放顺序请参考生命周期图

1
App.Terminate();

全局事件系统

应用程序已经内嵌的事件系统,详细文档请参考事件系统,下面是可以被使用的事件函数:

1
2
3
4
5
6
App.HasListeners();
App.Trigger();
App.TriggerHalt();
App.On();
App.Listen();
App.Off();

框架事件

下面的事件已经内嵌到应用程序内,满足条件时会自动触发,事件名都被放在ApplicationEvents中。

1
2
3
App.On(ApplicationEvents.OnStartCompleted, ()=>{
// todo:
});
事件名 描述
OnBootstrap 在框架引导开始之前。
Bootstrapping 在框架引导进行中,每次引导被激活前都会调用,会提供参数IBootstrap,参数值为当前准备被激活的引导。返回一个不为null的值(一般为false)可以终止引导激活。
OnBootstraped 在框架引导完成之后。
OnRegisterProvider 在注册服务提供者时,每次注册服务提供者都会触发,会提供参数IServiceProvider,参数值为当前准备被注册的服务提供者。返回一个不为null的值(一般为false)可以终止服务提供者注册。
OnInit 在框架初始化之前。
OnIniting 在框架初始化进行中,每个服务提供者初始化之前都会触发,会提供参数IServiceProvider,参数值为当前准备被初始化的服务提供者。
OnProviderInit 在服务提供者初始化启动之前。会提供参数IServiceProvider,参数值为当前准备被初始化的服务提供者。
OnProviderInited 在服务提供者初始化启动之后。会提供参数IServiceProvider,参数值为当前准备被初始化的服务提供者。
OnInited 在框架初始化完成后。
OnStartCompleted 在框架进入运行状态后触发。开发者可以接受这个事件来进入自己的业务代码。
OnTerminate 在框架终止之前。
OnTerminated 在框架终止之后。

注意,OnTerminated事件只允许使用Action的形式监听。因为这时框架已经被完全释放,不再具备依赖注入的功能,否则将会导致一个异常。

1
App.On(ApplicationEvents.OnTerminated, OnTerminated);
1
private void OnTerminated();

当框架被新创建时

通过App.OnNewApplication您可以捕获Application的创建事件,这对于一些在Application被创建前就已经执行的程序或者需要监听应用程序变化的程序非常有用。

1
2
3
App.OnNewApplication += (app)=>{
// todo:
};

App.OnNewApplicationnew Application之前可以被使用

设定框架的调试等级

您可以通过App.DebugLevel来设定框架的调试等级,所有的组件都可以识别这个调试等级来做出对应的处理。

1
App.DebugLevel = DebugLevels.Production; // Production,Staging,Development

调试等级的默认值为:DebugLevels.Production

获取运行期间的唯一Id

在应用程序生命周期内,您可以使用App.GetRuntimeId函数来获取运行时的唯一Id,该函数多线程安全。

1
int uuid = App.GetRuntimeId();

判断服务是否被注册

通过App.IsRegisted可以判断服务提供者是否已经被注册到应用程序中了。

1
App.IsRegisted(new ProviderFileSystem()); // return false

是否在主线程中执行

您可以通过App.IsMainThread来判断是否处于主线程中,该函数多线程安全。

1
App.IsMainThread;

创建应用程序的线程会被认为是主线程

获取当前框架的版本

通过App.Version可以获取当前框架的版本,框架版本遵循语义化版本

1
string version = App.Version;

比较框架版本

某些场景需要比较当前运行时的框架版本,这时您可以通过App.Compare函数来比较版本。

1
2
3
// App.Version 2.0.0
App.Compare("1.2.3"); // return 1
App.Compare("2.2.3"); // return -1

完整的例子

  • 设计服务接口FileSystem/IFileSystem.cs:

    1
    2
    3
    4
    public interface IFileSystem
    {
    void HelloWorld();
    }
  • 开发服务实现FileSystem/FileSystem.cs:

    1
    2
    3
    4
    5
    6
    7
    public class FileSystem : IFileSystem
    {
    public void HelloWorld()
    {
    Console.WriteLine("hello world");
    }
    }
  • 创建服务提供者FileSystem/ProviderFileSystem.cs:

    1
    2
    3
    4
    5
    6
    7
    8
    public class ProviderFileSystem : IServiceProvider
    {
    public void Init(){ }
    public void Register()
    {
    App.Singleton<IFileSystem, FileSystem>();
    }
    }
  • 创建服务提供者引导列表Config/Providers.cs:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    public static class Providers
    {
    /// <summary>
    /// 服务提供者
    /// </summary>
    public static IServiceProvider[] ServiceProviders
    {
    get
    {
    return new IServiceProvider[]{
    new FileSystemProvider()
    };
    }
    }
    }
  • 创建引导程序Bootstrap/BootstrapProviders.cs:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    public class BootstrapProviders : IBootstrap
    {
    public void Bootstrap()
    {
    foreach (var provider in Providers.ServiceProviders)
    {
    if (!App.IsRegisted(provider))
    {
    App.Register(provider);
    }
    }
    }
    }
  • 创建框架入口文件,Main.cs:

    1
    2
    3
    var application = Application.New();
    application.Bootstrap(new ProvidersBootstrap());
    application.Init();
  • 使用服务Main.cs:

    1
    App.Make<IFileSystem>().HelloWorld(); // 输出:hello world

与"{{ searched.keyword }}"相关的内容{{searched.results.length}}条

无搜索结果可以匹配"{{ searched.keyword }}"

{{ record.hash }}

  • {{ record.page }} - {{ record.page_title }} score:{{ record.score }}