2014-10-26 5 views
0

Я установил пакет Topshelf.FSharp, и есть пример того, как использовать его здесь:Topshelf, Owin selfhost, F # и явные поля

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

Часть примера определяет " Svc»(услуга) класса, как это:

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

с Owin selfhost вы называете один из различных статических перегрузках IDisposable WebApp.Start(...) для запуска веб-сервера, а затем утилизировать его, чтобы остановить его. В C#, если вы хотите комбинировать Topshelf и Owin, вы можете сохранить IDisposable результат Start() в частном локальном поле класса Svc, когда вызывается Start(), а затем вызывается Dispose() на нем в Stop ().

В F # вы можете объявить унифицированное поле типа IDisposable, используя «явные поля» (http://msdn.microsoft.com/en-us/library/dd469494.aspx), но это кажется несколько неудобным, есть ли лучший способ?

ответ

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 ->() 

Если служба не должен быть перезапускаемыми, я хотел бы использовать (неизменное) неявное ленивое поле вместо как @ - предложил Том.

+0

Я думаю, что «idempotent» вы имеете в виду идемпотент даже в том случае, называется «остановка»? В противном случае, если я использую ленивое поле, а кто-то вызывает старт, то остановитесь, а затем начните снова, второй вызов начать ничего не сделает, потому что ленивое значение уже было принудительно? – junichiro

+0

Да, это то, что я имел в виду (несколько смутно) от «идемпотента». Однако теперь я заменил «idempotent» на «перезагружаемый», что более важно. –

1

Не могли бы вы сделать член Lazy<T> вместо этого, чтобы он автоматически инициализировался при первом обращении к нему? Я не совсем уверен в требованиях F # в этом случае, то есть почему именно это проблема, но для отложенной инициализации Lazy, казалось бы, был хорошим выбором.

+0

мой оригинальный вопрос был ошибочным, оказалось, что вы можете объявить единичное поле типа IDisposable, используя «явные поля», хотя это кажется действительно грязным решением. – junichiro