Go के लिए Dependency Injection कंटेनर: Wire, Dig और Uber FX

शुरुआती लोगों के लिए ऑनलाइन Python प्रशिक्षक

Python आसानी से सीखें बिना सिद्धांत के बोझ के। स्वचालित जांच के साथ व्यावहारिक कार्य हल करें और ब्राउज़र में सीधे कोड लिखें।

पाठ्यक्रम शुरू करें

Go (Golang) के लिए Dependency Injection कंटेनर: Wire, Dig और Uber FX

Dependency Injection (DI) एक डिज़ाइन पैटर्न है जिसमें कोई ऑब्जेक्ट अपनी ज़रूरतों (डिपेंडेंसी) को खुद नहीं बनाता, बल्कि बाहर से प्राप्त करता है। Go (Golang) में DI का उपयोग मॉड्यूलर, टेस्ट करने योग्य और स्केलेबल कोड बनाने के लिए किया जाता है। Go के लिए सबसे लोकप्रिय DI टूल Google Wire, Uber Dig और Uber FX हैं। इस लेख में हम इन तीनों की विशेषताओं और उपयोग के उदाहरणों को विस्तार से देखेंगे।

Go में Dependency Injection की आवश्यकता क्यों?

Go एक स्टैटिकली टाइप की गई भाषा है जिसमें पैरामीटर स्पष्ट रूप से पास किए जाते हैं। DI के बिना, डेवलपर्स अक्सर ग्लोबल वेरिएबल या फैक्ट्री बनाते हैं, जिससे टेस्टिंग और मेंटेनेंस मुश्किल हो जाता है। DI कंटेनर इन समस्याओं को हल करते हैं:

  • कमजोर कपलिंग (Loose Coupling) — कंपोनेंट्स इंटरफेस पर निर्भर होते हैं, न कि कंक्रीट इम्प्लीमेंटेशन पर।
  • टेस्टेबिलिटी — डिपेंडेंसी को आसानी से मॉक से बदला जा सकता है।
  • कॉन्फ़िगरेशन सरल बनाना — कंटेनर ऑटोमैटिकली डिपेंडेंसी ग्राफ को हल करता है।

Google Wire — कंपाइल टाइम पर कोड जनरेशन

Wire (Google द्वारा) एक runtime कंटेनर नहीं है, बल्कि कोड जनरेटर है। यह कंस्ट्रक्टर फंक्शन का विश्लेषण करता है और कंपाइल टाइम पर डिपेंडेंसी को जोड़ने के लिए कोड जनरेट करता है। इससे runtime पर कोई ओवरहेड नहीं होता और एरर जल्दी पकड़ में आ जाते हैं।

Wire इंस्टॉल करना

go install github.com/google/wire/cmd/wire@latest

Wire का उपयोग उदाहरण

मान लीजिए हमारे पास एक सर्विस है जो डेटाबेस और लॉगर पर निर्भर है:

// main.go
package main

import "fmt"

type Logger struct{}

func NewLogger() Logger { return Logger{} }

func (l Logger) Log(msg string) { fmt.Println(msg) }

type Database struct {
    logger Logger
}

func NewDatabase(logger Logger) Database {
    return Database{logger: logger}
}

type Service struct {
    db  Database
    log Logger
}

func NewService(db Database, log Logger) Service {
    return Service{db: db, log: log}
}

अब Wire के लिए wire.go फ़ाइल बनाएं:

// wire.go
//go:build wireinject
// +build wireinject

package main

import "github.com/google/wire"

func InitializeService() Service {
    wire.Build(NewLogger, NewDatabase, NewService)
    return Service{}
}

जनरेशन चलाएं:

wire

Wire एक wire_gen.go फ़ाइल बनाएगा जिसमें इनिशियलाइज़ेशन कोड होगा:

// wire_gen.go
// Code generated by Wire. DO NOT EDIT.

package main

func InitializeService() Service {
    logger := NewLogger()
    database := NewDatabase(logger)
    service := NewService(database, logger)
    return service
}

Wire के फायदे:

  • कंपाइल टाइम पर एरर पकड़ना।
  • कोई reflection नहीं, उच्च प्रदर्शन।
  • सरल और अनुमानित कोड।

Wire के नुकसान:

  • अलग से जनरेशन स्टेप की आवश्यकता।
  • डायनामिक डिपेंडेंसी के साथ उपयोग करना मुश्किल।

Uber Dig — reflection के साथ runtime कंटेनर

Dig (Uber द्वारा) एक runtime कंटेनर है जो reflection का उपयोग करके टाइप का विश्लेषण करता है और ऑटोमैटिकली डिपेंडेंसी को हल करता है। Dig एक सरल API प्रदान करता है जिसमें कंस्ट्रक्टर रजिस्टर करना और ऑब्जेक्ट प्राप्त करना शामिल है।

Dig इंस्टॉल करना

go get go.uber.org/dig

Dig का उपयोग उदाहरण

package main

import (
    "fmt"
    "go.uber.org/dig"
)

type Config struct {
    Port int
}

func NewConfig() *Config {
    return &Config{Port: 8080}
}

type Server struct {
    config *Config
}

func NewServer(c *Config) *Server {
    return &Server{config: c}
}

func (s *Server) Start() {
    fmt.Printf("Server started on port %d\n", s.config.Port)
}

func main() {
    container := dig.New()

    // कंस्ट्रक्टर रजिस्टर करें                    

अनुशंसाएँ