Sam, Providers already get extra information since you can inject dependencies in the Provider, it is not exposed in the interface - which is great.
The 1:1 rule is about the binding to a type of provider, but once you have a Provider then there is no guarantee that it will always return the same instance. Certainly if you combine it with scoped bindings. What I need is a n:1 binding without needing to write out n lines of bind operation - as is the case right now. something like: bind(Matchers.subTypeOfAlert.class)).toProvider( AlertProvider.class ); or bind(Types.subtypeOf(Alert.class)).toProvider(AlertProvider.class); where the AlertProvider has a way to know the key it is actually trying to resolve when a dependency is resolved. Right now that requires the use of internal code, as demonstrated by Mr Rusakov, But why not support @Inject @BindKey Key<?> to avoid making changes to the Provider interface ? This kind of binding is not something you need very often but for certain kind of situations it is a nice solution. It certainly beats the solution of repeating the bind for every possible subtype with the same target type or to inject a custom made factory everywhere I need to be able to send alerts. On Thu, May 7, 2015 at 3:00 PM, Sam Berlin <[email protected]> wrote: > Providers are intended to be 1:1 with what they're providing, so there's > no information to supply. > > sam > > On Thu, May 7, 2015 at 5:10 AM David <[email protected]> wrote: > >> I only realize this now, I need to put my code in the >> com.google.inject.internal package. >> Does Guice not offer a way to get info about the type a provider is >> supposed to be creating (the type on which the ProvidedBy is put) ? >> >> On Mon, May 4, 2015 at 9:28 PM, Vyacheslav Rusakov <[email protected]> >> wrote: >> >>> I faced almost the same problem: I was writing a kind of spring-data >>> repositories, where queries supposed to be defined with annotations on >>> interface methods and in runtime proxies should be created. >>> >>> The solution I found is a bit hacky: I used @ProvidedBy with generic >>> provider, which could simply generate proxy class from provided interface. >>> It was important for me to generate proxy class, because guice aop >>> doesn't work for binded instances, and I was going to implement all >>> annotations on interfaces with aop (+reuse @Transactional logic). >>> >>> Detecting requested type in provider is possible, using internal guice >>> api: >>> https://github.com/xvik/guice-ext-annotations/blob/master/src/main/java/com/google/inject/internal/DynamicClassProvider.java >>> As a result, I can now simply annotate interface (or abstract class) >>> with @ProvidedBy(DynamicClassProvider.class) and it will generate required >>> proxy (using javassist) in runtime (during jit resolution) >>> >>> https://github.com/xvik/guice-ext-annotations#abstract-types-support >>> >>> I think, it perfectly fits for your case. You will just need to >>> implement @Alert annotation support with guice AOP. >>> Or you could write your own hacky provider the same way :) >>> >>> понедельник, 4 мая 2015 г., 20:40:09 UTC+6 пользователь Sam Berlin >>> написал: >>>> >>>> The reason for the lack of feature is because it would make code using >>>> it harder to understand. There's a 1:1 ratio right now with bind statements >>>> (or @Provides methods) and injectable types right now. That's relaxed to >>>> 0:1 for just-in-time bindings (so if you don't see a bind statement for a >>>> type, it must be a just-in-time binding). Allowing 1:many would make >>>> understanding what is being injected much harder. Guice is already >>>> confusing enough... no need to add more features that complicate the basic >>>> injection model even more. >>>> >>>> TypeListeners are somewhat different because they require using >>>> different annotations. The rules for @Inject stay the same, but Guice can >>>> be leveraged to supply data to other annotations. >>>> >>>> sam >>>> >>>> On Mon, May 4, 2015, 9:54 AM David <[email protected]> wrote: >>>> >>>>> Thanks for the link, I did not find that one before. >>>>> >>>>> From what I read in the bug report they need a compelling use case. >>>>> Assuming that there is no need for this because after 4 years of >>>>> discussions nobody joined the discussions is an easy answer. Most people >>>>> just don't bother joining in the discussion for various reasons. >>>>> >>>>> For me my example is a compelling case. Requiring duplication of >>>>> bindings (in my case 100+) is very tedious. Injecting a Factory instead is >>>>> also no so nice (but workable at this moment). And my case does not ask >>>>> for >>>>> a complete freedom, I need to register with some base class or matcher >>>>> that >>>>> would allow me to construct the required binding. >>>>> >>>>> How did the Custom Injections get accepted in Guice ? It is a very >>>>> limited scope and it actually is a bit of an anti pattern in that the >>>>> class >>>>> actually knows that the fields will be injected by some custom injector. >>>>> You could argue the same about assisted injects - although those have a >>>>> bit >>>>> more broader use. >>>>> >>>>> Various other projects like Jukito/gwtmockito offer a possibility to >>>>> "auto-mock" undefined bindings. So those could actually also use such an >>>>> extension mechanism. >>>>> >>>>> >>>>> On Mon, May 4, 2015 at 3:07 PM, Sam Berlin <[email protected]> wrote: >>>>> >>>>>> The lack of this feature is by design. See the discussion @ >>>>>> https://github.com/google/guice/issues/49. >>>>>> >>>>>> sam >>>>>> >>>>>> On Mon, May 4, 2015 at 9:05 AM David Nouls <[email protected]> >>>>>> wrote: >>>>>> >>>>>>> In my applications I need to be able to have some influence on how >>>>>>> Guice searches for bindings. >>>>>>> >>>>>>> The problem that I am trying to solve: >>>>>>> I have a system to generate alerts. The code that generates these >>>>>>> alerts need to declare an interface that extends a marker interface and >>>>>>> all >>>>>>> the methods use annotations to declare the actual text with placeholders >>>>>>> for the parameters. The actual implementation of this interface is done >>>>>>> by >>>>>>> one single dynamic proxy implementation. For example >>>>>>> >>>>>>> public interface Alerts {} >>>>>>> >>>>>>> public interface TestAlerts extends Alerts { >>>>>>> @Alert( "Hello {0}" ) >>>>>>> public void hello( String text ); >>>>>>> } >>>>>>> >>>>>>> In the application code I inject the TestAlerts and use it like a >>>>>>> regular object. The advantage of this approach is that I get nice >>>>>>> compiler >>>>>>> warnings whenever a change to parameters is done, or a message has been >>>>>>> removed from the Alerts interface. I can also do decent formatting and >>>>>>> type >>>>>>> conversion without complicating the code that uses my Alert system. >>>>>>> >>>>>>> Right now I have 2 possibilities in Guice: >>>>>>> 1) bind all interfaces that extends Alerts with a provider that can >>>>>>> create the dynamic proxy specific to the requested interface. >>>>>>> 2) Inject an AlertFactory that has a <V extends Alerts> V >>>>>>> create(Class<V> typeClass ) method. >>>>>>> >>>>>>> Solution 1 becomes tedious because in my case we are talking about >>>>>>> hundreds of injections (large enterprise system with lots of independent >>>>>>> components). >>>>>>> Solution 2 exposes the fact that you need to use a factory to send a >>>>>>> simple alert. Somehow this feels a bit like an anti-pattern because I am >>>>>>> not interested in how to create these objects, I just want on instance >>>>>>> by >>>>>>> magic as I am used in injection frameworks. >>>>>>> >>>>>>> I've read and tried the documentation section on custom Custom >>>>>>> Injections <https://github.com/google/guice/wiki/CustomInjections>. >>>>>>> But is very incomplete, since it only allows injection into members, not >>>>>>> constructors and it requires you to use a custom annotation, not @Inject >>>>>>> which basically already requires the class to know that what he is >>>>>>> depending on needs some kind of extension - which sounds like an >>>>>>> anti-pattern to me. >>>>>>> >>>>>>> I would like to be able to somehow register that Guice should use a >>>>>>> Factory that takes an argument of type class<V extends Alerts>. Or >>>>>>> someway >>>>>>> to register a TypeListener that gets invoked when some unknown type is >>>>>>> requested for injection. >>>>>>> >>>>>>> Any ideas how to do this ? Any chance of getting some extra >>>>>>> extension point in Guice to go a step further with extensions ? >>>>>>> >>>>>>> >>>>>>> -- >>>>>>> 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 [email protected]. >>>>>>> To post to this group, send email to [email protected]. >>>>>>> Visit this group at http://groups.google.com/group/google-guice. >>>>>>> To view this discussion on the web visit >>>>>>> https://groups.google.com/d/msgid/google-guice/d3e36ad3-c49b-4cbb-9640-6527877491bd%40googlegroups.com >>>>>>> <https://groups.google.com/d/msgid/google-guice/d3e36ad3-c49b-4cbb-9640-6527877491bd%40googlegroups.com?utm_medium=email&utm_source=footer> >>>>>>> . >>>>>>> For more options, visit https://groups.google.com/d/optout. >>>>>>> >>>>>> -- >>>>>> 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 [email protected]. >>>>>> To post to this group, send email to [email protected]. >>>>>> Visit this group at http://groups.google.com/group/google-guice. >>>>>> >>>>> To view this discussion on the web visit >>>>>> https://groups.google.com/d/msgid/google-guice/CAJEBNUeK-Ls%3DXZgP-h3gvg0KCGEuK%3Dp4ZTCtKBrThNHprGUT8w%40mail.gmail.com >>>>>> <https://groups.google.com/d/msgid/google-guice/CAJEBNUeK-Ls%3DXZgP-h3gvg0KCGEuK%3Dp4ZTCtKBrThNHprGUT8w%40mail.gmail.com?utm_medium=email&utm_source=footer> >>>>>> . >>>>> >>>>> >>>>>> For more options, visit https://groups.google.com/d/optout. >>>>>> >>>>> -- >>>>> 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 [email protected]. >>>>> To post to this group, send email to [email protected]. >>>>> Visit this group at http://groups.google.com/group/google-guice. >>>>> To view this discussion on the web visit >>>>> https://groups.google.com/d/msgid/google-guice/CABrJHW1Et3stENU-zq1CW7wEW1WE9WcxFbeBwB2dbxj3jOzTOA%40mail.gmail.com >>>>> <https://groups.google.com/d/msgid/google-guice/CABrJHW1Et3stENU-zq1CW7wEW1WE9WcxFbeBwB2dbxj3jOzTOA%40mail.gmail.com?utm_medium=email&utm_source=footer> >>>>> . >>>>> For more options, visit https://groups.google.com/d/optout. >>>>> >>>> -- >>> 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 [email protected]. >>> To post to this group, send email to [email protected]. >>> Visit this group at http://groups.google.com/group/google-guice. >>> To view this discussion on the web visit >>> https://groups.google.com/d/msgid/google-guice/96cbe006-2f8d-4855-ad96-a50c3f69dac7%40googlegroups.com >>> <https://groups.google.com/d/msgid/google-guice/96cbe006-2f8d-4855-ad96-a50c3f69dac7%40googlegroups.com?utm_medium=email&utm_source=footer> >>> . >>> >>> For more options, visit https://groups.google.com/d/optout. >>> >> -- >> 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 [email protected]. >> To post to this group, send email to [email protected]. >> Visit this group at http://groups.google.com/group/google-guice. >> To view this discussion on the web visit >> https://groups.google.com/d/msgid/google-guice/CABrJHW2r5_0Hb%3DZERGPqsMYFDjsov4xpF%3DWpoyeXBESjYuT7gg%40mail.gmail.com >> <https://groups.google.com/d/msgid/google-guice/CABrJHW2r5_0Hb%3DZERGPqsMYFDjsov4xpF%3DWpoyeXBESjYuT7gg%40mail.gmail.com?utm_medium=email&utm_source=footer> >> . >> For more options, visit https://groups.google.com/d/optout. >> > -- > 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 [email protected]. > To post to this group, send email to [email protected]. > Visit this group at http://groups.google.com/group/google-guice. > To view this discussion on the web visit > https://groups.google.com/d/msgid/google-guice/CAJEBNUeZVmS%3DtJtbiMfMTUKmiTw-urF9hZj-EYu33YRhfUnOOA%40mail.gmail.com > <https://groups.google.com/d/msgid/google-guice/CAJEBNUeZVmS%3DtJtbiMfMTUKmiTw-urF9hZj-EYu33YRhfUnOOA%40mail.gmail.com?utm_medium=email&utm_source=footer> > . > > For more options, visit https://groups.google.com/d/optout. > -- 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 [email protected]. To post to this group, send email to [email protected]. Visit this group at http://groups.google.com/group/google-guice. To view this discussion on the web visit https://groups.google.com/d/msgid/google-guice/CABrJHW0-6F%3D_a3XGybD4AxCNWBD8G9F5%3Dcicd6xXwBdPwWDqGw%40mail.gmail.com. For more options, visit https://groups.google.com/d/optout.
