deniz.in

Piyasalar

Hava durumu

Hava durumu yükleniyor

· kaynak dev.to (home feed)

wire yeni özellik almazken kanna-di, Go için provider kaydı gerektirmeyen compile-time DI sunuyor

Aracın yazarının dev.to'daki yazısı, provider kaydı olmadan compile-time dependency injection yapan bir Go kod üreteci olan kanna-di'yi tanıtıyor; araç, özellik geliştirmesi durdurulmuş google/wire'ın halefi olarak konumlanıyor.

wire yeni özellik almazken kanna-di, Go için provider kaydı gerektirmeyen compile-time DI sunuyor

dev.to'daki bir yazı, yazının yazarı tarafından geliştirilen ve Go için compile-time dependency injection kod üreteci olan kanna-di'yi tanıtıyor. Yazar, aracı sürekli karşımıza çıkan bir soruya verilen yanıt olarak çerçeveliyor: google/wire artık yeni özellik kabul etmiyor, peki ondan sonra ne gelecek? wire gibi kanna-di de sıradan Go kaynak kodu üretir ve çalışma zamanında hiçbir şey import etmez. Fark yaratan nokta, provider kaydını tamamen ortadan kaldırmasıdır.

wire'ın gerektirdiği kayıt işi

Yazar, motivasyonu bir wire kurulumunun taleplerine dayandırıyor: her injector imzasının elle yazıldığı //go:build wireinject etiketli ayrı bir wire.go dosyası, wire.NewSet ile birleştirilip wire.Build'e verilen provider setleri, her interface için bir wire.Bind kaydı ve yeni bir constructor ortaya çıktığında bir sete geri dönüş. Yazıya göre constructor'lar zaten ürettikleri tiplerin yanında duruyor; dolayısıyla wire fiilen sizden bunların ikinci, ayrı bir envanterini daha tutmanızı istiyor.

Konvansiyonla çözümleme

kanna-di bu düzeni tersine çeviriyor. Composition root görevi gören struct'a //kanna:container ek açıklamasını ekleyip go generate çalıştırıyorsunuz. Üreteci her alanın tipini inceliyor, o tiple ilişkili constructor'ı buluyor, o constructor'ın parametrelerini özyinelemeli olarak takip ediyor ve tüm grafiği inşa edip struct'ı bir temizlik fonksiyonu ve bir hatayla birlikte döndüren bir fonksiyon içeren di_gen.go dosyasını yazıyor.

Yalnızca root'un verebileceği kararlar, yanına eklenen struct tag'leriyle ifade ediliyor: di:"with=postgres.NewUserRepository" bir domain interface'inin arkasına hangi implementasyonun geçeceğini seçiyor ve openDB gibi elle yazılmış bir yardımcı, kendi constructor'ı olmayan *sql.DB gibi standard library değerlerini sağlıyor. Bir kez yüklenen bir config değeri ona bağımlı olan her şey arasında paylaşılıyor ve bir constructor'ın parametre listesi değiştiğinde, bir sonraki üretim turu çağıran kodu yeniden yazıyor.

Provider arama, yazıda açıkça belirtildiği üzere sabit bir öncelik sırasını izliyor: container'a bir argüman (di:"arg"), di:"with=..." ile seçilen provider, container'ın embed ettiği veya blank olarak bildirdiği bir struct'ın export edilen alanı, container'ın kendi paketindeki bir fonksiyon ve son olarak, o paket modülünüzün veya go.work'un içinde olması koşuluyla, tipi bildiren paketteki export edilen bir fonksiyon. Hiçbir şey eşleşmezse ve aynı düzeyde iki aday ortaya çıkarsa üretim duruyor. Standard library ve harici modüller bilinçli olarak hiçbir zaman aranmıyor — yazı, io'nun io.Writer döndüren fonksiyonlar içerdiğini, sessizce sizin yerinize birinin seçilmesini istemeyeceğinizi belirtiyor.

Alanı işaret eden hatalar

Başarısız çözümleme, DI araçlarının en çok zaman tükettiği yer olduğu için tanılama birinci sınıf muamele görüyor. Hatalar, eksik bir bağımlılığı zincirin başladığı container alanına kadar izliyor ve ilgili constructor'lar üzerinden geçen yolu listeliyor. Belirsiz durumlarda iki aday fonksiyon da dosya konumlarıyla ve onları ayırt edecek tag ile birlikte gösteriliyor. Yanlış yazılmış isimler bir "bunu mu demek istediniz" önerisi tetikliyor ve with= ile seçilen bir implementasyon interface'i sağlamadığında, eksik metodu adlandıran bir hata üretiliyor.

Farklı bir test hikayesi

Yazarın görüşüne göre wire ile en keskin fark test kompozisyonunda. wire altında fake'lerle değiştirmek, başka bir injector ve başka bir provider seti kurmak demek. kanna-di ile ise bir _test.go dosyası, production container'ını embed eden ve seçilen interface'leri di:"arg" argümanlarına yükselten kendi container'ını bildiriyor; üretilen test constructor'ı da yerine koymaları doğrudan kabul ediyor. Production bağlamaları kullanılmadığı için veritabanını açma, yapılandırmayı yükleme ve harici mail istemcisini kurma gibi altyapı işleri test sırasında hiç çalışmıyor.

Neden önemli

wire hâlâ yaygın biçimde kullanılıyor ama özellik dondurması Go ekiplerini net bir ileri yol olmadan bırakıyor ve halef sorusu düzenli olarak gündeme geliyor. kanna-di, wire'ı çekici kılan özelliği — sıfır çalışma zamanı import'ıyla düz Go üretmek — korurken, bakım maliyetinin büyük kısmını oluşturan paralel provider kaydını ortadan kaldırıyor. Akılda tutulmaya değer iki uyarı var: karşılaştırma aracın kendi yazarından geldiği için bir nötr değerlendirme değil tanıtım gibi okunuyor ve konvansiyon odaklı arama, açık kaydı örtük keşifle takas ediyor — açık bağlantılandırmaya değer veren ekiplerin reddedebileceği bir takas bu. wire kod tabanı sürdüren herkes için, Go'da compile-time DI'nin nasıl görünmesi gerektiği tartışmasında en azından ciddi bir veri noktası.

  • #golang
  • #dependency-injection
  • #code-generation
  • #open-source

İlgili yazılar