Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Class annotated with @Implementation cannot have constructor with argument of parametrised type. #1

Closed
AlexWih opened this issue Mar 3, 2018 · 6 comments
Assignees
Labels
bug Something isn't working

Comments

@AlexWih
Copy link

AlexWih commented Mar 3, 2018

If my implementation has input argument of parametrised type T like this:

@Implementation(forType = Foo.class)
public class FooImpl<T extends Number> implements Foo {

    public FooImpl(T dependency) {

    }
}

then compilation of generated class MagnetFooImplFactory gets failed:

public final class MagnetFooImplFactory implements Factory<Foo> {
  @Override
  public Foo create(DependencyScope dependencyScope) {
    T dependency = dependencyScope.require(T.class);
    return new FooImpl(dependency);
  }
}
@sergejsha sergejsha self-assigned this Mar 3, 2018
@sergejsha sergejsha added bug Something isn't working to be analyzed and removed bug Something isn't working labels Mar 3, 2018
@sergejsha
Copy link
Owner

sergejsha commented Mar 3, 2018

Before getting a dependency from the scope someone needs to put this dependency into the scope. How would you write the code for putting it in this particular case?

@AlexWih
Copy link
Author

AlexWih commented Mar 3, 2018

As T is a subtype of Number then the DependencyScope should receive some subtype of Number, i.e.:
dependencyScope.register(Long.class, Long.MAX_VALUE);

@sergejsha
Copy link
Owner

And in case when I put

dependencyScope.register(Long.class, Long.MAX_VALUE);
dependencyScope.register(Byte.class, Byte.MIN_VALUE);

which value should be provided to constructor of FooImpl?

@AlexWih
Copy link
Author

AlexWih commented Mar 3, 2018

I believe it is a design decision.
I would expect runtime error as both dependencies match.
Or alternatively the qualifiers could be utilised as Dagger does.

@sergejsha
Copy link
Owner

sergejsha commented Mar 3, 2018

I was thinking about adding qualifiers later on, but they won't help here. It will still be possible to add both Float and Byte types with the same qualifier, which is fully valid construct, and this will produce ambiguity when the type is requested though a generic type. I believe even Dagger will fail to inject a generic type due to mentioned type ambiguity.

I'm going to disallow generics in implementation constructors for now. However compiler will fail with a meaningful message.

@sergejsha sergejsha added bug Something isn't working and removed to be analyzed labels Mar 3, 2018
@sergejsha
Copy link
Owner

sergejsha commented Mar 3, 2018

Moreover, it is always possible to resolve this ambiguity manually in the constructor. Just add DependencyScope as a constructor parameter and then request from the scope whatever needed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants