Skip to content

Instantly share code, notes, and snippets.

@daxfohl
Last active May 16, 2020 01:15
Show Gist options
  • Save daxfohl/0183db108924ee87440928cb803dcfc3 to your computer and use it in GitHub Desktop.
Save daxfohl/0183db108924ee87440928cb803dcfc3 to your computer and use it in GitHub Desktop.
Simple SOA in F#
module Program
// A simple service
module PrinterService =
open System
// Helper functions first
// They can be public for easy unit testing, so long as they don't leave things inconsistent
let isObscene s = String.length s = 4
let censor s = if isObscene s then String('*', s.Length) else s
let print s = printfn "%s" (censor s)
// Here's the interface that most consumers will use
type IPrinter =
abstract member Print : s:string -> unit
// The class is a thin wrapper around some funtions defined above
type Printer() =
interface IPrinter with
member __.Print s = print s
// A service depending on another
module AdderService =
open PrinterService
// Helper functions. I prefer curried style on simple functions with raw types, but tupled style otherwise.
let add x y = x + y
let addAndPrint(printer: IPrinter, x, y) =
let z = add x y
printer.Print(sprintf "%d+%d=%d" x y z)
z
// The interface
type IAdder =
abstract member Add: x:int * y:int -> int
// The class, note it takes the other service and then calls existing functions with it
// Also note it takes the other service as an interface, so easy mocking if desired
type Adder(printer: IPrinter) =
interface IAdder with
member __.Add(x, y) = addAndPrint(printer, x, y)
// The app itself
module App =
open PrinterService
open AdderService
// Note even the app is just a function, could be considered a library thing
let run(p: IPrinter, a: IAdder) =
p.Print("happy")
p.Print("asdf")
a.Add(2, 3) |> ignore
// Main
[<EntryPoint>]
let main _ =
// Main glues everything together and calls the app function
let p = PrinterService.Printer()
let a = AdderService.Adder(p)
App.run(p, a)
0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment