2013-07-15 29 views
8

Android uygulamasına bağımlılıkları enjekte etmek için Dagger kullanıyorum ve temiz bir şekilde nasıl çözüleceğimi tam olarak bilmediğim bir sorunla karşılaştım.Hançer ve iç içe geçmiş enjeksiyonları

Elde etmeye çalıştığım şey, yardımcıları kavramak ve benim etkinliğim içine enjekte etmektir ve bu yardımcıların da enjekte edilen üyeler içermesi gerekir.

benim yardımcı enjekte ediliyor etkinlik işleri ne

:

public class MyActivity extends Activity { 
    @Inject SampleHelper helper; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     ((MyApplication) getApplication()).inject(this); 

     Log.i("debug", "helper = " + helper); 
     Log.i("debug", "helper context = " + helper.context); 
    } 
} 

nesne grafiği oluşturma uygulaması: Doğrudan instanciate zaman

public class MyApplication extends Application { 
    private ObjectGraph graph; 

    @Override 
    public void onCreate() { 
     super.onCreate(); 

     graph = ObjectGraph.create(getModules()); 
    } 

    private Object[] getModules() { 
     return new Object[] { new MyModule(this) }; 
    } 

    public void inject(Object target) { 
     graph.inject(target); 
    } 
} 

enjeksiyon mükemmel çalışıyor bir SampleHelper sınıfı, kendi başına enjekte edilen bir uygulama eşini alır.

public interface SampleHelper { 
} 

@Singleton 
public class SampleHelperImpl implements SampleHelper { 

    @Inject public Context context; 

    @Inject 
    public SampleHelperImpl() {} 
} 
: nmetin: Aşağıdaki modül ile

@Singleton 
public class SampleHelper { 

    @Inject public Context context; 

    @Inject 
    public SampleHelper() {} 
} 

: Ben onun uygulanmasından yardımcı arayüzünü ayrıldıklarında

@Module(
    injects = { MyActivity.class }, 
    complete = false, 
    library = true 
) 
public class MyModule { 
    private final MyApplication application; 

    public MyModule(MyApplication application) { 
     this.application = application; 
    } 

    @Provides @Singleton Context provideApplicationContext() { 
     return application; 
    } 
} 

Ne Ancak

çalışmıyor

Ve bunu hançer modülüne ekleyin:

public class MyModule { 
    ... 

    // added this method 
    @Provides @Singleton public SampleHelper provideSampleHelper() { 
     return new SampleHelperImpl(); 
    } 

    ... 
} 

Buradaki örneklem, SampleHelperImpl'de beklediğim gibi enjekte edilmiyor. Şimdi, ben bu örneklememeli constructor çağrısı yerine doğrudan constructor çağrı ile instanciated olduğunu düşünüyorum, çünkü MyModule # providApplicationContext() bile çağrılmıyor, bu yüzden benim tahminim hançer hakkında bir şey eksik olduğunu Muhtemelen, önceki DI deneyimlerim sadece Bahar dahil olduğu gibi.

İçeriğimin enjekte edilen yardımcı uygulamasında "temiz Hançer" şeklinde nasıl enjekte edildiğiyle ilgili bir fikriniz var mı?

Çok teşekkürler!

@Provides @Singleton public SampleHelper provideSampleHelper(Context context) { 
    SampleHelper helper = new SampleHelperImpl(); 
    helper.setContext(context); 
    return helper; 
} 

Bu çalışır, ancak yine de biraz hantal hissediyorum: Bir hançer modülünde bir @Provides yöntemini uygularken kimse ilgileniyor durumda

+0

Ayrıca şu anda hançer ile mücadele ediyorum ve sizinkiyle benzer bir yapılandırm var. Kendisine uygulama yapmamaya yardım edenlerin etkinliklerini enjekte etmem gerekiyor, ama aksi takdirde çok benzer. Bu yüzden size bir sorum var: Neden yapıcı parametre olarak değil, 'SampleHelper' içine bir üye olarak bağlam enjekte ediyorsunuz? Benim durumumda, constructor parametresi ile enjeksiyon başarısız olur ve bu yüzden bundan kaçınılması gereken özel bir şey olup olmadığını merak ediyorum. Konu dışı olduğunu anlıyorum, ama eğer yardım ederseniz takdir edilecektir. – Haspemulator

