As a side note, I have a number of applications without modules and a number of
libraries without modules as well. If I only have one implementation, I
generally use @ImplementedBy and reduce the module overhead. I've also found
that for libraries, using @ImplementedBy allows me to easily override (when
needed) the libraries default implementations inside an application that uses
the library.
-bp
On May 10, 2011, at 7:30 AM, David Hoffer wrote:
> I think I'm starting to 'get' it. Having just one Module with the
> 'configuration' sure is a lot simpler. In cases where I need to map to a
> specific implementation I used this approach:
>
> @Named("MyImpl")
> &
> bind(IMyInterface.class).annotatedWith(Names.named("MyImpl")).to(MyImpl.class);
>
> That seems pretty simple. I still think/hope the IDE can be smart and make
> sure that if I annotate with @Inject it will let me know and/or help me make
> sure all the parameters have been specified in the 'configuration'.
>
> Thanks for the explanations it really helps.
>
> -Dave
>
> On Tue, May 10, 2011 at 12:53 PM, Thomas Broyer <[email protected]> wrote:
>
>
> On Tuesday, May 10, 2011 10:47:51 AM UTC+2, dhoffer wrote:
> 1. Hum, perhaps I'm doing more work than I need to...perhaps just out
> of habit of previously using manual factories...but I think I got this
> from the Guice online docs. Here is what I do:
> Class A takes 4 parameters where all are interfaces of course. I add
> @Inject annotation to the constructor and optionally scope annotation
> to the class. I then create a module for this class that extends from
> AbstractModule that implements configure. In this method I create and
> maintain 4 bind() method calls that map the interface to the actual
> class. I assume the order of these bind statements much match the
> order in the constructor. Repeat for every IoC class in the
> application.
>
>
> You're doing it wrong. Modules are not factories, they're configuration.
>
> 1. the bind() order is not significant
> 2. using a module per "class requiring injection", you'll probably have
> duplicate bindings (classes Foo and Bar have a dependency on Baz, following
> your "rule", both FooModule and BarModule will
> bind(Baz.class).to(BazImpl.class), this will cause an error) or conflicts
> (FooModule binds Baz to BazImpl whereas BarModule binds Baz to AnotherBaz).
> If you want to make very fine-grained modules (really not sure that's a best
> practice), you'd rather have one per "interface some other class depends on"
> (i.e. interface Baz), but then you could in simple cases just as easily use
> an @ImplementedBy annotation.
>
> You have to think at a wider level than "one class", think "module" instead
> (I'm not talking about Guice modules, but application/feature modules).
> As an example, we have "api modules" (Maven modules, think of them as JARs or
> Eclipse projects if you prefer) comprised mostly of interfaces (we have one
> for managing entities in a simple datastore, one for indexing and searching
> them, one for validating them, one for dispatching events on a bus, etc.)
> Then we have "implementation modules" where the storage is implemented using
> Morphia/MongoDB, the indexing/searching backed by Solr, validation by
> Hibernate Validator and JSR303, and the event bus by HornetQ. In each of
> these "implementation modules", we have only a single Guice module that binds
> each interface from the "api module" to the concrete implementation of the
> "implementation module" (Indexer to a SolrIndexer backed by a SolrServer,
> EntityManager to a MorphiaEntityManager backed by a Morphia Datastore, etc.)
> Then we have several applications (a webapp and a bunch or "executables")
> that make use of these modules, each one creates a Guice Injector installing
> the required modules; the code only depends on the interfaces from the "api
> modules" though.
>
> I guess I just don't get your comment 'bind()ings are about *what* to
> inject, not *where* to inject them.'
>
> It's not where I use an EntityManager that I decide which one I'll use (i.e.
> it's not in a FooModule along side a Foo class with an "@Inject EntityManager
> em" field, that I bind(EntityManager.class)), it's at the application level
> that I instead decide which modules I'll install, those modules providing the
> bindings (some classes need an EntityManager, and the bootstrap code for the
> app chooses to use the MorphiaStorageModule that binds EntityManager to an
> implementation based on Morphia).
>
> It seems you need some way to
> specify the *where* too.
>
> If you need several implementations of a given interface to be injected at
> different places in your app, then you have to annotate those places. For
> instance, we have several Solr indexes –Solr cores–, one used for "suggest as
> you type" and one for "advanced search", because they need different Solr
> configurations. In our app, both are accessed through a Searcher interface.
> We created a "binding annotation" (or you could use @Named if your prefer) so
> that anywhere I need a "searcher for suggest-as-you-type" I declare a
> "@ForIndex(Index.Suggest) Searcher" field or constructor argument, and
> anywhere I need a "searcher for advanced search" I declare a
> "@ForIndex(Index.AdvancedSearch) Searcher" field or constructor argument.
> In the SolrSearchModule, we then have two bindings (in the form of @Provides
> methods):
> @Provides @ForIndex(Index.Suggest) Searcher provideSuggestSearcher(...other
> dependencies...) { ... }
> @Provides @ForIndex(Index.AdvancedSearch) Searcher
> provideAdvancedSearchSearcher(...other dependencies...) { ... }
>
> See, it's about *what* you depend on/inject, not about *where* you inject it.
>
> --
> 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.
--
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.