Using Subcut to inject a string into a third party library

52 views Asked by At

I am trying to integrate Subcut with my project for Dependency injection and am running into an issue integrating it with a third party library.

The library requires the location of a file to load which I am storing in my Play configuration and I want to inject the location using Subcut. Below is the module I have currently defined :

object ServerModule extends NewBindingModule (module => {
import module._ 

bind[String] idBy 'location toSingle {
  Play.current.configuration.getString("file.location").getOrElse (
    throw new IllegalStateException("Cannot find location")
  )
}

bind[ThirdPartyLib] toSingle {
  val location = inject [String] (Some('location.toString))
  ThirdPartyLib fromFile location
}

bind[Controller] toProvider { implicit module => new Controller}})

This code compiles but at runtime it fails saying it cannot find the binding for the location String identified by 'location.

Another thing I do not understand why I can do idBy 'location but doing inject[T]('location) causes compilation to fail? From looking at the code it appears that idBy just converts a Symbol into a String then the inject method only takes a String. Is this just a deficiency of the Subcut API or am I doing something wrong?

1

There are 1 answers

0
ahjmorton On BEST ANSWER

I found the problem was using Symbols for the binding identifier. I swapped them out for a solution using BindingIds and everything worked :

object BindingKeys {
  object Location extends BindingId
}

object ServerModule extends NewBindingModule (module => {
  import module._
  import BindingKeys._

  bind[String] idBy Location toSingle {
    Play.current.configuration.getString("file.location").getOrElse (
      throw new IllegalStateException("Cannot find file")
    )
  }

  bind[ThirdPartyLib] toProvider { implicit module =>
      val libLocation = inject [String] (Some(Location))
      ThirdPartyLib fromFile libLocation
  }

  bind[Controller] toProvider { implicit module => new Controller}})