+0

Aslında, yapılamacıyı doğrudan yapıcıda değil, hançer modülündeki bir @Provides yönteminin parçası olarak yapılandırılmış olsa da (aşağıdaki cevabımda da belirtildiği gibi) bağlamı şimdi geçiriyorum (ve çalışır) . Benim ilk fikrim, hançer sayesinde üyelerimi atamakla ilgili tüm kodları bırakmaktı, ancak bahar enjeksiyonunun olduğu kadar kolay kullanılmasını sağlayamadım. Yani, aynı şekilde ve aynı kısıtlamalarla çalışmadıklarının farkındayım ve hançer hala çok şey getiriyor. – mrlem

+0

Merhaba, cevap için teşekkürler. Belki soruma bir göz atabilirsin? http://stackoverflow.com/questions/17839451/activity-graphs-and-non-found-dependency – Haspemulator

cevap

17

Bu oldukça eski bir sorudur ama ne istediğini bu olduğunu düşünüyorum:

@Provides @Singleton public SampleHelper provideSampleHelper(SampleHelperImpl impl) { 
    return impl; 
} 

Bu şekilde Hançer enjekte nedenle SampleHelperImpl oluşturup olacaktır.

+0

Çok geç değil: gerçekten sorumu mükemmel bir şekilde cevaplıyor. Çok teşekkürler! – mrlem

+0

@alexanderblom Yaptıklarınız ile müminin ne yaptığı arasındaki farkı açıklar mısınız? – peacepassion

0

(vaka birisi daha iyi bir çözüm ile geliyor ben biraz beklemek gerekir).

+0

Cevabınız için teşekkürler: Bu örnekte zaten rastladım (çok fazla değil). Gerçekten de, gerçek hayattaki bir uygulamada, doğru içeriği enjekte etmeniz gerekir. Ama benim ilk sorum biraz daha genel oldu: Uygulamanın yardımcı arayüzünü ayırarak, uygulama anında çalışmayı engeller. Yardımcı örnekleme artık doğrudan Dagger tarafından ele alınmaz. – mrlem

1

(Uygula: Hançer v1.0.1)

Adaptör enjeksiyonu kullandığınızdan emin olun. Yansıtıcı enjeksiyon ile hançer @Provides nesnelerine hiçbir şekilde geçici bir enjeksiyon yapmaz. Bence bu bir böcek.

+1

Bu, benim sorunum gibi geliyor. Ama lütfen sadece 2 şeyi netleştirebilir misiniz: 1/Enjeksiyonları için yansımayı kullanmadığını düşündüm? ("yansıtıcı enjeksiyon" ile kastettiğinizi mi kastediyorsunuz, yoksa ek açıklama temelli enjeksiyon mu demek istediniz?) 2/adaptör enjeksiyonu ile ne demek istiyorsunuz: hançer modülünde @Provides kullanarak enjeksiyonlar? – mrlem

+0

Hançer, '@ Inject 'açıklamalı alanlarının iki şekilde ayarlanmasını sağlar. Biri yansıma yoluyla, diğeri üretilen bir adaptör sınıfıyla. Her iki durumda da, alanların en azından paket erişilebilir olması gerekir. Yansıma yöntemi bir geri dönüştür ve gelecek sürümlerde mevcut olmayabilir. Kullandığınız enjeksiyon yöntemini öğrenmek için, modülünüzün 'Sağla 'yönteminde bir kesme noktası belirleyin ve yığın izlemenizi inceleyin. 'injectMembers(): 118, ReflectiveAtInjectBinding {dagger.internal.plugins.reflect}' vs 'injectMembers(): dikkat 82, sinifIsminiz $$ InjectAdapter {your.classes.package}' –

+0

Tamam, teşekkürler açıklama için bunu kontrol etmeye çalışacağım! – mrlem

İlgili konular