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 <[email protected]>
>>> 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 [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/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 [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/a8d21f0a-798a-4a72-a2fc-4764a8177ec4%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.