Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [sisu-users] Question about @Priority

That would be one option, but there are other solutions such as checking bound provider types when we're ranking the bindings and not just peeking at the implementation type.

On Wed, 30 Oct 2019 at 13:48, Giamma <gm.romanato@xxxxxxxxx> wrote:
Thank you.

Out of curiosity, the fix will consist in changing QualifiedTypeBinder.bindProviderType so that when the provider type is annotated Priority, a highPriorityBinder is created as in the workaround and later used in place of the member binder to bind the provider?



On Wed, Oct 30, 2019 at 1:59 PM Stuart McCulloch <mcculls@xxxxxxxxx> wrote:
Thanks, I'll make sure that gets fixed.

In the meantime you can use the following named module workaround to bind your provider at a higher priority:

  import static org.eclipse.sisu.inject.Sources.prioritize;

  @Named
  public static class HighPriorityProviderModule
      extends AbstractModule
  {
    @Override
    protected void configure() {
      Binder highPriorityBinder = binder().withSource(prioritize(Integer.MAX_VALUE));
      highPriorityBinder
          .bind(Foo.class)
          .annotatedWith(Names.named("HighPriorityExample"))
          .toProvider(FooProvider.class);
    }
  }

Anything bound using the custom source will have the assigned priority, which is useful when you want to install everything in a third-party module at a higher priority.

On Mon, 28 Oct 2019 at 15:13, Giamma <gm.romanato@xxxxxxxxx> wrote:
Hi Stuart,

as usual thank you for the quick response.

Gian Maria.

On Mon, Oct 28, 2019 at 3:04 PM Stuart McCulloch <mcculls@xxxxxxxxx> wrote:
Hi Gian,

Yes at the moment @Priority has no affect on providers (because the code that looks for priority information cannot "see" through the provider indirection)

There are a couple of ways you can workaround this that are cleaner and avoid the nested lookup in your current workaround - I'll write those up this evening.

In the meantime could you open a feature request to support @Priority on providers, so I can add support for this in the development branch.

Cheers, Stuart

On Mon, 28 Oct 2019 at 09:08, Giamma <gm.romanato@xxxxxxxxx> wrote:

Hello,

In general I can annotate @Named classes with @Priority and injection will take this into account properly returning the highest priority binding:

public class FirstImpl implements Service
@Named @Priority(10)
public class SecondImpl implements Service

// the following will return SecondImpl as the first candidate
locator.locate(Keys.get(Service.class)); 

@Priority however seems to be ignored when a Provider is used. For example:

public class FirstImpl implements Service
@Named @Priority(10)
public class SecondImplProvider implements Provider<Service>

// the following will return FirstImpl
locator.locate(Keys.get(Service.class));

I tried to work around the above issue specifying a custom ranking function like the following, and it seems to solve my problem.  My questions are:
  1. is the above expected, shouldn't priority be honored also if declared on Providers ?
  2. the custom ranking function below seems to solve the problem, but it performs a nested lookup using the BeanLocator. Is this acceptable or a bad practice? Are there better ways to solve this issue? I tried to look into BeanLocator, RankedBindings, RankedSequence, and the Guice SPI but I could not find an easy solution.

public class CustomRankingFunction implements RankingFunction {

    private DefaultRankingFunction delegate;
   
    @Inject
    private DefaultBeanLocator locator;

    public CustomRankingFunction(final int primaryRank) {
        delegate = new DefaultRankingFunction(primaryRank);
    }

    public CustomRankingFunction() {
        this(0);
    }

    public int maxRank() {
        return delegate.maxRank();
    }

    public <T> int rank(final Binding<T> binding) {
        if (binding instanceof ProviderKeyBinding) {
            ProviderKeyBinding pkb = (ProviderKeyBinding) binding;
            BeanEntry o1 = (BeanEntry) locator.locate(pkb.getProviderKey()).iterator().next();
            if (o1.getImplementationClass().isAnnotationPresent(Priority.class)) {
                Priority p = (Priority) o1.getImplementationClass().getAnnotation(Priority.class);
                return p.value();
            }
        }
        return delegate.rank(binding);
    }
}

--
Gian Maria Romanato
<gm.romanato (at) gmail (dot) com>
_______________________________________________
sisu-users mailing list
sisu-users@xxxxxxxxxxx
To change your delivery options, retrieve your password, or unsubscribe from this list, visit
https://www.eclipse.org/mailman/listinfo/sisu-users
_______________________________________________
sisu-users mailing list
sisu-users@xxxxxxxxxxx
To change your delivery options, retrieve your password, or unsubscribe from this list, visit
https://www.eclipse.org/mailman/listinfo/sisu-users


_______________________________________________
sisu-users mailing list
sisu-users@xxxxxxxxxxx
To change your delivery options, retrieve your password, or unsubscribe from this list, visit
https://www.eclipse.org/mailman/listinfo/sisu-users
_______________________________________________
sisu-users mailing list
sisu-users@xxxxxxxxxxx
To change your delivery options, retrieve your password, or unsubscribe from this list, visit
https://www.eclipse.org/mailman/listinfo/sisu-users


--
Gian Maria Romanato
<gm.romanato (at) gmail (dot) com>
_______________________________________________
sisu-users mailing list
sisu-users@xxxxxxxxxxx
To change your delivery options, retrieve your password, or unsubscribe from this list, visit
https://www.eclipse.org/mailman/listinfo/sisu-users

Back to the top