How exactly is Assisted-Inject supposed to be used to be useful...

87 views
Skip to first unread message

Maatary Okouya

unread,
Dec 25, 2013, 8:09:04 PM12/25/13
to google...@googlegroups.com
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. 

If anyone could enlighten me here, i would greatly i appreciate, 

May thanks 

Moandji Ezana

unread,
Dec 26, 2013, 1:08:21 AM12/26/13
to google...@googlegroups.com

If everything depends on CLI input, you could wrap it in a 'settings' object and inject that object where needed, rather than use assisted injection everywhere.

--
You received this message because you are subscribed to the Google Groups "google-guice" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-guice...@googlegroups.com.
To post to this group, send email to google...@googlegroups.com.
Visit this group at http://groups.google.com/group/google-guice.
For more options, visit https://groups.google.com/groups/opt_out.

Maatary Okouya

unread,
Dec 26, 2013, 4:53:43 AM12/26/13
to google...@googlegroups.com
Thx for the prompt answer. However I don't think that would work.

Like I said u have A needs B needs C need Z needs cli inputs. 
C needs a Z, but Z can t be constructed without inputs, which must be cli provided.
B needs a C, but C can be constructed without a Z inputs
And so on.
And so on. 
You received this message because you are subscribed to a topic in the Google Groups "google-guice" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/google-guice/c9fipvWw1j8/unsubscribe.
To unsubscribe from this group and all its topics, send an email to google-guice...@googlegroups.com.

Willi Schönborn

unread,
Dec 26, 2013, 5:46:51 AM12/26/13
to google...@googlegroups.com

It does work, I've done it multiple times this way. It's very easy of you use args4j, you then already have a little pojo which wraps your command line arguments.

What you then need to do is: bind your settings to that one instance and let your Z depend on it. Everything else just depends on their direct dependency.

Maatary Okouya

unread,
Dec 26, 2013, 11:01:18 AM12/26/13
to google...@googlegroups.com
Maybe if we go for example or more details information that could help. Here is my situation : 

I have an InfrastructureService, which require a KnowledgeBaseService which in turn require anConFigDataObject. 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 a file that exist, and provide a getter method that return that File to its consumer (i.e instead of the fileName). 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 InfrastructureServicewhich takes as parameter for its creation method a KnowledgeBaseService.



So what exactly are you recommending here ? Would suggest to: 


val data = new ConfigData(.....)


Class module extends AbstractModule {

    bind(Configdata).toInstance(data)

    .....

}


I have to try.... but let me know if i got u right please

Nate Bauernfeind

unread,
Dec 26, 2013, 11:27:42 AM12/26/13
to google...@googlegroups.com
FWIW, I use AssistedInject Factories for dynamic content.

So for example, I've written a monitoring system where nodes announce themselves in real-time (via Zookeeper) and user-input information like alert configuration gets stored in a simple key-value store (and also shows up dynamically).

Each item has a ServiceName associated with it. To make the software scale, it has the ability to monitor any subset of Services. So for each Service I construct a new object graph for that service (and that service alone).

So I use assisted inject to create my ServiceMonitor class, which is the main entry point for that sub-graph. It has the primary Injector injected and then uses it to create a childInjector and binds a handful of objects as Singletons in the [logical] scope of the Service.

It's a really convenient pattern, as there are dynamic properties (serviceName and metric tags), singletons in the scope of the sub-graph (current state about healthy hosts, for example), and singletons across the entire system (like the subsystem that communicates with Pagerduty).


I do not use AssistedInject for Configuration at all. As I've told you before, I heavily use dropwizard, so I follow their pattern for Configuration. As a result I typically have a top level Configuration object which actually has several fields that are Configuration objects for each different sub-system. When I construct the Guice Module for that sub-system I typically pass the Configuration object into the module. It is then up to that Module to do whatever it needs to do with Config. 

I try to avoid injecting any Configuration objects as they're not really re-usable -- you use it once and hopefully throw it away. So if I need the information to, say, create an HttpClient, then I tend to create a Provider method on the Module and use the Configuration right there without letting it leak any further.


Hope that helps.

Nate

Maatary Okouya

unread,
Dec 26, 2013, 12:21:36 PM12/26/13
to google...@googlegroups.com


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


Is it what you guys had in mind ?



On Thu, Dec 26, 2013 at 11:46 AM, Willi Schönborn <w.scho...@gmail.com> wrote:

Maatary Okouya

unread,
Dec 29, 2013, 4:39:00 PM12/29/13
to google...@googlegroups.com
Thank you i get that better now.
To unsubscribe from this group and stop receiving emails from it, send an email to google-guice+unsubscribe@googlegroups.com.

To post to this group, send email to google...@googlegroups.com.
Visit this group at http://groups.google.com/group/google-guice.
For more options, visit https://groups.google.com/groups/opt_out.

--
You received this message because you are subscribed to a topic in the Google Groups "google-guice" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/google-guice/c9fipvWw1j8/unsubscribe.
To unsubscribe from this group and all its topics, send an email to google-guice+unsubscribe@googlegroups.com.

To post to this group, send email to google...@googlegroups.com.
Visit this group at http://groups.google.com/group/google-guice.
For more options, visit https://groups.google.com/groups/opt_out.

--
You received this message because you are subscribed to the Google Groups "google-guice" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-guice...@googlegroups.com.
To post to this group, send email to google...@googlegroups.com.
Visit this group at http://groups.google.com/group/google-guice.
For more options, visit https://groups.google.com/groups/opt_out.

--
You received this message because you are subscribed to a topic in the Google Groups "google-guice" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/google-guice/c9fipvWw1j8/unsubscribe.
To unsubscribe from this group and all its topics, send an email to google-guice...@googlegroups.com.
To post to this group, send email to google...@googlegroups.com.
Visit this group at http://groups.google.com/group/google-guice.
For more options, visit https://groups.google.com/groups/opt_out.
Reply all
Reply to author
Forward
0 new messages