Son zamanlarda Mark Seemann'ın Service Locator anti-pattern hakkındaki makalesini okudum .
Yazar, ServiceLocator'ın bir anti-desen olmasının iki ana nedenine dikkat çekiyor:
API kullanım sorunu (ki ben çok iyiyim)
Sınıf bir Servis bulucu kullandığında, çoğu durumda sınıfın yalnızca bir PARAMETERLESS yapıcısı olduğu için bağımlılıklarını görmek çok zordur. ServiceLocator'ın aksine DI yaklaşımı, bağımlılıkları yapıcı parametreleri aracılığıyla açıkça ortaya koyar, böylece IntelliSense'te bağımlılıklar kolayca görülebilir.Bakım sorunu (beni
şaşırtan ) Aşağıdaki örneği düşünün
Bir Servis bulucu yaklaşımı kullanan bir 'MyType' sınıfımız var :
public class MyType
{
public void MyMethod()
{
var dep1 = Locator.Resolve<IDep1>();
dep1.DoSomething();
}
}
Şimdi 'MyType' sınıfına başka bir bağımlılık eklemek istiyoruz
public class MyType
{
public void MyMethod()
{
var dep1 = Locator.Resolve<IDep1>();
dep1.DoSomething();
// new dependency
var dep2 = Locator.Resolve<IDep2>();
dep2.DoSomething();
}
}
Ve burada yanlış anlaşılmam başlıyor. Yazar diyor ki:
Kırılma değişikliği yapıp yapmadığınızı söylemek çok daha zorlaşıyor. Servis Bulucu'nun kullanıldığı tüm uygulamayı anlamalısınız ve derleyici size yardımcı olmayacaktır.
Ama bir saniye bekleyin, eğer DI yaklaşımını kullanıyor olsaydık, yapıcıdaki başka bir parametreye (yapıcı enjeksiyonu durumunda) bir bağımlılık getirirdik. Ve sorun hala orada olacak. ServiceLocator kurmayı unutabilirsek, IoC kapsayıcımıza yeni bir eşleme eklemeyi unutabiliriz ve DI yaklaşımı aynı çalışma zamanı sorununa sahip olur.
Ayrıca, yazar birim test zorluklarından bahsetti. Ancak, DI yaklaşımıyla ilgili sorunlarımız olmayacak mı? Bu sınıfı başlatan tüm testleri güncellememiz gerekmeyecek mi? Testimizi derlenebilir hale getirmek için onları yeni bir alay bağımlılığını geçecek şekilde güncelleyeceğiz. Ve bu güncellemeden ve zaman harcamasından fayda görmüyorum.
Servis Bulucu yaklaşımını savunmaya çalışmıyorum. Ama bu yanlış anlama beni çok önemli bir şey kaybettiğimi düşündürüyor. Birisi şüphelerimi giderebilir mi?
GÜNCELLEME (ÖZET):
"Servis Bulucu bir anti-model mi?" Sorumun cevabı gerçekten koşullara bağlı. Ve kesinlikle araç listenizden çıkarmanızı önermem. Eski kodla uğraşmaya başladığınızda çok kullanışlı olabilir. Projenizin en başında olmak için yeterince şanslıysanız, DI yaklaşımı Servis Bulucu'ya göre bazı avantajları olduğundan daha iyi bir seçim olabilir.
Ve beni yeni projelerim için Servis Bulucu'yu kullanmamaya ikna eden temel farklar:
- En belirgin ve önemli: Servis Bulucu sınıf bağımlılıklarını gizler
- Bazı IoC kapsayıcısı kullanıyorsanız, tüm bağımlılıkları doğrulamak ve eksik eşlemeler (veya yanlış yapılandırma) hakkında anında geri bildirim vermek için başlangıçta tüm kurucuları tarar; IoC kapsayıcınızı Servis Bulucu olarak kullanıyorsanız bu mümkün değildir
Ayrıntılar için aşağıda verilen mükemmel cevapları okuyun.