Why isn't Guice finding my List<Interface> binding? - dependency-injection

I've got a interface with a couple of implementations:
interface PuNoManager {
fun notifyUser(userId: Int)
}
class FcmManager
#Inject
constructor(val fcmClient: FcmClient) : PuNoManager {
override fun notifyUser(userId: Int) { ... }
}
class ApnsManager
#Inject
constructor(val apnsClient: ApnsClient) : PuNoManager {
override fun notifyUser(userId: Int) { ... }
}
Which are both bound in my Module, along with a #Provides-annotated method to get a List<PuNoManager>:
class PuNoModule: AbstractModule() {
override fun configure() {
bind(ApnsManager::class.java)
bind(FcmManager::class.java)
}
#Provides
fun puNoManagers(apnsManager: ApnsManager, fcmManager: FcmManager): List<PuNoManager> {
return listOf(apnsManager, fcmManager)
}
}
The problem arises when I have a class that needs the List<PuNoManager>—Guice complains that the type hasn't been bound:
Explicit bindings are required and java.util.List<? extends ...PuNoManager> is not explicitly bound.
while locating java.util.List<? extends ...PuNoManager>
I know my Guice setup is working, as I previously had just the ApnsManager and am adding the second PuNoManager, FcmManager. The problem stems from the dependent class requesting injection of List<PuNoManager> instead of just ApnsManager.

List<X> in Kotlin is translated to java.util.List<? extends X> on the JVM. Apparently, Guice doesn't support injection of such values. To avoid the wildcard here, you can use a MutableList<X> instead, which translates to java.util.List<X>

Try adding #JvmSuppressWildcards to the module class.

Related

Generic protocol Swift 4 error

The following code use to work for me at Swift 3.2, but with the latest release of Swift 4 I am getting an strange error I can not get to understand.
I am trying to create a generic protocol like so:
public protocol FactoryComponent {
associatedtype Argument
associatedtype Service
static var factory: (Resolver) -> (Argument) -> Service { get }
}
public extension FactoryComponent {
public typealias Factory = (Argument) -> Service
}
And using it here:
public extension Container {
#discardableResult
public func register<Component: FactoryComponent>(
factory componentType: Component.Type
) -> ServiceEntry<Component.Factory> { // On this line the error shows
return self.register(componentType.Factory.self) { resolver in
componentType.factory(resolver)
}
}
}
Error:
'Component' does not have a member type named 'Factory'; did you mean 'Factory'?
And of course, the auto-fix does not help since the error is useless...
I checked out Swift 4 breaking changes and did not see anything involving generic protocols.
Can somone please help me understand what does this mean?
It seems that a concrete class of FactoryComponentis missing. The Factory type alias can be called only by protocol's concrete classes.
Try create an FactoryComponent concrete class that implements its protocol
The Argument and Service still generic on your implementation and needs an concrete type. My english is very bad, but I hope I've been help you. Check the code bellow if I'm wasn't clear on my answer.
```
class Resolver {}
protocol FactoryComponent {
associatedtype Argument
associatedtype Service
static var factory: (Resolver) -> (Argument) -> Service { get }
}
extension FactoryComponent {
typealias Factory = (Argument) -> Service
}
class ConcreteFactoryComponent: FactoryComponent {
static var factory: (Resolver) -> Factory {
return foo
}
static func foo(_ resolver: Resolver) -> Factory {
let factory: Factory = { argument in return "" }
return factory
}
typealias Argument = String
typealias Service = String
}
let factory: ConcreteFactoryComponent.Factory = { argument in return "" }
```
I believe the error is not really on the line with the return type. The processing of generic signature resolution has changed slightly in Swift 4 due to the new default for #escaping. The fact that the function is calling a self.register function with an identical signature as the function itself is likely the source of the issue.
From other similar instances, I would suggest looking at the signature of the Container.register. If it happens to have an #escaping closure, then the signature of the generic function in the extension should also have one so that it is recognized as an overload.
See this post: https://stackoverflow.com/a/43081214/5237560
[EDIT] I just realized this change was between Swift 2 and 3. Leaving the answer here in case it can provide some inspiration.

Bind list of objects using Guice + Kotlin

