Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save hsanchez/6632318 to your computer and use it in GitHub Desktop.
Save hsanchez/6632318 to your computer and use it in GitHub Desktop.
/**
* 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