Is the @Singleton scope based on the instance of the Injector being used? I have two classes that aren't getting injected. One is a static factory class (ThreadResourceFactory). The other is a class that the factory instantiates for me (ThreadResource).
In my TestNG @BeforeClass method, I call ThreadResourceFactory.get() to retrieve an instance of ThreadResource for the current TestNG test thread. Since I couldn't figure out a way to retrieve the injector previously created by TestNG, I did the following in the ThreadResource constructor: Guice.createInjector(new MyModule()).injectMembers(this); This works sort of, but because I create another injector, it seems to be managing another set of @Singletons for that new Injector instance. I'm sure there is a better way to do this, I am just unsure how. Any suggestions? On Fri, Oct 28, 2011 at 11:51 AM, Stuart McCulloch <[email protected]>wrote: > On 28 Oct 2011, at 18:43, Jeff wrote: > > Thanks for the great info and helping me work things out. The fog is > clearing. > > Since my language provider depends on the environment, is it kosher to do > something like: > > @Provides *@Named("ENV")* @Singleton > public Properties EnvironmentProvider() { > //setup env > return env; > } > > @Provides @Named("LANG") @Singleton *@Inject* > > ^ you shouldn't need @Inject here since every parameter in a @Provides > method will always be injected > > public Properties LanguageProvider*(@Named("ENV")* Properties env) { > //load language files based on lang setting in env > return lang; > } > > And if I mark these as @Singleton, am I the one that needs to store and > manage the instance or does Guice cache the object returned for lang and > env and never call this method directly again? > > > Guice will apply the scoping around the @Provides method, so you don't > need cache the result yourself > > On Fri, Oct 28, 2011 at 6:32 AM, Stuart McCulloch <[email protected]>wrote: > >> On 27 Oct 2011, at 21:12, Jeff wrote: >> >> The classes containing the injected fields are TestNG test classes. I am >> creating the Injector using the ServiceLoader mechanism within a class that >> implements org.testng.ISuiteListener. TestNG automatically picks up and >> runs the onStart() method before doing anything else and I call >> createInjector() there. >> >> Though, I think I just realized my problem (besides trying to learn/use >> Guice from within another framework I'm also just learning). >> >> The key bit I had not grasped previously was that for Guice/@Inject to >> work, object instantiation must be done directly by Guice >> (Injector.getInstance()), at least for the root node of the object graph (I >> think). >> >> Since TestNG instantiates classes without Guice by default, it was just >> creating normal instances and the @Inject annotations weren't getting >> processed. >> >> TestNG does support Guice via @Test(guiceModule = MyModule.class)annotation, >> but I wanted to avoid the need to put this on EVERY test class >> and thought I could insert my Modules/Providers and enable my custom >> bindings to work globally. >> >> I'm still playing with my code, but I feel like I'm on the right track. >> Can anyone confirm or help me understand if there is a different way? >> >> >> Yes, either the root of the object graph needs to be instantiated by >> Guice or you need to use injectMembers(...) to inject an existing instance >> (in which case you can't use constructor injection in that particular >> class). Of course one benefit of putting @Test(guiceModule=...) on each >> test class (or @Guice in the latest version: >> http://testng.org/doc/documentation-main.html#guice-dependency-injection) >> is that it documents that you're using dependency injection for that test, >> and with modern IDEs it's not too hard to add this automatically or use a >> template. Also note the latest release of TestNG supports module factories >> so you could use the same factory across all your tests: >> http://testng.org/javadocs/org/testng/IModuleFactory.html >> >> Thanks!! >> >> On Thu, Oct 27, 2011 at 5:40 AM, Stuart McCulloch <[email protected]>wrote: >> >>> On 27 Oct 2011, at 06:14, Jeff wrote: >>> >>> I want to do something like: >>> >>> @Inject @Named("conf") >>> Properties config; >>> >>> @Inject @Named("lang") >>> Properties language; >>> >>> Where these objects are singletons initialized once at runtime with >>> environment-specific information. >>> >>> I've tried various things and none result in my Provider or @Provides >>> methods getting called. Here is a trimmed down version of my code using a >>> Provider class: >>> >>> *MyModule.java:* >>> >>> public class SeleniumInjectionModule extends AbstractModule { >>> @Override >>> protected void configure() { >>> >>> bind(Properties.class).annotatedWith(Names.named("conf")).toProvider(ConfigProvider.class); >>> >>> bind(Properties.class).annotatedWith(Names.named("lang")).toProvider(LanguageProvider.class); >>> >>> } >>> } >>> >>> *ConfigProvider.java:* >>> >>> @Singleton >>> public class ConfigProvider implements Provider<Properties> { >>> private final Properties config = new Properties(); >>> >>> public ConfigProvider() { >>> //Load properties file based on 'config' system property value set >>> in Maven profile >>> ... >>> config.load(...); >>> ... >>> } >>> @Override >>> public Properties get() { >>> return config; >>> } >>> } >>> >>> >>> *LanguageProvider.java:* >>> >>> @Singleton >>> public class LanguageProvider implements Provider<Properties> { >>> private final Properties lang = new Properties(); >>> >>> public LanguageProvider() { >>> //Load properties file based on 'language' system property value set >>> in Maven profile >>> ... >>> lang.load(...); >>> ... >>> } >>> @Override >>> public Properties get() { >>> return lang; >>> } >>> } >>> >>> * In my Global Init code:* >>> Guice.createInjector(new MyModule()); >>> >>> What am I missing? >>> >>> >>> Where's the class containing the injected config/language fields >>> mentioned in the start of this email? >>> >>> Assuming that class is called Foo then you need to use >>> injector.getInstance(Foo.class) - or injector.injectMembers(myFoo) if you >>> already have an instance of Foo - to start the injection process and inject >>> those fields. Note that you don't need to do this for everything, just the >>> class at the beginning of the injection graph to kick things off. >>> >>> -- >>> Jeff Vincent >>> [email protected] >>> See my LinkedIn profile at: >>> http://www.linkedin.com/in/rjeffreyvincent >>> I ♥ DropBox <http://db.tt/9O6LfBX> !! >>> >>> >>> -- >>> You received this message because you are subscribed to the Google >>> Groups "google-guice" group. >>> To post to this group, send email to [email protected]. >>> To unsubscribe from this group, send email to >>> [email protected]. >>> For more options, visit this group at >>> http://groups.google.com/group/google-guice?hl=en. >>> >>> >>> >>> -- >>> You received this message because you are subscribed to the Google >>> Groups "google-guice" group. >>> To post to this group, send email to [email protected]. >>> To unsubscribe from this group, send email to >>> [email protected]. >>> For more options, visit this group at >>> http://groups.google.com/group/google-guice?hl=en. >>> >> >> >> >> -- >> Jeff Vincent >> [email protected] >> See my LinkedIn profile at: >> http://www.linkedin.com/in/rjeffreyvincent >> I ♥ DropBox <http://db.tt/9O6LfBX> !! >> >> >> -- >> You received this message because you are subscribed to the Google Groups >> "google-guice" group. >> To post to this group, send email to [email protected]. >> To unsubscribe from this group, send email to >> [email protected]. >> For more options, visit this group at >> http://groups.google.com/group/google-guice?hl=en. >> >> >> >> -- >> You received this message because you are subscribed to the Google Groups >> "google-guice" group. >> To post to this group, send email to [email protected]. >> To unsubscribe from this group, send email to >> [email protected]. >> For more options, visit this group at >> http://groups.google.com/group/google-guice?hl=en. >> > > > > -- > Jeff Vincent > [email protected] > See my LinkedIn profile at: > http://www.linkedin.com/in/rjeffreyvincent > I ♥ DropBox <http://db.tt/9O6LfBX> !! > > > -- > You received this message because you are subscribed to the Google Groups > "google-guice" group. > To post to this group, send email to [email protected]. > To unsubscribe from this group, send email to > [email protected]. > For more options, visit this group at > http://groups.google.com/group/google-guice?hl=en. > > > -- > You received this message because you are subscribed to the Google Groups > "google-guice" group. > To post to this group, send email to [email protected]. > To unsubscribe from this group, send email to > [email protected]. > For more options, visit this group at > http://groups.google.com/group/google-guice?hl=en. > -- Jeff Vincent [email protected] See my LinkedIn profile at: http://www.linkedin.com/in/rjeffreyvincent I ♥ DropBox <http://db.tt/9O6LfBX> !! -- You received this message because you are subscribed to the Google Groups "google-guice" group. To post to this group, send email to [email protected]. To unsubscribe from this group, send email to [email protected]. For more options, visit this group at http://groups.google.com/group/google-guice?hl=en.
