Last active
December 28, 2015 18:39
-
-
Save privateblue/7544244 to your computer and use it in GitHub Desktop.
mixed style dependency injection pattern for repositories and services
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
// COMMON-BASE LIBRARY | |
// dependencies | |
trait ConnectionPoolProvider { | |
protected val connectionPool: ConnectionPool | |
} | |
trait ExternalStuff { | |
protected val stuff = "stuff" | |
} | |
// BUSINESS LOGIC LIBRARY (depends on COMMON-BASE) | |
// models and messages | |
case class Post(name: String) | |
case class Blog(name: String) | |
case class DoFancy | |
case class IsLame | |
// repositories | |
abstract class Repository(cp: ConnectionPool) | |
class PostRepository(cp: ConnectionPool) extends Repository(cp) { | |
def get = Post("hello") | |
def add = ??? | |
} | |
class BlogRepository(cp: ConnectionPool) extends Repository(cp) { | |
def get = Blog("world") | |
def add = ??? | |
} | |
// internal services | |
trait ServiceComponent { | |
abstract class Service | |
} | |
trait PostReadServiceComponent extends ServiceComponent { | |
self: ConnectionPoolProvider with ExternalStuff => | |
protected val postReadService = new PostReadService | |
class PostReadService extends Service { | |
private val postRepository = new PostRepository(connectionPool) | |
private val blogRepository = new BlogRepository(connectionPool) | |
def get = postRepository.get | |
def foobar = (stuff, blogRepository.get.name) | |
} | |
} | |
trait PostWriteServiceComponent { | |
self: ConnectionPoolProvider with PostReadServiceComponent => | |
protected val postWriteService = new PostWriteService | |
class PostWriteService extends Service { | |
private val postRepository = new PostRepository(connectionPool) | |
def add = postRepository.add | |
def doSomething = postReadService.get | |
} | |
} | |
// client facing api services | |
trait ApiService | |
trait FancyFeatureService extends ApiService | |
with ConnectionPoolProvider | |
with ExternalStuff | |
with PostReadServiceComponent | |
with PostWriteServiceComponent { | |
def doFancy = { | |
postWriteService.add | |
postReadService.foobar | |
} | |
} | |
trait LameFeatureService extends ApiService | |
with ConnectionPoolProvider | |
with ExternalStuff | |
with PostReadServiceComponent | |
with PostWriteServiceComponent { | |
def isLame = postWriteService.doSomething == postReadService.get | |
} | |
// COMMON-PLAY or COMMON-UTILS LIBRARY (depends on COMMON-BASE) | |
// environment specific implementation of dependencies | |
trait ProductionConnectionPoolProvider extends ConnectionPoolProvider { | |
val cp = ??? | |
} | |
trait ProductionExternalStuff extends ExternalStuff { | |
override val stuff = "stuff in this environment" | |
} | |
// CLIENT APP (depends on BUSINESS LOGIC LIBRARY, COMMON-PLAY LIBRARY) | |
// api service instances | |
object FancyFeature extends FancyFeatureService | |
with ProductionConnectionPoolProvider | |
with ProductionExternalStuff | |
object LameFeature extends LameFeatureService | |
with ProductionConnectionPoolProvider | |
with ProductionExternalStuff | |
// akka interface | |
class MyActor extends Actor { | |
def receive = { | |
case DoFancy => FancyFeature.doFancy | |
case IsLame => sender ! LameFeature.isLame | |
} | |
} | |
// http interface | |
class MyController extends Controller { | |
def doFancy = FancyFeature.doFancy | |
def isLame = LameFeature.isLame | |
} | |
// TESTS | |
trait TestConnectionPoolProvider extends ConnectionPoolProvider { | |
val cp = ??? | |
} | |
trait TestExternalStuff extends ExternalStuff { | |
override val stuff = "test stuff" | |
} | |
object TestFancyFeature extends FancyFeatureService | |
with TestConnectionPoolProvider | |
with TestExternalStuff | |
object TestLameFeature extends LameFeatureService | |
with TestConnectionPoolProvider | |
with TestExternalStuff | |
object MyTest { | |
def run = { | |
TestFancyFeature.doFancy | |
TestLameFeature.isLame | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment