Skip to content

通用主机

通用主机主要用来处理后台任务,消息队列之类的场景。通用主机整合了基础设施,开箱即用。

快速启动

cangjie
import spire_extensions_hosting.*

main(args: Array<String>) {

    let builder = Host.createBuilder(args)

    let host = builder.build()

    host.run()

    return 0
}

总结

运行上面的代码,主线程进入阻塞,什么也不会干。但是通用主机为我们整合了基础设施,使得我们可以快速进行应用开发。

后台服务

cangjie
import spire_extensions_options.*
import spire_extensions_hosting.*
import spire_extensions_logging.*
import spire_extensions_injection.*

// 1. 创建选项
public class WorkerOptions {
    public var delay = Duration.second * 1
}

// 2. 创建任务
public class WorkerServer <: BackgroundService {
    private let _logger: ILogger

    public WorkerServer(
        let _options: IOptions<WorkerOptions>,
        let _loggerFactory: ILoggerFactory) {
        _logger = _loggerFactory.createLogger<WorkerServer>()
    }

    public func run() {
        while (!Thread.currentThread.hasPendingCancellation) {
            _logger.info("working...")
            sleep(_options.value.delay)
        }
    }
}

// 3. 扩展到容器
extend ServiceCollection{
    public func addWorker(configureOptions: (WorkerOptions) -> Unit) {
        this.configure(configureOptions)
        this.addHostedService<WorkerServer>()
    }
}

main(args: Array<String>) {

    let builder = Host.createBuilder(args)

    builder.services.addWorker{ configureOptins =>   
        configureOptins.delay = Duration.second * 4
    }                                                

    let host = builder.build()

    host.run()

    return 0
}

总结

  1. 这样我们就可以开启后台线程去运行后台服务,处理后台任务了。通过这个案例我们可以看到通用主机为我们整合了基础设施,开箱即用!

  2. 通用主机已经为我们注册 ILoggerFactoryIConfiguration 服务

多环境开发

日常开发过程中,许多逻辑需要区分开发场景还是生产场景。环境变量名可以通过 命令行参数 或者 环境变量 来修改,规则如下:

  1. 命令行参数:environment=Development
  2. 环境变量:spire-environment=Development
cangjie
main(args: Array<String>) {

    let builder = Host.createBuilder(args)

    builder.services.addWorker{ configureOptins =>
        //如果是开发环境延迟4s
        if (builder.environment.isDevelopment()) { 
            configureOptins.delay = Duration.second * 4
        } else { 
            configureOptins.delay = Duration.second * 3
        } 
    }

    let host = builder.build()

    host.run()

    return 0
}

//注入到容器
public class WorkerServer <: BackgroundService {

    public WorkerServer(
        let _options: IOptions<WorkerOptions>,
        let _loggerFactory: ILoggerFactory,
        let _env :IHostEnvironment) { 
        _logger = _loggerFactory.createLogger<WorkerServer>()
    }

    public func run() {
        while (!Thread.currentThread.hasPendingCancellation) {
            if(_env.isProduction()) { 
                _logger.info("working...")
            } else {
                _logger.info("sleep...")
            }
            sleep(_options.value.delay)
        }
    }
}

总结

  1. 如果没有配置环境变量名,默认为 Production
  2. 通用主机默认会加载 appsetting.json 配置文件和 appsetting.${environment}.json
  3. WorkerService 也可以解析 IHostEnvironment 来获取环境名,通用主机已经将他注册到容器中了

内置服务

通用主机为我们内置了一些服务,具体如下:

接口用途
ILoggerFactory用于创建和配置 ILogger 实例,管理日志记录器的生命周期和日志提供程序(如 Console、File 等)。
IConfiguration提供对应用程序配置(如 appsettings.json、环境变量、命令行参数等)的键值对访问和读取功能。
IHostEnvironment提供当前宿主环境的信息(如 ApplicationNameEnvironmentNameContentRootPath 等)。