I encountered the same problem with Tapestry IOC 5.4beta. registry.getService() doesn't respect service overrides. Is this a designed feature or a bug?
2013-12-13 2:20 GMT+08:00 Adriaan Joubert <adriaan...@gmail.com>: > Hi, > > we love the IOC and are using it in our standalone Java applications as > well as our web applications. I do however have a problem with overriding > services. When using the suggestions from the cookbook ( > http://tapestry.apache.org/ioc-cookbook-overriding-ioc-services.html) to > override a service, I find that the the service is not overridden using the > getService method on the registry. I've been through the IOC code and I > could see that the ServiceOverride service is called from the > MasterObjectProvider but not from elsewhere. Based on that I tried to use > the getObject() method on the registry, and that does indeed give me the > overridden service. I found this behaviour rather unexpected, so I assume > I'm missing something. > > We use getService in a lot of places, and it would be quite a change to > have to use getObject everywhere instead. As we have markers on our > services, the getService interface is also easier to use. > > So my question is: why the difference between getService and getObject? And > which one should we be using? > > Please see below a junit test that demonstrates this behaviour. I'd really > appreciate any enlightenment! > > Cheers, > > Adriaan > > > import static org.junit.Assert.assertEquals; > > import org.apache.tapestry5.ioc.MappedConfiguration; > import org.apache.tapestry5.ioc.Registry; > import org.apache.tapestry5.ioc.RegistryBuilder; > import org.apache.tapestry5.ioc.ServiceBinder; > import org.apache.tapestry5.ioc.annotations.Contribute; > import org.apache.tapestry5.ioc.annotations.SubModule; > import org.apache.tapestry5.ioc.internal.NullAnnotationProvider; > import org.apache.tapestry5.ioc.services.ServiceOverride; > import org.junit.Test; > > public class IocTest { > > public interface Simple { > String getString(); > } > > public static class SimpleImpl implements Simple { > @Override > public String getString() { > return "foo"; > } > } > > public static class SimpleOverrideImpl implements Simple { > @Override > public String getString() { > return "bar"; > } > } > > public static class DefaultAppModule { > public static void bind(ServiceBinder binder) { > binder.bind(Simple.class, SimpleImpl.class); > } > } > > @SubModule(DefaultAppModule.class) > public static class OverrideAppModule { > @Contribute(ServiceOverride.class) > public static void testOverrides( > MappedConfiguration<Class<?>, Object> configuration) { > configuration.addInstance(Simple.class, > SimpleOverrideImpl.class); > } > } > > @Test > public void testWithoutOverride() { > RegistryBuilder builder = new RegistryBuilder(); > builder.add(DefaultAppModule.class); > Registry registry = builder.build(); > registry.performRegistryStartup(); > Simple simple = registry.getService(Simple.class); > assertEquals("foo", simple.getString()); > registry.cleanupThread(); > registry.shutdown(); > } > > @Test > public void testWithOverride() { > RegistryBuilder builder = new RegistryBuilder(); > builder.add(OverrideAppModule.class); > Registry registry = builder.build(); > registry.performRegistryStartup(); > Simple simple = registry.getService(Simple.class); > // !FAILS! > assertEquals("bar", simple.getString()); > registry.cleanupThread(); > registry.shutdown(); > } > > @Test > public void testWithOverrideAndObjectProvider() { > RegistryBuilder builder = new RegistryBuilder(); > builder.add(OverrideAppModule.class); > Registry registry = builder.build(); > registry.performRegistryStartup(); > Simple simple = registry.getObject(Simple.class, > new NullAnnotationProvider()); > // SUCCEEDS > assertEquals("bar", simple.getString()); > registry.cleanupThread(); > registry.shutdown(); > } > > } >