I'm writing a JavaFX application in Kotlin with the following controller definition:
class MainController {
#Inject private lateinit var componentDescriptors: List<ComponentDescriptor>
/* More code goes here */
}
I'm using Guice for Dependency management. And I'm trying to inject the list of class instances loaded via java.util.ServiceLoader. My problem is to define a binding that will inject the list of loaded object instances into the declared field. I tried annotation based provisioning:
internal class MyModule: AbstractModule() {
override fun configure() { }
#Provides #Singleton
fun bindComponentDescriptors(): List<ComponentDescriptor> =
ServiceLoader.load(ComponentDescriptor::class.java).toList()
}
and multibinding extension (switched List to Set in field definition of corse):
internal class MyModule: AbstractModule() {
override fun configure() {
val componentDescriptorBinder = Multibinder.newSetBinder(binder(), ComponentDescriptor::class.java)
ServiceLoader.load(ComponentDescriptor::class.java).forEach {
componentDescriptorBinder.addBinding().toInstance(it)
}
}
}
but both of these approaches leads to the same error:
No implementation for java.util.List<? extends simpleApp.ComponentDescriptor> was bound.
while locating java.util.List<? extends simpleApp.ComponentDescriptor>
for field at simpleApp.MainController.componentDescryptors(MainController.kt:6)
while locating simpleApp.MainController
1 error
at com.google.inject.internal.InjectorImpl.getProvider(InjectorImpl.java:1042)
at com.google.inject.internal.InjectorImpl.getProvider(InjectorImpl.java:1001)
at com.google.inject.internal.InjectorImpl.getInstance(InjectorImpl.java:1051)
at com.gluonhq.ignite.guice.GuiceContext.getInstance(GuiceContext.java:46)
at javafx.fxml.FXMLLoader$ValueElement.processAttribute(FXMLLoader.java:929)
at javafx.fxml.FXMLLoader$InstanceDeclarationElement.processAttribute(FXMLLoader.java:971)
at javafx.fxml.FXMLLoader$Element.processStartElement(FXMLLoader.java:220)
at javafx.fxml.FXMLLoader$ValueElement.processStartElement(FXMLLoader.java:744)
at javafx.fxml.FXMLLoader.processStartElement(FXMLLoader.java:2707)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2527)
... 12 more
I'm starting to suspect that it somehow related to Kotlin gerenic variance and Guice strict type checking. But I don't know how to declare the binding so Guice will know what to inject into this field.
Yes, it happens because of variance but there's a way to make it work.
class MainController {
#JvmSuppressWildcards
#Inject
private lateinit var componentDescriptors: List<ComponentDescriptor>
}
By default Kotlin generates List<? extends ComponentDescriptor> signature for the componentDescriptors field. The #JvmSuppressWildcards makes it generate a simple parameterized signature List<ComponentDescriptor>.
#Michael gives the correct answer and explanation. Here's an example of one strategy for unit testing a Set multibinding for those that like to test their modules:
class MyModuleTest {
#JvmSuppressWildcards
#Inject
private lateinit var myTypes: Set<MyType>
#Before fun before() {
val injector = Guice.createInjector(MyModule())
injector.injectMembers(this)
}
#Test fun multibindings() {
assertNotNull(myTypes)
assertTrue(myTypes.iterator().next() is MyType)
}
}
#Michael comment is working. If you want to do the injection in constructor, you need do something like
class MainController #Inject consturctor(
private var componentDescriptors: List<#JvmSuppressWildcards ComponentDescriptor>
) {}

Anonymous inner Class in Swift

In Java I can do the following:
interface SomeCallback {
void onDone();
}
then I can create a function like this:
void test(SomeCallback callback) {
...
}
To call this function I do:
test(new SomeCallback() {
#Override
void done() {
...
}
});
I want to do something similar in Swift. I could create a protocol
protocol SomeCallback : class {
func done()
}
and a function like this
func test(callback: SomeCallback) {
...
}
I am still struggling with the call of this function.
Edit: Since I use an external API which requires a delegate I cannot use a Closure.
Is it possible to create some kind of anonymous inner class like I did it in the Java example to call test()?
Update: If you can't use a closure/function, the direct answer is: no, there are no anonymous inner classes. However, as Mike M points out, you'll have to use a class, and this class may be nested/inner to prevent polluting the global namespace. This class may well have a closure for every method it needs to implement and just call through to those closures.
The Swift-y way of doing this as long as you just need one method is to just use a lambda/closure.
For example, see NSComparator, which is typealiased since it is used all over the place and you are meant to recognize it.
In your example, specifying a function type inline will do fine. So for example:
func test(callback: () -> Void) {
...
callback()
}
// called as:
test({ in
...
})
// or even (since it's the last parameter)
test { in
...
}
Just to clarify the syntax because what you wrote is a little confusing.
#objc protocol SomeCallback {
func done() -> Void
}
No need to inherit from class as you wrote. Also, don't forget the #objc even if you do not want to bridge the protocol to that language. It helps with compiler complaints later on (might be a bug at the moment)
You cannot instantiate a protocol in Swift. You can however have an internal class that inherits from NSObject (root object) and implements this.
class External: NSObject {
class Internal : SomeCallback {
func done() {
// does something
}
}
let int = Internal()
func test(callback : SomeCallback) {
// additional work
callback.done()
}
}

