Last active
March 8, 2016 14:50
-
-
Save joescii/687ffe9090498a643ccf to your computer and use it in GitHub Desktop.
Scala dependency injection with traits
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.joescii | |
package object code { | |
val DbThing = new DbThingImpl() | |
val HttpThing = new HttpThingImpl() | |
val BizThing = new BizThingImpl(DbThing, HttpThing) | |
trait DbThing { | |
def getDbStuff(params):Future[DbStuff] | |
} | |
trait HttpThing { | |
def getHttpStuff(params):Future[HttpStuff] | |
} | |
trait BizThing { | |
def doComplicatedStuff(params):Future[BizStuff] | |
} | |
private [code] class DbThingImpl extends DbThing { | |
override def getDbStuff(params):Future[DbStuff] = ??? | |
} | |
private [code] class HttpThingImpl extends HttpThing { | |
override def getHttpStuff(params):Future[HttpStuff] = ??? | |
} | |
private [code] class BizThingImpl(db:DbThing, http:HttpThing) extends BizThing { | |
override def doComplicatedStuff(params):Future[BizStuff] = | |
db.getDbStuff(params).zip(http.getHttpStuff(params)).map { | |
case (dbStuff, httpStuff) => ??? | |
} | |
} | |
} |
Thanks for all the tips! I feel like I'm actually in pretty good shape today, but with some cool ideas to try soon. I often hear about ReaderT
btw. Maybe it's about time to dive into that one.
I was going for something like what @sleepynate did. Just separate out the purecode (f) from the impure side-effecting code (BizThingImpl). That way you can unit test f easily and then integration test BizThingImpl with Wiremock etc.
@pellunutty's solution looks pretty nice. Because M is a Monad you could substitute Future with the Identity Monad for your tests (or any other Monad you want to).
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@pellunutty should
case class Env[M[_]](dbThing: DbThing[M], httpThing: HttpThing[M])
becase class Env[M[_]](dbThing: M[DbThing], httpThing: M[HttpThing])
?If not could you definite what DbThing and HttpThing would look like?