hi,
your question is a bit long and i'm not sure if i fully understand the
problem, but let me share some thoughts:
1. I wouldn't create 2 providers just for the two properties. Technically
you can but it makes the design more complicated.
you could either just load the properties in the configure() method that
i suppose is the default method. The code is something like:
Properties prop1 = /** load it */
bind(Properties.class).annotatedWith(Names.named("conf")).toInstance(prop1);
Another way I prefer is to use provider annotation in the Module class,
the code is something like:
public class PropertiesModule extends AbstractModule{
protected void configure() {} //you could just leave it blank
@Provides @Named("conf") Properties getConf(@Named("base") File
basePath){ // basePath is just an example for you. you could just use no
parameter
return null;
}
}
2. Guice is an DI framework so it is designed to create and manage the
instance for you, but technically, there are ways that allow you to create
instance elsewhere and pass in Guice. e.g. you could add member variables to
your Module class, e.g.
public class PropertiesModule extends AbstractModule{
final Properties lang; //final is optional
final Properties conf;
public PropertiesModule(Properties lang, Properties conf){
this.lang=lang; this.conf = conf;
}
protected void configure(){
bind(Properties.class).annotatedWith(Names.named("conf")).toInstance(conf);
//will throw NPE if conf is null
//TODO: do the same for lang
}
}
3. i don't know TestNG but use JUnit intensively. The concept should be
similar. I wouldn't use ServiceLocator to load all module in unit test. The
purpose of unit test is to isolate units for testing and the beauty of Guice
is that it allows us to programmatically prepare the minimum number of
modules for testing. Another practical reason is it probably will take too
long to load all modules for running every unit test case.
an example of junit test class that load a single module is as follows:
public class PropertiesTest{
static Injector g = Guice.createInjector( new PropertiesModule() );
@Test public void testSomething(){
Properties conf = g.getInstance( Key.get( Properties.class,
Names.named("conf"))
assertNotNull(conf);
}
}
disclaimer: all code above are written in email client but not IDE and they
may not work. they are just for illustrating the concept.
just my 2 cents. hope they help.
regards,
mingfai
On Fri, Oct 28, 2011 at 4:12 AM, Jeff <[email protected]> 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?
>
> 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.