How to require a generic type implement a generic protocol using a specific type in the protocol

Hi I'm using generics a lot in my current project. However, I've come across a problem:
I need a generic function foo<T> to be able to take a parameter that conforms to a generic protocol using a specific type.
For example in Java I can do:
public interface Proto<B> {
public void SomeFunction()
}
public class SampleClass {
}
public class Conforms extends Proto<SampleClass> {
#Override
public void SomeFunction () {}
}
public class TestingClass {
public void Requires (Proto<SampleClass> param) {
// I can use param
}
}
How would I do the same Requires() function in Swift?
I know in Swift you use typealias in the protocol for generics. How do I constrain a parameter based on the typealias?
Prototypes don't seem to have generics the way classes and structs do in Swift, but you can have associated types with typealias, which are close.
You can use type constraints to make sure that the object you pass in adopts the Proto with type constraints. To make the Proto you pass into require has the right B, you use where.
Apples documentation on generics has a lot of info.
This blog post is also a good source of info on doing more complicated things with generics.
protocol Proto {
typealias B
func someFunction()
}
class SampleClass {}
class Conforms : Proto {
typealias B = SampleClass
func someFunction() { }
}
class TestingClass {
func requires<T: Proto where T.B == SampleClass>(param: T) {
param.someFunction()
}
}
You can use a where clause to specify multiple requirements for a generic. I think your example translates to this, but it crashes Xcode. Beta!
protocol Proto {
func someFunction()
}
class SampleClass {
}
class Conforms: SampleClass, Proto {
func someFunction() {
}
}
class TestingClass {
func requires<T: SampleClass >(param: T) where T: Proto {
param.someFunction() // it's this line that kills Xcode
}
}
let testingClass = TestingClass()
let conforms = Conforms()
testingClass.requires(conforms)

Inject dependencies in methods or in the constructor?

Dependency injection seems to be a good thing. In general, should dependencies be injected at the methods that require them, or should they be injected in the contructor of the class?
See the samples below to demonstrate the two ways to inject the same dependency.
//Inject the dependency into the methods that require ImportantClass
Class Something {
public Something()
{
//empty
}
public void A()
{
//do something without x
}
public void B(ImportantClass x)
{
//do something with x
}
public void C(ImportantClass x)
{
//do something with x
}
}
//Inject the dependency into the constructor once
Class Something {
private ImportantClass _x
public Something(ImportantClass x)
{
this._x = x;
}
public void A()
{
//do something without x
}
public void B()
{
//do something with this._x
}
public void C()
{
//do something with this._x
}
}
The major benefit of constructor injection is that it allows your fields to be marked final. For example:
class Foo {
private final Bar _bar;
Foo(Bar bar) {
_bar=bar;
}
}
The following page has a great list of the pro's and con's: Guice Best Practices:
Method injection
+ Isn't field injection
+ Only thing that works for some strange edge cases
Constructor injection
+ Fields can be final!
+ Injection cannot possibly have been skipped
+ Easy to see dependencies at a glance
+ It's what the idea of construction is all about
- No optional injections
- Useless when DI library can't do instantiation itself
- Subclasses need to "know about" the injections needed by their superclasses
- Less convenient for tests that only "care about" one of the parameters
If you inject during the methods than you are not differentiating the behavioral abstraction from the concrete dependencies. This is a big no no :). You want to depend on abstractions so you are not coupled with the dependencies of your classes dependencies . . .
Since your constructor would not be there in any interface that your concrete class supports than you are not coupling to that dependency. But the method calls would have that issue.
Here is a good article on this tiopic:
http://chrisdonnan.com/blog/2007/05/20/conquest-through-extreme-composition-glue-part-2/
By not injecting the dependency at each method you then force each caller to know or retrieve the dependency.
Also from a tooling standpoint there are many frameworks available (at least in .NET) that enable or make constructor injection much easier to do. This should not sway the decision but makes it much more attractive.
Good luck.
Another method is to user a setter for the dependency. Sometimes this is combined with constructor injection. This can be useful if you want to change which implementation you are using later without having to recreate the instance.
public interface IFoo
{
void Do();
}
public class DefaultFoo : IFoo
{
public void Do()
{
}
}
public class UsesFoo
{
private IFoo foo;
public IFoo Foo
{
set { this.foo = value; }
}
public UsesFoo()
{
this.Foo = new DefaultFoo();
}
public UsesFoo( IFoo foo )
{
this.Foo = foo;
}
public void DoFoo()
{
this.Foo.Do();
}
}
Crazy Bob Lee says use constructor injection whenever possible. Only use method injection when you don't have control over instantiation (like in a servlet).

Resources