Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [sisu-users] Having trouble customizing one binding

On 1 Feb 2014, at 13:32, Benson Margulies <benson@xxxxxxxxxxxxx> wrote:

> I want to take detailed control of one binding.
> 
> In a module, I would write:
> 
> @Override
>            protected void configure()
>            {
> 
> bind(JsonFactory.class).annotatedWith(WsBusTicketCodecJsonFactory.class).to(SmileFactory.class);
>            }
> 
> If I make a module by extending AbstractModule with this code, I have
> a choice of two failure.
> 
> If I pass it to the injector ahead of WireModule, Guice complains that
> I have a duplicate binding for this binding.
> 
> If I pass it to the WireModule as the first parameter, I stuck on a
> different problem.
> 
> My module has several @Parameters-annotated methods. One is:
> 
> @Provides
>            @Parameters
>            WsBusConfig config() {
>                return new WsBusConfig(configFilePathname);
>            }

Hi Benson,

Just wondering why you use @Parameters here, because the original aim of this annotation was for binding (or injecting) configuration maps - or argument arrays, like the String[] args you get from main:

	@Inject
	@Parameters
	Map<?, ?> properties;

	@Inject
	@Parameters
	String[] args;

WireModule will merge multiple @Parameters bindings - for maps by merging the contents, for string arrays by concatenating them - so when you @Inject @Parameters Map/String[] you get the merged content:

	https://github.com/eclipse/sisu.inject/blob/master/org.eclipse.sisu.inject/src/org/eclipse/sisu/wire/ElementAnalyzer.java#L286

Because WsBusConfig is not a Map (or a String array), the ElementAnalyzer doesn’t know how to merge it and you get the “ Ignoring incompatible @Parameters binding” error message.

If you just want to @Inject your WsBusConfig (ie. not access it via the injected @Parameters Map) then you don’t need the @Parameters annotation, and removing this annotation will avoid the error.

But if you want to add this object as an element of the injected @Parameters Map instead of @Inject it directly then you could change the binding to:

	@Provides
	@Parameters
	Map<?,?> config() {
		return Collections.singletonMap(“some.key”, new WsBusConfig(configFilePathname));
	}

in which case it would then get merged in with the other @Parameters bindings.

PS. if you wanted to override elements, but didn’t want to put the overriding module inside WireModule then you could always use the Modules utility class from Guice:

	Modules.override( new WireModule( appModules ) ).with( overridingModule );

	http://google-guice.googlecode.com/git/javadoc/com/google/inject/util/Modules.html

We could also look at enhancing the ElementAnalyzer code above to treat non-map @Parameters bindings as a single key-value element - if this is what you expected it to do?

HTH

—
Cheers, Stuart

> When my module is outside of WireModule, all is well. When it's inside, I get
> 
> WARN: Sisu - Ignoring incompatible @Parameters binding:
> ProviderInstanceBinding[key=Key[type=com.basistech.wsbus.api.WsBusConfig,
> annotation=@org.eclipse.sisu.Parameters],
> source=com.basistech.wsbus.api.WsBusConfig
> com.basistech.wsbus.launcher.BusBootstrap$1.config(),
> scope=Scopes.NO_SCOPE, provider=@Provides
> com.basistech.wsbus.launcher.BusBootstrap$1.config(BusBootstrap.java:91)]
> 
> followed by a cascade of problem when that value is not in fact injected.
> _______________________________________________
> sisu-users mailing list
> sisu-users@xxxxxxxxxxx
> https://dev.eclipse.org/mailman/listinfo/sisu-users



Back to the top