Topshelf,Owin selfhost,F#和显式字段

时间:2014-10-26 13:14:26

标签: f# owin topshelf

我已经安装了Topshelf.FSharp软件包,这里有一个如何使用它的例子:

https://gist.github.com/haf/4252121

该示例的一部分定义了一个“Svc”(服务)类,如下所示:

type Svc() =
  member x.Start() =
    printfn "Started"
  member x.Stop() =
    printfn "Stopped"

使用Owin selfhost,您可以调用IDisposable WebApp.Start(...)的各种静态重载之一来启动Web服务器,然后将其置于停止状态。在C#中,如果要组合Topshelf和Owin,可以在调用Start()时将Start()的IDisposable结果存储在Svc类的私有本地字段中,然后在Stop中调用Dispose()(方法。

在F#中,您可以使用“显式字段”(http://msdn.microsoft.com/en-us/library/dd469494.aspx)声明IDisposable类型的单元化字段,但这看起来有点尴尬,有更好的方法吗?

2 个答案:

答案 0 :(得分:2)

您不必使用显式字段来生成“未初始化的”IDisposable值。例如,要定义可重新启动的服务,可以使用隐式webApp字段,如下所示:

// Example 1: Using an implicit mutable IDisposable field.  
type Svc() =
    let mutable webApp = null

    member __.Start() = 
        if webApp = null then webApp <- WebApp.Start<Startup> "http://localhost:12345"

    member __.Stop() = 
        if webApp <> null then webApp.Dispose(); webApp <- null

// Example 2: Using an implicit mutable IDisposable option field.  
type Svc'() =
    let mutable webApp = None

    member __.Start() = 
        match webApp with 
            | Some _ -> () 
            | None -> webApp <- Some(WebApp.Start<Startup> "http://localhost:12345")

    member __.Stop() = 
        match webApp with 
            | Some webAppValue -> webAppValue.Dispose(); webApp <- None
            | None -> ()

如果服务不必重新启动,我会使用(不可变的)隐式惰性字段,而不是像@Tom建议的那样。

答案 1 :(得分:1)

您是否可以将该成员改为Lazy<T>并让它在首次访问时自动初始化?在这种情况下,我不太确定F#的要求,即为什么这是一个问题,但对于延迟初始化,Lazy似乎是一个不错的选择。