Saturday, 8 September 2012

Alternative dependency injection in F#

Dependency injection is a pattern where a dependency of a class is passed to an instance of the class at runtime and is not created by the class itself. This is very useful for decoupling code, especially when you are unit testing and want to mock a dependency.

In OO languages like C# and Java, this is mostly often done with constructor injection, i.e.:

interface IB
{
        void DoB();
}

class A
{
        public A(IB b)
        {
                this.b = b;
        }

        public DoA()
        {
                this.b.DoB();
        }

        private IB b;
}

The same thing can be done in F#, but there's an alternative. You could have your dependency be an abstract member and use an object expression to create a concrete instance that has the correct dependency.

type IB =
    abstract DoB : unit -> unit

type B() =
    interface IB with
        member this.DoB() = ()

[<AbstractClass>]
type A() = 
    abstract b : IB
    member this.doA() = this.b.DoB()

let implA = 
    { new A() with 
        member x.b = B() :> IB
    }

This isn't a better way of doing dependency injection. It's a more complicated way of achieving pretty much the same thing, but it does remind me a little of the Scala cake pattern.

No comments: