I’m not sure if it’s a good name but as we inject types into our classes, type injection seems a good name. I used this technic in my latest project to build a database-agnostic data-access layer on top of Slick 3.
In Slick 3 (the latest version at the moment) you have to be aware of the database engine you’re connecting to. There is a specific API implementation for each database engine which should be imported in other to work with it.
For instance, the following code is needed to connect and work with Postgres:
On the other hand it’s wise to use an in-memory DB for functional tests instead of Postgres. H2 is a perfect choice, but it’s not fully compatible with Postgres and we were seeing serious issues in our tests when we just replaced the postgres connection with H2.
So, there are three options available:
- Don’t use non-h2-compatible APIs
- Use Postgres; create a new Postgres DB before each test and drop afterward (we can use random db names to support parallel tests)
- Make data-access layer database-agnostic and let Slick handle it
The first one feels like being in jail and the second one makes tests too slow but the third one is OK.
Slick is one of the most advanced libraries I’ve ever seen. It uses the most advanced features of Scala to be type-safe and strong yet simple to use.
We have to inject the slick driver API which, in fact, is a trait and subsequently a type containing various other types. For example
slick.driver.H2Driver.Table is different than
This is easily possible by injecting the
JdbcProfile and import the driver specific types.
The profile can be set to Postgres for production:
And it can be set to H2 for tests:
Now data-access layer will switch to H2 when running tests.
This is a sample of type injection in Scala.