Forked from addybhardwaj/DependencyInjectionWithCakePattern.scala
Created
September 20, 2013 01:44
-
-
Save hsanchez/6632318 to your computer and use it in GitHub Desktop.
This file contains 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
/** | |
* Following Gist provides | |
* | |
* - BaseRepository, | |
* - Respositories Trait/Implementation, | |
* - BaseService, | |
* - Services Traits/Implementations | |
* - Config to tie services and repositories | |
* - Registry to add environment specific config like spring profiles (this is for Play framework) | |
*/ | |
/** | |
* Common repository functions. | |
* | |
* @tparam A | |
*/ | |
trait BaseRepository[A] { | |
def _save(instance: A): A | |
def _getById(id: String): A | |
} | |
/** | |
* Defines venue repository contract. | |
*/ | |
trait VenueRepositoryComponent { | |
val venueRepository: VenueRepository | |
trait VenueRepository extends BaseRepository[Venue] { | |
def _findVenuesBy(geoLocation: GeoLocation, radius: Int): Seq[Venue] | |
} | |
} | |
/** | |
* Defines player repository contract. | |
*/ | |
trait PlayerRepositoryComponent { | |
val playerRepository: PlayerRepository | |
trait PlayerRepository extends BaseRepository[Player] { | |
def _findPlayersBy(venue: Venue): Seq[Player] | |
} | |
} | |
/** | |
* Mocked implementation of repository | |
*/ | |
trait MockedVenueRepositoryComponent extends VenueRepositoryComponent { | |
val venueRepository = new MockedVenueRepository | |
class MockedVenueRepository extends VenueRepository { | |
def _save(instance: Venue) = ??? | |
def _getById(id: String) = ??? | |
def _findVenuesBy(geoLocation: GeoLocation, radius: Int) = ??? | |
} | |
} | |
/** | |
* Mocked Player implementation | |
*/ | |
trait MockedPlayerRepositoryComponent extends PlayerRepositoryComponent { | |
val playerRepository = new MockedPlayerRepository | |
class MockedPlayerRepository extends PlayerRepository { | |
def _save(instance: Player) = ??? | |
def _getById(id: String) = ??? | |
def _findPlayersBy(geoLocation: GeoLocation, radius: Int) = ??? | |
} | |
} | |
/** | |
* Common service implementations which are based on BaseRepository | |
*/ | |
trait BaseService[A] { | |
def baseRepository: BaseRepository[A] | |
def save(instance: A): A = { | |
baseRepository._save(instance) | |
} | |
def getById(id: String): A = { | |
baseRepository._getById(id) | |
} | |
} | |
trait VenueServiceComponent { | |
this: VenueRepositoryComponent => | |
val venueService: VenueService | |
trait VenueService extends BaseService[Venue] { | |
def baseRepository = venueRepository | |
def findVenuesBy(geoLocation: GeoLocation, radius: Int): Seq[Venue] = { | |
venueRepository._findVenuesBy(geoLocation, radius) | |
} | |
} | |
} | |
trait PlayerServiceComponent { | |
this: PlayerRepositoryComponent => | |
val playerService: PlayerService | |
trait PlayerService extends BaseService[Player] { | |
def baseRepository = playerRepository | |
def findPlayersBy(venue: Venue): Seq[Player] = { | |
playerRepository._findPlayersBy(venue) | |
} | |
} | |
trait VenueServiceComponentImpl extends VenueServiceComponent { | |
this : VenueRepositoryComponent => | |
val venueService = new VenueServiceImpl | |
class VenueServiceImpl extends VenueService {} | |
} | |
trait PlayerServiceComponentImpl extends PlayerServiceComponent { | |
this : PlayerRepositoryComponent => | |
val playerService = new PlayerServiceImpl | |
class PlayerServiceImpl extends PlayerService {} | |
} | |
/** | |
* Config which ties the pieces together | |
*/ | |
trait ServiceConfigurations { | |
val venueService: VenueServiceComponent#VenueService | |
val playerService: PlayerServiceComponent#PlayerService | |
} | |
object MockServiceConfigurations | |
extends ServiceConfigurations | |
with VenueServiceComponentImpl | |
with PlayerServiceComponentImpl | |
with MockedVenueRepositoryComponent | |
with MockedPlayerRepositoryComponent { | |
} | |
/** | |
* Following is play specific config which takes environment into account. Just like spring profiles | |
*/ | |
import play.api.Play._ | |
import play.api.{Mode, Play} | |
object Registry { | |
def envConfig[A](dev: A, test: A, prod : A) : A = { | |
Play.application.mode match { | |
case Mode.Dev => dev | |
case Mode.Test => test | |
case Mode.Prod => prod | |
} | |
} | |
val serviceConfig : ServiceConfigurations = envConfig(MockServiceConfigurations, ???, ???) | |
} | |
/** | |
* ServiceRegistry can be used to get access to correct implementation of the services | |
*/ | |
trait ServiceRegistry { | |
val venueService = Registry.serviceConfig.venueService | |
val playerService = Registry.serviceConfig.playerService | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment