Well I might have misunderstood the user guide here but the following is
true by checking the code:

1. The first (!) encountered constructor with a given annotation is choosen.
     Since the JVM makes no statement about the ordering of methods (and
constructors) in the class definition after the compile process,
     we have to rephrase the userguide statements to: A random method /
constructor being annotated with @Inject is choosen.

    private static <T extends Annotation> Constructor
findConstructorByAnnotation(Constructor[] constructors,

Class<T> annotationClass)
    {
        for (Constructor c : constructors)
        {
            if (c.getAnnotation(annotationClass) != null)
                return c;
        }

        return null;
    }


2. The method with the most parameters win. There is no distinction between
those parameters that can be injected and those who cant.

    So we have to rephrase the inspect parameters and the method with the
most parameters that can (!) be injected by the IOC wins to
    simply the constructor with the most parameters win regardless the
injectability. I dreamed about having more then one constructor
    and just configure different services applying to different scenarios
(like using a certain library instead of providing a abstraction on top),
    but nope I have to deal with it myself.

    Here is the code part of selecting note the pragmatism by using sort
instead of a iterator with compare. I like it (really, straight forward
    and fast enough).

     // Choose a constructor with the most parameters.
    Comparator<Constructor> comparator = new Comparator<Constructor>() {
            public int compare(Constructor o1, Constructor o2) {
                return o2.getParameterTypes().length -
o1.getParameterTypes().length;
            }
        };
        Arrays.sort(constructors, comparator);
        return constructors[0];

I was looking for a way to ask the registry whether a service object for a
given class exists or can be created (there is no way to
ask if a certain service is already instanciated or at least proxiated). No
way to do that.

3. Annotating a parameter inside a constructor to mark it as Injectable is
not the same as putting a @Inject on top of the
    constructor itself. Dont ask... just listen :(.


So here is what I do now, I just iterate over candidate methods and if it
finds more than one candidate it just spills out a certain
exception.

Invoker.on(target).call(methodName).with([informalName], [Type,]
value).annotatedWith(annotations...).invoke();

The with part fills in a parameter if the given type is spotted in the
parameter and the parameter does not have a inject
annotation. The order of with is valued. The informalName is just ignored
it is for documentation only to increase
readability.

I was eager to implement a overwrite where you can specify a certain
service interface being not injected but used
as provided. This way I would be able to pass a certain dependency to the
target but I dont have a concrete use
case so this would be overengineering, so its left out.

So invoker.on(myTask).call("process").with("timeout", 60).with("delay",
15).invoke();
This will make it possible to have a method, without knowing it.

MyTask {
     boolean process(@Inject service, int timeout, int delay) {
     }
}

I also added Invoker.newInstance(class) which just calls autobuild or
Invoker.getService(class) which asks the registry.

Thats it. Simple straight forward and does the job. And I only use it for
some spare situations where
I have to or just dont know what the given implementation will look like
since I will have processing tasks
that do not use the database at all etc. So I dont care for if(task
instanceof foo) anymore and I have
optional before and after methods.

Invoker.on(myTask).callAnyMethod().annotatedWith(Setup.class).invokeIfExists();

And yes this method calls really any method, not just the first found.



Cheers,

Martin (Kersten)


PS: @Thiago Pesti comes from pest and marks something as being sort of a
distraction or an annoyance.



2013/9/23 Thiago H de Paula Figueiredo <thiag...@gmail.com>

> On Mon, 23 Sep 2013 17:07:54 -0300, Martin Kersten <
> martin.kersten...@gmail.com> wrote:
>
>  Yeah thats what I was thinking about exactly. This way I can get rid of
>> the pesti constructor injection.
>>
>
> Pesti? What is that? If you were talking Brazilian Portuguese, I'd knew. :D
>
>
>  Does anyone knows if the autobuild / build process fails if a property
>> annotated @inject could not be injected? Kind of should be but I am quite
>> not sure... .
>>
>
> Try it and tell us what happened. ;)
>
>
> --
> Thiago H. de Paula Figueiredo
>
> ------------------------------**------------------------------**---------
> To unsubscribe, e-mail: 
> users-unsubscribe@tapestry.**apache.org<users-unsubscr...@tapestry.apache.org>
> For additional commands, e-mail: users-h...@tapestry.apache.org
>
>

Reply via email to