Is it possible to inject an object with scala-guic

2019-06-01 04:14发布

I would like to inject the scala.io.Source but I failed to find a working solution. This is what I have so far:

class Foo @Inject()(var source:Source) {
  // ...
}

And the binding:

class DependencyInjection extends AbstractModule with ScalaModule {
  def configure:Unit = {
     bind[Source.type].to[Source]
     // bind[Source] didn't work
  }
}

Maybe I can wrap the scala.io.Source calls into a local class but it doesn't sound right. Is there a way to inject objects with scala-guice?

1条回答
女痞
2楼-- · 2019-06-01 04:22

Because Source is an abstract class, and there are no public extensions for it (and even if there were, you wouldn't be able to use them anyway since they likely wouldn't have been Guice-enabled), you'll have to use providers or @Provide methods.

Providers:

class Config extends AbstractModule with ScalaModule {
  override def configure: Unit = {
    bind[Source].toProvider(new Provider[Source] {
      override def get = Source.fromFile("whatever.txt")(Codec.UTF8)
    })
  }
}

// you can also extract provider class and use `toProviderType[]` extension 
// from scala-guice:

class FromFileSourceProvider extends Provider[Source]
  override def get = Source.fromFile("whatever.txt")(Codec.UTF8)
}

class Config extends AbstractModule with ScalaModule {
  override def configure: Unit = {
    bind[Source].toProviderType[FromFileSourceProvider]
  }
}

Another way is to use @Provides methods:

class Config extends AbstractModule with ScalaModule {
  @Provides def customSource: Source = Source.fromFile("whatever.txt")(Codec.UTF8)
  // that's it, nothing more
}

I'd also suggest adding a binding annotation to distinguish between different sources in your program, though it entirely depends on your architecture.

This approach is no different from that in Java, when you need to inject classes which are not Guice-enabled or available through factory methods only.

查看更多
登录 后发表回答