Tutorial: Using Existing Services
Consume the standard FsFlow service packages from an explicit environment.
FsFlow ships with a few reusable service packages such as clock, logging, environment variables, console, filesystem, HTTP, and process execution.
These are still explicit dependencies. The workflow only sees them when your environment provides them.
Build An Environment
open FsFlow
open FsFlow.Services.Core
type AppEnv =
{ Runtime: BaseRuntime }
interface IHas<IClock> with
member this.Service = this.Runtime.Clock
interface IHas<ILog> with
member this.Service = this.Runtime.Log
interface IHas<IEnvironmentVariables> with
member this.Service = this.Runtime.EnvironmentVariables
Use The Services
let loadMode : Flow<AppEnv, EnvironmentVariableError, string> =
flow {
let! now = Clock.utcDateTime
let! mode = EnvironmentVariable.get "APP_MODE"
do! Log.info $"[{now:O}] starting in mode {mode}"
return mode
}
The workflow does not know where the clock, logger, or environment variables came from. It only knows the service contracts.
Run It
let run () = task {
let env = { Runtime = BaseRuntime.liveValue }
let! exit = loadMode.ToTask(env)
printfn "%A" exit
}
If you already have several standard services, wrapping them once in an app environment is usually the cleanest boundary.
Continue with Tutorial: Creating Reusable Services when you need your own service contract alongside the built-in ones.