Oh and I should mention that I haven't got any static code analysis tools along these lines.
All I'm suggesting is that there are other use-cases for this besides loading images, DB connections come to mind although there you might want all the typical try-finally ritual typically associated with db connections. In our particular case we have a graph that we configure. If I could specify paths into that graph for injection it would save me a lot of test setup headache. Consider: GraphAnalyzingThing(Graph graph){ nodesOfInterest = graph.getRoot().resolve("A").flatMap(node -> node. resovle("B")); } vs GraphAnalyzingThing(@Named("/ANodes/BNodes") List<Node> nodes){ thingsOfInterest = nodes; } //with a provider: @Provides List<Node> getNodesForPath(Graph graph, Named path){ List<String> traversal = path.split("/"); List<node> nodes = { graph.getRoot() }; for(String pathSection : traversal){ nodes = nodes.flatMap(node -> node.resolve(pathSection)); } return nodes; } The latter is a lot easier to create from a testing environment, and it allows us to centralize some of that traversal logic. On Sunday, October 25, 2015 at 10:26:39 AM UTC-7, Tim Peierls wrote: > > On Saturday, October 24, 2015 at 11:43:59 PM UTC-4, Geoff Groos wrote: >> >> the benefit is fairly straight forward: you don't have to inject a >> `ResourceEnvironment` instance, and we lose a little bit of code >> duplication by centralizing the place where the resource-loading flow >> starts and finishes. >> > > I should have used a less "heavy" sounding term than ResourceEnvironment. > How about an interface, ProviderOfNamed<T>? Here's my rewrite of your > example again, but with the different name: > > https://gist.github.com/Tembrel/5662bdecc0d3557debc1 > > This is almost identical to your example, but instead of injecting > *@Named("...") > Image* and relying on what would be a new feature, it injects > *ProviderOfNamed<T>*, and the desired image is obtained through a call to > *provider.get(name)*. The *@Provides* method is essentially the same. > > > >> That same object is the one that offers the ability to load native code >> through JNA, so its a fairly scary object. If it becomes too scary we of >> course have the option of hiving that complexity off into a new class, a >> `NativeResourceLoader` and the regular `ResourceEnvironment`, but I just >> thought the ability to push the actual loading of resources out of a >> constructor and into guice would be handy. >> > > I don't think you want to describe it as pushing logic *into *Guice. > Better to say that you want to decouple the actual (and common) machinery > of loading a resource based on a string name from the places where those > resources are used. Both of our examples accomplish that end, but mine does > it without needing a new and potentially very complicated enhancement to > Guice. > > > >> And I would think that this would be a handy feature for deep >> configuration: if the type isn't a uniquely identifying feature, the >> ability to make runtime decisions about static configuration through >> annotations seems really handy and not likely to break much (whose going to >> be binding instances of annotations to things?) In my case, a static image >> resource can be identified by a path similar to >> "/com/ourcompany/whatever/someimage.png". >> > > I'm not following this. Are you saying that you'd like to do static code > analysis so you can do build-time initialization of configuration data > structures? I can sort of see an application for this, but I don't think > it's worth introducing a new Guice feature for it. I would do something > like this: > > > class SomeService { > > static final String IMG_NAME = "/com/whatever/..."; > > @Preconfigured(IMG_NAME) final Image img; > > @Inject SomeService(ProviderOfNamed<Image> imgProvider) { > img = imgProvider.get(IMG_NAME); > } > } > > > Then a static analysis tool could go through a jar and know from which > things need to be "preconfigured", whatever that means. > > > On Sunday, October 18, 2015 at 7:30:06 AM UTC-7, Tim Peierls wrote: >>> >>> What benefits would this have over what I imagine your colleagues are >>> doing? >>> >>> public interface ResourceEnvironment { >>> Image getImage(String name); >>> // ... other resource-providing methods ... >>> } >>> >>> public class SomeService { >>> >>> private final Image image; >>> >>> @Inject public SomeService(ResourceEnvironment env){ >>> image = env.getImage("/com/mycompany/myasset.png"); >>> } >>> >>> //big complex methods doing big complex method things. >>> } >>> >>> //with a module containing >>> public class ModuleToDoThat implements Module{ >>> public void configure(){ >>> //... >>> } >>> >>> @Provides ResourceEnvironment getResourceEnvironment() { >>> return new ResourceEnvironment() { >>> @Override public getImage(String name) { >>> return toImage(getClassLoader().getResource(name)); >>> } >>> Image toImage(URL url) { ... } >>> // ... implement other resource-providing methods ... >>> }; >>> } >>> } >>> >>> >>> On Sun, Oct 18, 2015 at 1:18 AM, Geoff Groos <geoff...@empowerops.com> >>> wrote: >>> >>>> Hey guys, >>>> >>>> So it's occurred to me that a number of classes in our codebase are >>>> injecting a so called 'ResourceEnvironment' so they can use it to retrieve >>>> a static image from whiten our deployed jar. This got me wondering if I >>>> could achieve something as slick as injecting the image directly with >>>> guice: >>>> >>>> public class SomeService{ >>>> >>>> private final Image image; >>>> >>>> @Inject >>>> public SomeService(@Named("/com/mycompany/myasset.png") myAssetImage >>>> ){ >>>> image = myAssetImage; >>>> } >>>> >>>> //big complex methods doing big complex method things. >>>> } >>>> >>>> //with a module containing >>>> public class ModuleToDoThat implements Module{ >>>> public void configure(){ >>>> //... >>>> } >>>> >>>> @Provides Image getImageWithName(Named name){ >>>> return getClassLoader().getResource(name.value()); >>>> } >>>> } >>>> >>>> This would actually reduce a fair bit of code on our code base; using >>>> annotations to pass meta-data about the specific instance that's needed >>>> *at >>>> runtime* would be a really cool feather for guice's cap. >>>> >>>> AFAIK the feature I'm requesting is binding annotations to be >>>> whitelisted (along with the calling Injector) as things that you can >>>> request without providing an explicit configuration path for them. A >>>> little >>>> less obtusely: with the injector you don't need to tell guice how to >>>> provide a provider method with an injector, it just assumes the injector >>>> you're looking for is the one doing the provide-ing. I would ask that >>>> binding annotations be given the same 'scope', such that any binding >>>> annotations used would be automatically wired to that provider method (and >>>> if they don't exist, the provider methods eligibility for provision >>>> removed). >>>> >>>> Needless to say this is a fair bit of rope to hang yourself with, in >>>> the event that you need to start passing more information than is >>>> available >>>> at annotation-writing-time, some developers (myself included) might try to >>>> ham-fist some things into static scope so that they can be used by the >>>> annotation. That said, I think the benefit outweighs the cost; it would be >>>> really slick and cut 50 lines of cruft off my codebase. >>>> >>>> I'm *fairly* certain I could hack something together with provision >>>> listener and a stack (probably static), but rather than go down that road >>>> I >>>> figured I should post this as a request-for-help and/or a feature request >>>> here first. >>>> >>>> Is there a way to do this without using the SPI that would give me the >>>> same effect? If I was to try to do it myself with a stack and a provision >>>> listener, would it be as hard as I think it is? Is this something I should >>>> request a little more formally (by creating a github issue)? >>>> >>>> cheers, >>>> >>>> -Geoff >>>> >>>> >>>> -- >>>> 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 google-guice...@googlegroups.com. >>>> To post to this group, send email to google...@googlegroups.com. >>>> 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/882e5b98-a32a-4f5a-a47f-02b4fc8d117b%40googlegroups.com >>>> >>>> <https://groups.google.com/d/msgid/google-guice/882e5b98-a32a-4f5a-a47f-02b4fc8d117b%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 google-guice+unsubscr...@googlegroups.com. To post to this group, send email to google-guice@googlegroups.com. 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/a8d21f0a-798a-4a72-a2fc-4764a8177ec4%40googlegroups.com. For more options, visit https://groups.google.com/d/optout.