5 people like it.

Dependency injection, revisited

Dependency injection using the cutting edge programming language research, also known as global mutable variable. Is this a serious snippet or not? No category theory and mocking frameworks are required, so probably not.

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
19: 
20: 
21: 
22: 
23: 
24: 
25: 
26: 
27: 
28: 
// The `isCurrentMonth` depends on an implementation of a
// timer that tells the current time or a mock time for tests

type ITime =
  abstract Now : System.DateTime

let mutable time:ITime = 
  { new ITime with 
    member x.Now = failwith "Not initialized" }

let isCurrentMonth (t:System.DateTime) = 
  t.Month = time.Now.Month

// Implementation for production

time <- 
  { new ITime with 
    member x.Now = System.DateTime.Now }

isCurrentMonth (System.DateTime(2018, 7, 5))

// Implementation for unit testing

time <- 
  { new ITime with 
    member x.Now = System.DateTime(2018, 1, 1) }

isCurrentMonth (System.DateTime(2018, 7, 5))
abstract member ITime.Now : System.DateTime

Full name: Script.ITime.Now
namespace System
Multiple items
type DateTime =
  struct
    new : ticks:int64 -> DateTime + 10 overloads
    member Add : value:TimeSpan -> DateTime
    member AddDays : value:float -> DateTime
    member AddHours : value:float -> DateTime
    member AddMilliseconds : value:float -> DateTime
    member AddMinutes : value:float -> DateTime
    member AddMonths : months:int -> DateTime
    member AddSeconds : value:float -> DateTime
    member AddTicks : value:int64 -> DateTime
    member AddYears : value:int -> DateTime
    ...
  end

Full name: System.DateTime

--------------------
System.DateTime()
   (+0 other overloads)
System.DateTime(ticks: int64) : unit
   (+0 other overloads)
System.DateTime(ticks: int64, kind: System.DateTimeKind) : unit
   (+0 other overloads)
System.DateTime(year: int, month: int, day: int) : unit
   (+0 other overloads)
System.DateTime(year: int, month: int, day: int, calendar: System.Globalization.Calendar) : unit
   (+0 other overloads)
System.DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int) : unit
   (+0 other overloads)
System.DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, kind: System.DateTimeKind) : unit
   (+0 other overloads)
System.DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, calendar: System.Globalization.Calendar) : unit
   (+0 other overloads)
System.DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, millisecond: int) : unit
   (+0 other overloads)
System.DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, millisecond: int, kind: System.DateTimeKind) : unit
   (+0 other overloads)
val mutable time : ITime

Full name: Script.time
type ITime =
  interface
    abstract member Now : DateTime
  end

Full name: Script.ITime
val x : ITime
property ITime.Now: System.DateTime
val failwith : message:string -> 'T

Full name: Microsoft.FSharp.Core.Operators.failwith
val isCurrentMonth : t:System.DateTime -> bool

Full name: Script.isCurrentMonth
val t : System.DateTime
property System.DateTime.Month: int
property System.DateTime.Now: System.DateTime
Raw view Test code New version

More information

Link:http://fssnip.net/7Vb
Posted:6 years ago
Author:Tomas Petricek
Tags: dependency injection