F# Host.CreateDefaultBuilder().ConfigureServices() 没有 HostBuilderContext
F# Host.CreateDefaultBuilder().ConfigureServices() does not have HostBuilderContext
我正在创建一个 WorkerService。
我有信心使用 C# 来完成它,但我正在努力使用 F# 版本。
C#Program.cs
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureServices((hostContext, services) =>
{
// here I have access to the builded configuration
// read stuff from configuration
var interval = TimeSpan.Parse(hostContext.Configuration["Service:Run:interval"]);
services.AddHostedService<Worker>();
});
F#Program.fs
let CreateHostBuilder (args) =
Host.CreateDefaultBuilder()
.ConfigureServices(
fun (services:IServiceCollection) -> //hostContext:HostBuilderContext,
//fun (context:HostBuilderContext, services:IServiceCollection) ->
// where is the builded configuration ???
//let configuration = ???
services.AddHostedService<Worker>() |> ignore
)
我不知道如何读取配置来设置我需要注入的一些服务设置。
为什么IHostBuilder.ConfigureServices的签名不一样?
C#
IHostBuilder ConfigureServices(Action configureDelegate);
F#
IHostBuilder 配置服务:configureDelegateAction -> IHostBuilder
HostBuilderContext 传递给 .ConfigureContainer() 所以我尝试了这个:
open System
open System.Threading
open System.Threading.Tasks
type IMyWorker =
abstract member Start: unit -> unit
type MyWorker(interval:TimeSpan) =
inherit BackgroundService()
override this.ExecuteAsync (step:CancellationToken):Task = Task.CompletedTask
interface IMyWorker with
member this.Start() = ()
let CreateHostBuilder (args) =
// 1. this is empty
//let configuration = ConfigurationBuilder().Build()
//let interval = TimeSpan.Parse(configuration.["Service:Run:interval"])
let mutable loadedConfiguration:Option<IConfiguration> = None
Host.CreateDefaultBuilder()
.ConfigureHostConfiguration( fun(confBuilder:IConfigurationBuilder) ->
// it's ok here to read more settings, like "serilog.json" for example ?
// 2. this is still empty
//let configuration = confBuilder.Build()
//let interval = TimeSpan.Parse(configuration.["Service:Run:interval"])
// where to store the values ? configuration.[""]
()
)
.ConfigureContainer( fun (hostContext:HostBuilderContext) ->
// 5. this is ok, it is builded properly
// but ist is called after ConfigureServices()
loadedConfiguration <- Some(hostContext.Configuration) // :> IConfigurationRoot
let interval = TimeSpan.Parse(hostContext.Configuration.["Service:Run:interval"])
()
)
.ConfigureServices(
fun(services:IServiceCollection) ->
// 4. this is empty
//let configuration = ConfigurationBuilder().Build()
//let interval = TimeSpan.Parse(configuration.["Service:Run:interval"])
if loadedConfiguration.IsNone then failwith "configuration not loqaded yet"
let interval = TimeSpan.Parse(loadedConfiguration.Value.["Service:Run:interval"])
//let interval = TimeSpan.Parse("00:01:00")
let worker = new MyWorker(interval)
services.AddSingleton<IMyWorker>(worker) |> ignore
)
但它不起作用,因为 ConfigureContainer() 在 ConfigureServices() 之后调用,我认为应该有一种方法可以使用构建的配置而不将其存储在某处。
它应该如何运作?
这应该可以解决问题:
let createHostBuilder args =
Host
.CreateDefaultBuilder(args)
.ConfigureServices (fun hostContext services ->
let interval = TimeSpan.Parse(hostContext.Configuration.["Service:Run:interval"]);
services.AddHostedService<Worker>() |> ignore
)
我正在创建一个 WorkerService。
我有信心使用 C# 来完成它,但我正在努力使用 F# 版本。
C#Program.cs
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureServices((hostContext, services) =>
{
// here I have access to the builded configuration
// read stuff from configuration
var interval = TimeSpan.Parse(hostContext.Configuration["Service:Run:interval"]);
services.AddHostedService<Worker>();
});
F#Program.fs
let CreateHostBuilder (args) =
Host.CreateDefaultBuilder()
.ConfigureServices(
fun (services:IServiceCollection) -> //hostContext:HostBuilderContext,
//fun (context:HostBuilderContext, services:IServiceCollection) ->
// where is the builded configuration ???
//let configuration = ???
services.AddHostedService<Worker>() |> ignore
)
我不知道如何读取配置来设置我需要注入的一些服务设置。
为什么IHostBuilder.ConfigureServices的签名不一样?
C#
IHostBuilder ConfigureServices(Action configureDelegate);
F#
IHostBuilder 配置服务:configureDelegateAction -> IHostBuilder
HostBuilderContext 传递给 .ConfigureContainer() 所以我尝试了这个:
open System
open System.Threading
open System.Threading.Tasks
type IMyWorker =
abstract member Start: unit -> unit
type MyWorker(interval:TimeSpan) =
inherit BackgroundService()
override this.ExecuteAsync (step:CancellationToken):Task = Task.CompletedTask
interface IMyWorker with
member this.Start() = ()
let CreateHostBuilder (args) =
// 1. this is empty
//let configuration = ConfigurationBuilder().Build()
//let interval = TimeSpan.Parse(configuration.["Service:Run:interval"])
let mutable loadedConfiguration:Option<IConfiguration> = None
Host.CreateDefaultBuilder()
.ConfigureHostConfiguration( fun(confBuilder:IConfigurationBuilder) ->
// it's ok here to read more settings, like "serilog.json" for example ?
// 2. this is still empty
//let configuration = confBuilder.Build()
//let interval = TimeSpan.Parse(configuration.["Service:Run:interval"])
// where to store the values ? configuration.[""]
()
)
.ConfigureContainer( fun (hostContext:HostBuilderContext) ->
// 5. this is ok, it is builded properly
// but ist is called after ConfigureServices()
loadedConfiguration <- Some(hostContext.Configuration) // :> IConfigurationRoot
let interval = TimeSpan.Parse(hostContext.Configuration.["Service:Run:interval"])
()
)
.ConfigureServices(
fun(services:IServiceCollection) ->
// 4. this is empty
//let configuration = ConfigurationBuilder().Build()
//let interval = TimeSpan.Parse(configuration.["Service:Run:interval"])
if loadedConfiguration.IsNone then failwith "configuration not loqaded yet"
let interval = TimeSpan.Parse(loadedConfiguration.Value.["Service:Run:interval"])
//let interval = TimeSpan.Parse("00:01:00")
let worker = new MyWorker(interval)
services.AddSingleton<IMyWorker>(worker) |> ignore
)
但它不起作用,因为 ConfigureContainer() 在 ConfigureServices() 之后调用,我认为应该有一种方法可以使用构建的配置而不将其存储在某处。
它应该如何运作?
这应该可以解决问题:
let createHostBuilder args =
Host
.CreateDefaultBuilder(args)
.ConfigureServices (fun hostContext services ->
let interval = TimeSpan.Parse(hostContext.Configuration.["Service:Run:interval"]);
services.AddHostedService<Worker>() |> ignore
)