2016-08-22 1 views
0

encore un petit problème en comprenant "comment fonctionne la tapisserie".Tapisserie: Injecter à l'exécution

J'ai une composante de tapisserie (dans ce cas, un codeur):

public class EditionEncoder implements ValueEncoder<Edition>, ValueEncoderFactory<Edition> { 

    @Inject 
    private IEditionManager editionDao; 

    public EditionEncoder(IEditionManager editionDao) { 
     this.editionManager = editionDao; 
    } 

    @Override 
    public String toClient(Edition value) { 
     if(value == null) { 
      return ""; 
     } 
     return value.getName(); 
    } 

    @Override 
    public Edition toValue(String clientValue) { 
     if(clientValue.equals("")) { 
      return null; 
     } 
     return editionManager.getEditionByName(clientValue); 
    } 

    @Override 
    public ValueEncoder<Edition> create(Class<Edition> type) { 
     return this; 
    } 
} 

Injecter le gestionnaire ne fonctionne pas, parce que le codeur est créé dans une page comme ça:

public void create() { 
     editionEncoder = new EditionEncoder(); 
    } 

casued par cela, je suis obligé d'utiliser cette solution laide:

@Inject 
private IEditionManager editionmanager; 
editionEncoder = new EditionEncoder(editionManager); 

y at-il une meilleure façon pour injecter des composants pendant l'exécution ou y a-t-il une meilleure solution en général pour cela?

Merci pour votre aide à l'avance,

Répondre

0

Dès que vous utilisez « nouveau » puis la tapisserie cio ne participe pas à la création d'objets et ne peut pas injecter. Vous devriez tout injecter et ne jamais utiliser "nouveau" pour les services singleton. Cela est vrai pour tous les conteneurs ioc, pas seulement pour Tapestry-ioc.

Si vous placez @Inject sur un champ, vous n'avez pas non plus besoin d'un constructeur pour le définir. Fais l'un ou l'autre, jamais les deux.

Vous devriez faire quelque chose comme ceci:

public class MyAppModule { 
    public void bind(ServiceBinder binder) { 
     binder.bind(EditionEncoder.class); 
    } 
} 

Ensuite, dans votre page/composant/Service

@Inject EditionEncoder editionEncoder; 

Si vous voulez mettre vos propres objets instanciés là-bas que vous pouvez faire

public class MyServiceModule { 
    public void bind(ServiceBinder binder) { 
     binder.bind(Service1.class, Service1Impl.class); 
     binder.bind(Service2.class, Service2Impl.class); 
    } 
    public SomeService buildSomeService(Service1 service1, Service2 service2, @AutoBuild Service3Impl service3) { 
     Date someDate = new Date(); 
     return new SomeServiceImpl(service1, service2, service3, someDate); 
    } 
} 
+0

yip, c'est clair pour moi. Mais par exemple Au printemps, il est possible de "forcer" le mécanisme d'injection avec des objets instanciés manuellement. Je suis à la recherche d'une manière similaire., Je ne suis pas comme les arguments constructeur. – user3066027