Last active
December 18, 2015 15:49
-
-
Save privateblue/5806836 to your computer and use it in GitHub Desktop.
cake pattern based 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
// a dependency | |
trait Driver { | |
val message: String | |
} | |
trait ProductionDriver extends Driver { | |
val message = "production " | |
} | |
trait TestDriver extends Driver { | |
val message = "test " | |
} | |
// repositories | |
abstract class Repository { | |
self: Driver => | |
} | |
class PostRepository extends Repository { | |
self: Driver => | |
def hello = message + "post" | |
} | |
class BlogRepository extends Repository { | |
self: Driver => | |
def hello = message + "blog" | |
def bar = message + "blog bar" | |
} | |
trait RepositoryContext { | |
val postRepository: PostRepository | |
val blogRepository: BlogRepository | |
} | |
trait ProductionRepositoryContext extends RepositoryContext { | |
val postRepository = new PostRepository with ProductionDriver | |
val blogRepository = new BlogRepository with ProductionDriver | |
} | |
trait TestRepositoryContext extends RepositoryContext { | |
val postRepository = new PostRepository with TestDriver | |
val blogRepository = new BlogRepository with TestDriver | |
} | |
// services | |
trait ServiceComponent { | |
self: RepositoryContext => | |
abstract class Service | |
} | |
trait PostServiceComponent extends ServiceComponent { | |
self: RepositoryContext with SomeBehaviourServiceComponent with BlogServiceComponent => | |
val postService: PostService | |
class PostService extends Service | |
with SomeBehaviourService { | |
def foo = postRepository.hello | |
def bar = blogRepository.bar | |
def baz = blogService.bar | |
} | |
} | |
// extra PostService behaviour factored out to separate trait | |
trait SomeBehaviourServiceComponent extends ServiceComponent { | |
self: PostServiceComponent with RepositoryContext => | |
trait SomeBehaviourService { | |
self: PostService => | |
def behave = postRepository.hello + " with a twist" | |
} | |
} | |
trait BlogServiceComponent { | |
self: RepositoryContext with PostServiceComponent => | |
val blogService: BlogService | |
class BlogService extends Service { | |
def foo = blogRepository.hello | |
def bar = postService.bar | |
} | |
} | |
trait ServiceContext extends RepositoryContext | |
with SomeBehaviourServiceComponent | |
with PostServiceComponent | |
with BlogServiceComponent { | |
val postService = new PostService | |
val blogService = new BlogService | |
} | |
trait ProductionServiceContext extends ServiceContext | |
with ProductionRepositoryContext | |
trait TestServiceContext extends ServiceContext | |
with TestRepositoryContext { | |
// mocking PostService | |
override val postService = new PostService { | |
override def bar = "mock bar" | |
} | |
} | |
// client code (application) | |
trait Controller | |
object MyController extends Controller | |
with ProductionServiceContext { | |
def foo = | |
postService.foo + "\n" + | |
postService.bar + "\n" + | |
postService.baz + "\n" + | |
postService.behave + "\n" + | |
blogService.foo + "\n" + | |
blogService.bar | |
} | |
trait Test | |
object MyTest extends Test | |
with TestServiceContext { | |
def foo = | |
postService.foo + "\n" + | |
postService.bar + "\n" + | |
postService.baz + "\n" + | |
postService.behave + "\n" + | |
blogService.foo + "\n" + | |
blogService.bar | |
} | |
MyController.foo | |
MyTest.foo |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment