Cool. Thanks. I was looking for the documentation but did not found the
correct hint. I only remembered from the code reading.

Do I also remember correctly that tapestry just do not throw an exception
when there are two possible matches but use the nearest matching one
(preferable that what is bind) and throw an exception only if I bind an
interface that was already bound before? I thought I also saw an exception
mechanism if there are two potential matches but I also have a strong
feeling it was the other way round... .

PS: I was not able to test it myself but I did some paper work and planing
ahead, that's why I asked.


2013/10/19 Thiago H. de Paula Figueiredo <[email protected]>

> I was not mistaken! I never make mistakes! Except when I do! :-D
>
> Now I've wrote a test and it passes. Tapestry-IoC already does what Martin
> is asking, second time today, hehehe. Always did. When you ask for an
> injection without specifying a service id, Tapestry-IoC searches all
> services for one that matches (implements the requested interface or is the
> same type as the requested class or a subclass of the requested class).
> That's also exactly why you have marker annotations: to choose just one
> service when more than one matches and you don't want or you can't request
> an specific service id.
>
> Here's the code:
>
> public interface ServiceB {
>      void printB();
> }
>
> public interface ServiceA extends ServiceB{
>      void printA();
> }
>
> public class TestModule {
>      public static void bind(ServiceBinder binder) {
>          binder.bind(ServiceA.class, ServiceImpl.class);
>      }
> }
>
> public class TestSuite {
>
>      public static void main(String[] args) {
>          new TestSuite().test();
>      }
>
>      @Test
>      public void test() {
>             RegistryBuilder builder = new RegistryBuilder();
>             builder.add(TestModule.class);
>             Registry registry = builder.build();
>             ServiceA serviceA = registry.getService(ServiceA.class);
>             ServiceB serviceB = registry.getService(ServiceB.class);
>             System.out.println(serviceA == serviceB);
>             assert serviceA == serviceB;
>       }
>
> }
>
>
> On Sat, Oct 19, 2013 at 3:02 PM, Thiago H. de Paula Figueiredo <
> [email protected]> wrote:
>
> >
> > Unless I'm mistaken (I cannot test this now,) if you have ServiceA
> extends
> > ServiceB and ServiceImpl implements ServiceA, if you do a
> > binder.bind(ServiceA.class, ServiceImpl.class) and @Inject ServiceA
> > serviceA and @Inject ServiceB serviceB, it will work (serviceA ==
> > serviceB). Have you tested this? If not, please do.
> >
> > Anyway, this is for sure: you can declare any service with any scope
> > (singleton or perthread) with both binder.bind() and builder methods. To
> > declare a perthread service with binder.bind(), just call
> > binder.bind(...).scope(ScopeConstants.PERTHREAD).
> >
> >
> > On Sat, Oct 19, 2013 at 6:02 AM, Martin Kersten <
> > [email protected]> wrote:
> >
> >> Hi there,
> >>
> >>    I just wonder how I can simply define a service applying to multiple
> >> Service interfaces at the same time.
> >>
> >> I know there was this auto discovery feature of the IOC.
> >>
> >> Lets say we have this hierachy: SerivceImpl -> ServiceA -> ServiceB
> >>
> >> I want ServiceImpl to be registered for ServiceA and ServiceB.
> >>
> >> and that registry.getService(ServiceA) == registry.getService(ServiceB).
> >>
> >> Is there any way (beside registering a builder instead)? The service
> would
> >> be
> >> PerThread so I can do this with a builder but I would love to have
> >> something
> >> different.
> >>
> >>
> >>
> >> Cheers,
> >>
> >> Martin (Kersten),
> >> Germany
> >>
> >
> >
> >
> > --
> > Thiago
> >
>
>
>
> --
> Thiago
>

Reply via email to