2017-07-14 1 views
0

En utilisant Guice dans Scala, j'essaie de reproduire le code Java suivant.Scala injection de dépendance avec la classe générique

Interface Foo et la déclaration de classe:

public interface Foo[T] {} 
public class FooImpl[T] implements Foo[T] {} 

code de liaison Guice:

bind(Foo.class).to(FooImpl.class); 

Et un exemple d'utilisation serait;

@Inject 
public class Bar(Foo<String> foo) {} 

SCALA, mon premier pari était:

bind(classOf[Foo]).to(classOf[FooImpl]) 

Mais il se plaint de 'type de paramètre Foo prend le type' Comment puis-je obtenir ces résultats dans scala?

Merci

+0

Que diriez-vous 'bind (classof [Foo ]).à (classOf [FooImpl ]) ' – frozen

+1

' bind (classOf [Foo [_]]). à (classOf [FooImpl [_]]) ' – Dima

+0

Salut Dima, merci pour votre réponse. On dirait que ça marche MAIS je suis incapable de confirmer maintenant car je suis confronté à un autre problème. J'ai 2 paramètres implicites sur ma classe et on dirait qu'ils ne sont pas fournis correctement en utilisant Guice et l'injection. Si cela fonctionne, je vous le ferai savoir pour que vous puissiez répondre à ma question. – Jeep87c

Répondre

0

Votre question a une erreur et ainsi vous permet une mauvaise réponse.

Fixons d'abord votre idée de concept. Ayant trait

trait Foo[T] { def hello: T } 

fonctionne très bien. Mais alors, les classes spécifiques étendant ce trait seront, fe:

class FooImpl1 extends Foo[Int] { override def hello: Int = 42 } 
class FooImpl2 extends Foo[String]{ override def hello: String = "test" } 

Et ils ne pouvaient pas être:

class FooImpl[Int] extends Foo[Int] { override def hello: Int = 42 } 
class FooImpl[String] extends Foo[String]{ override def hello: String = "test" } 

Parce qu'alors, la Int ou String est juste le NOM pour un paramètre générique. Il pourrait aussi bien s'agir de A et B, mais vous vous êtes confus.


Ayant ce triés, vous savez savez que vous avez FooImpl1 et FooImpl2. Ils ont besoin de noms différents car vous ne pouvez pas avoir deux classes nommées identiques dans la même portée!

Et c'est très bien. Parce que quand vous:

bind(classOf[X]).to(classOf[Y]) 

Vous dites que chaque fois que votre classe appellera les méthodes de la Interface ou TraitX vous voulez fournir la mise en œuvre de la classe Y.

Vous devez fournir une classe que vous pouvez instancier! Vous ne pouvez pas instancier une classe avec un paramètre générique.

Et, à la fin, votre ressembleraient liaison appropriée ceci:

bind(new TypeLiteral[Foo[Int]](){}).to(classOf[FooImpl1]) 
bind(new TypeLiteral[Foo[String]](){}).to(classOf[FooImpl2])