Şu anda Dagger'u kullanmak üzere bir Android uygulamasının yeniden tasarlanmasını yapıyorum. Uygulamam büyük ve karmaşık ve yakın zamanda şu senaryoyu karşılıyorum:Yapıcılara bağımlılık enjeksiyonu için Hançeri Kullanılıyor
Nesne A, enjeksiyon için mükemmel bir aday olan özel bir DebugLogger örneği gerektirir. Kaydediciyi geçmektense, sadece A'nın yapıcısı ile enjekte edebilirim. Bu şu gibi bir şeye benziyor: Şimdilik bu mantıklıdır. Bununla birlikte, A böylece şeyler yapmanın Dagger yolunu izleyerek A birden çok örneği inşa edilmelidir başka sınıf B. tarafından inşa edilmesi gerekir Basit B içine Provider<A>
enjekte:
class B
{
private Provider<A> aFactory;
@Inject
public B(Provider<A> aFactory)
{
this.aFactory = aFactory;
}
}
Tamam, iyi şimdiye kadar. Ama bekle, birdenbire inşası için hayati olan "miktar" olarak adlandırılan bir tamsayı gibi ek girişlere ihtiyaç var. Şimdi, A için benim kurucu böyle bakmak gerekiyor:
@Inject
public A(DebugLogger logger, int amount)
{
...
}
Aniden bu yeni parametre enjeksiyon engeller. Üstelik, bu işe yaramış olsa bile, yanıltıcı olmadıkça, sağlayıcıdan yeni bir örnek alınırken "miktar" da geçmem için bir yol olmazdı. Burada yapabileceğim birkaç şey var ve sorum şu ki hangisi en iyisi?
Kurucudan sonra çağrılması beklenen setAmount()
yöntemini ekleyerek A'yı yeniden ayarlayabilirim. Bu çirkin bir durumdur, çünkü bu, "miktar" ın doldurulmasına kadar A'nın inşasını geciktirmeye zorlar. Eğer iki tür parametreye, "miktar" ve "frekans" a sahip olsaydım, o zaman iki ayarlayıcıya sahip olurdum. karmaşık hem belirleyiciler olarak adlandırılır devam eder sonra A'nın o inşaat sağlamak için kontrol, yoksa şöyle karışımı içine henüz üçüncü yöntemi eklemek gerekir:
(Somewhere in B):
A inst = aFactory.get();
inst.setAmount(5);
inst.setFrequency(7);
inst.doConstructionThatRequiresAmountAndFrequency();
diğer alternatif Ben yapıcı kullanmak kalmamasıdır tabanlı enjeksiyon ve alan bazlı enjeksiyon ile gidin. Ama şimdi, alanlarımı herkese açık hale getirmeliyim. Bu benimle iyi oturmuyor, çünkü şimdi sınıflarımın iç verilerini diğer sınıflara gösterme yükümlülüğüm var.
Şimdiye kadar, aklıma gelen tek biraz zarif çözüm şöyle, sağlayıcıları için alan bazlı enjeksiyon kullanmaktır:
class A
{
@Inject
public Provider<DebugLogger> loggerProvider;
private DebugLogger logger;
public A(int amount, int frequency)
{
logger = loggerProvider.get();
// Do fancy things with amount and frequency here
...
}
}
bile hala, ben beri, zamanlama konusunda emin değilim Marancı firmamın çağrılmasından önce sağlayıcıyı enjekte edeceğinden emin değilim.
Daha iyi bir yolu var mı? Hançerin nasıl çalıştığı hakkında bir şey mi duyuyorum?
Hızlı yanıtınız için teşekkür ederiz. Tanımladığınız fabrika modeli en iyi yaklaşım gibi görünüyor. Ayrıca Dagger özel alan enjeksiyonunu desteklediyse, gerçekleştirmeye çalıştığım şeye kolayca izin vereceğini de fark ettim. Bunun neden Dagger'ın orijinal tasarımının bir parçası olmadığını merak ediyorum? Dagger'ın yansımayı kullanarak enjekte ettiğini farz ediyorum. Öyleyse, özel alanlar sorun yaratmaz, değil mi? – Alex
Hançer yansımasına geri döner, ancak bu birincil enjeksiyon aracı değildir. Doğrudan alanları belirleyen ya da kurucularınızı arayarak kod üretir. Bu şekilde, kaynak ağacınızdaki herhangi bir kod parçası gibi çalışır ve "özel" üyelere erişemez. –
Ve bazı güvenlik yöneticileri, sınıflarınızdaki erişilebilirliği değiştirmeye dayanan yansımayı kıracak. –