Jas
Jas

Reputation: 15103

Scala cake pattern and multiproject

In common-project I have this:

trait DBProvider
trait DBTableNamesProvider
trait DefaultDBProvider extends DBProvider
trait DefaultTableNames extends  DBTableNamesProvider

trait MyService extends DBProvider with DBTableNamesProvider

object MyService {
  def apply() = new MyService with DefaultDBProvider with DefaultTableNames {}
}

In projectA which has a reference to common-project as a jar I wish to construct MyService

projectA (has dependency on common-project):

object MyOtherApp {
  trait MyOtherTableName extends DBTableNamesProvider
  val MyCustomService = MyService() with MyOtherTableName // will not compile how to reuse the module's MyService() with another implementation of one of the traits?
}

The above will not compile I cannot just call MyService() construction and override some of the dependencies.

The above is what I wish to do, I wish to override from a different project the factory construction of MyService() apply with my own implementation of MyProjectATableNames is that possible in scala? if not what is the recommended way without code repetition?

Upvotes: 0

Views: 55

Answers (2)

Dima
Dima

Reputation: 40500

 val MyCustomService = new MyService() with MyOtherTableName

should work

If you want to also inherit from the DefaultDBProvider and DefaultTableNames, you would have to either list them explicitly as well:

val MyCustomService = new MyService() with MyOtherTableName with DefaultDBProvider with DefaultTableNames

or create an intermediate trait in the common library:

trait DefaultService extends MyService with DefaultDBProvider with DefaultTableNames

Upvotes: 1

ntviet18
ntviet18

Reputation: 792

You cannot override constructed type like that because MyService() is an object not a type anymore. So to reuse your code you might create a class like

class ConfiguredMyService extends DefaultDBProvider with DefaultTableNames

in the first app you can declare

object MyService {
  def apply() = new ConfiguredMyService
}

and in the second

val MyCustomService = new ConfiguredMyService with MyOtherTableName

Note: Nowadays, Cake pattern is considered an anti-pattern, so I recommend you checkout Dependency Injection.

Upvotes: 0

Related Questions