I'm currently using Guice
in my App. However I find myself mostly using assisted inject because there is a chain of injected objects that all depend on what was the input of the program.
Hence almost everything is assisted inject.
For instance A need B who need C who need Z which needs input from the command line. In the end I feel like everything will be assisted injected. So given that I'm stuck with it I want to be sure that I'm using it right.
I personally feel like writing my own factories would be as good. Moreover, in addition to the same advantage I could further limit the creation of my objects in question to these factories.
Hence my question here is, how useful is it really to use assisted inject, is it only the idea of having things assisted and non assisted as the same time? What if like in my case you have only have assisted parameters?
Their must be some gain at organizing it with assisted injection. I just don't see it.
PS:
My dependency is as such:
I have an InfrastructureService, which require a KnowledgeBaseService which in turn require an ConFigDataObject. My configDataObject contains information coming from the inputs of the program. The configDataObject store these information after doing some validation and processing on those inputs. For instance a string representing file path can be provided to it, and it will validate that it is file that exist, and have a getter method that return that File to its consumer. Other things might be URLNname to real URL Object, and so on.
The important point here is this following graph: InfrastructureService -> KnowledgeBaseService -> ConFigDataObject -> InputData
Therefore the InfrastructureService can only work with a knowledgeBaseService that is started with the right inputFile, URL, workingfolder and etc.... which is provided to it with a configDataObject, that receive them from the input of the program and store a processed version of them.
Therefore as of now what I do is to have a assistedFactory to create the knowledgeBaseService. It takes as parameter the ConfigDataObject. The configDataObject is created with a factoryMethod (Scala Companion Object). Finally, the an assistedFactory is also create for the InfrastructureService which takes as parameter for its creation method a KnowledgeBaseService.
As you can guess everything is pretty much created upfront, and somehow manually. I find it odd.
Here is what i did to finally solve the issue in a more elegant way than using an unnecessary chain of assisted injected due to the parameters of the application.
that is If as in my case your data comes from the command Line then the right appraoch i believe is to bind the type of the input data structure to instance input structure obtained from the command line:
object MyApp extends App {
val config = ConfigData(args(0))
val injector = Guice.createInjector(module(config))
val service = injector.getInstance(classOf[InfrastructureService])
println("The service name is:" + service.kbService.config.configName)
}
case class module(config: ConfigData) extends AbstractModule {
def configure(): Unit = {
bind(classOf[ConfigData]).toInstance(config)
}
}
case class ConfigData(val configName: String)
class KbService @Inject() (val config: ConfigData)
class InfrastructureService @Inject() (val kbService: KbService)
I believe the Key here is to remind yourself that the module can be parameterize with any input data deem necessary