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 !! 
>>>  
>>> 
>>> -- 
>>> 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 !! 
>> 
>> 
>> -- 
>> 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 !! 
> 
> 
> -- 
> 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.

Reply via email to