private <T> Provider<T> createProvider(Key<T> key)
{
Class<T> type = (Class<T>) key.rawClass();
if (Provider.class.equals(type)) {
TypeRef subType = TypeRef.of(key.type()).to(Provider.class).param(0);
Key<Object> subkey = Key.of(subType.type(), key.annotationTypes());
return (Provider) new ProviderProvider(key, -10, provider(subkey));
}
else if (Optional.class.equals(type)) {
TypeRef subType = TypeRef.of(key.type()).to(Optional.class).param(0);
Key<Object> subkey = Key.of(subType.type(), key.annotationTypes());
return (Provider) new ProviderOptional(key, -10, provider(subkey));
}
else if (type.isInterface() || Modifier.isAbstract(type.getModifiers())) {
return new ProviderNull(key, -10000, new InjectScopeSingleton());
}
int priority = -10;
InjectScope<T> scope = findScope(type);
BindingAmp<T> binding = new ProviderConstructor<>(this, key, priority, scope, type);
binding.bind();
return binding.provider();
}