2014-06-04 15 views
5

ı bu arayüzü var diyelimParametreleri Guice ile Sağlayıcıya nasıl geçiririm? o zaman bu uygulama</p> <pre><code>public interface DbMapper{ } </code></pre> <p>Ve:

public interface NameDbMapper extends DbMapper { 

    @SqlUpdate("insert into names (name) values (:name)") 
    void insert(@Bind("name") String name); 
} 

Bu uygulama bir modül var, bu yüzden derleme anda tüm DbMappers bilmiyorum. Ben yansıma yoluyla DbMappers keşfetmek:

public class DbMapperProvider implements Provider<DbMapper> { 

    private final User user; 

    @Inject 
    public DbMapperProvider(User user) { 
     this.user = user; 
    } 

    @Override 
    public DbMapper get() { 
     String jdbc = user.getJdbc(); 

     DBI userSpecificDatabase = new DBI(jdbc, "user", "password"); 
     //How to replace NameDbMapper.class here with the db variable in GuiceModule? 
     DbMapper dbMapper = userSpecificDatabase.onDemand(NameDbMapper.class); 
     return dbMapper; 
    } 
} 

Kullanıcı bir @RequestScoped örneğidir, bu yüzden GuiceModule düzenli sağlayıcıları oluşturamazsınız:

public class GuiceModule extends AbstractModule{ 

    @Override 
    protected void configure() { 
     Reflections reflections = new Reflections("com.company"); 
     Set<Class<? extends DbMapper>> dbMappers = reflections.getSubTypesOf(DbMapper.class); 

     for (Class<? extends DbMapper> dbMapper : dbMappers) { 
      Class<DbMapper> db = (Class<DbMapper>) dbMapper; 
      binder().bind(db).toProvider(DbMapperProvider.class); 
     } 
    } 

Sonra benim sağlayıcısı haritacılarla instansiate. Enjekte eden Kullanıcı çalışır, ancak DbMapperProvider'da NameDbMapper kodunun yerine hangi Sınıf DBI'nın kullanması gerektiğini nasıl iletirim?

http://google-guice.googlecode.com/git/javadoc/com/google/inject/assistedinject/FactoryModuleBuilder.html numaralı makalede önerilen yaklaşımı denedim ancak işe alamadı.

Buradaki amaç, modüllerin kendi sağlayıcılarını yazmaları gerekmemesi gerektiğidir, bu mümkün mü?

cevap

7

Sen O zaman bu gibi sağlayıcıyı değiştirmek

for (Class<? extends DbMapper> dbMapper : dbMappers) { 
    bind(dbMapper).toProvider(new DbMapperProvider<>(db)); 
} 

gibi bir sağlayıcı örneğine bağlayabilir. Ben kapsamına sahip nesneye erişilemiyor" olsun

public class DbMapperProvider<T extends DbMapper> implements Provider<T> { 
    // Use field or method injection 
    @Inject 
    private Provider<User> user; 

    private final Class<T> type; 

    public DbMapperProvider(Class<T> type) { 
     this.type = type; 
    } 

    @Override 
    public T get() { 
     String jdbc = user.get().getJdbc(); 

     DBI userSpecificDatabase = new DBI(jdbc, "user", "password"); 
     DbMapper dbMapper = userSpecificDatabase.onDemand(type); 
     return dbMapper; 
    } 
} 
+0

ya biz bir HTTP Servlet içeride halen değildir istek veya com.google.inject.servlet.GuiceFilter'ı bu istek için bir sunucu filtresi olarak uygulamayı unutmuş olabilirsiniz. ", Bazı nedenlerden dolayı Guice başlatma sırasında hevesle örnekler oluşturmaya çalışır? – jontejj

+1

Elbette. Bunun yerine bir Sağlayıcı enjekte edebilirsiniz. –

+0

Vay! Bunun için bir demet teşekkürler. +1 – jontejj

İlgili konular