विषय पर बढ़ें

अंतिम अद्यतन:2026-10-12

C++ डिपेंडेंसी इंजेक्शन

हाल ही में प्रीमियम कम्युनिटी के एक सदस्य ने डिपेंडेंसी इंजेक्शन पर सामग्री अपडेट करने को कहा, तो यह लेख लिखा गया — वास्तविक उदाहरणों से समझाया गया है; इसमें कुछ सिद्धांत तथा कार्यान्वयन शामिल हैं, और पूरे कार्यान्वयन का सरल संस्करण प्रीमियम कम्युनिटी में रखा गया है। चलिए मुख्य विषय से शुरू करते हैं।

रूपरेखा:

  • प्रत्यक्ष निर्भरता (direct dependency)
  • इंटरफ़ेस डिपेंडेंसी इंजेक्शन
  • टेम्प्लेट डिपेंडेंसी इंजेक्शन

डिपेंडेंसी इंजेक्शन एक सामान्यतः प्रयुक्त डिज़ाइन पैटर्न है, जिसमें प्रायः इंटरफ़ेस/टेम्प्लेट का तरीका अपनाकर कोड की परीक्षणक्षमता (testability) तथा अनुरक्षणक्षमता (maintainability) बढ़ाई जाती है; नीचे एक उदाहरण देखते हैं।

मान लीजिए एक यूज़र सर्विस क्लास UserService है, जिसे HTTP क्लाइंट के माध्यम से रिमोट सर्वर से संवाद करना है; ऐसी स्थिति में हम निम्नलिखित तीन प्रकार के कार्यान्वयन लिख सकते हैं।

1.प्रत्यक्ष निर्भरता

UserService के भीतर सीधे HttpClient की निर्भरता है, उदाहरण के लिए:

class HttpClient {
 public:
  std::string Get(const std::string& url);
  void Post(const std::string& url, const std::string& data);
};

class UserService {
 private:
  HttpClient m_httpClient;
};

UserService के भीतर प्रायः m_httpClient को चलाने वाली कुछ विधियाँ होती हैं। यह तरीका सीधा-सादा है, परंतु इसमें UserService विशिष्ट HttpClient से जुड़ जाता है, जिससे निर्भर ऑब्जेक्ट बदलना कठिन हो जाता है और यूनिट टेस्ट करना भी कठिन।

इसी से आगे के दो तरीके निकले।

2.इंटरफ़ेस डिपेंडेंसी इंजेक्शन

हमारा लक्ष्य है कि परीक्षण के समय सुविधाजनक ढंग से परीक्षण हो सके, बिना विशिष्ट क्लास बनाए — उपयोगकर्ता एक mock क्लास बनाकर परीक्षण कर सके। इसके लिए हमें इंटरफ़ेस का ध्यान आता है; HttpClient को अलग निकालकर पाते हैं:

struct IHttpClient {
  virtual std::string Get(const std::string& url) = 0;
  virtual void Post(const std::string& url, const std::string& data) = 0;
  virtual ~IHttpClient() = default;
};
class UserService {
 private:
  std::unique_ptr<IHttpClient> m_httpClient;
};

तब परीक्षण के समय एक client mock करके परीक्षण किया जा सकता है, उदाहरण के लिए:

class MockHttpClient : public IHttpClient {
public:
  MOCK_METHOD(std::string, Get, (const std::string& url), (override));
  MOCK_METHOD(void, Post, (const std::string& url, const std::string& data), (override));
};

auto mockHttpClient = std::make_unique<MockHttpClient>();
UserService userService(std::move(mockHttpClient));

उपरोक्त परिवर्तनों के बाद, हम यह कर सकते हैं:

  • .cc फ़ाइल में कार्यान्वयन विवरण छिपाना
  • एब्स्ट्रैक्ट इंटरफ़ेस पर काम करना
  • ऑब्जेक्ट के निर्माण के दौरान निर्भरताएँ इंजेक्ट करना

3.टेम्प्लेट डिपेंडेंसी इंजेक्शन

टेम्प्लेट डिपेंडेंसी इंजेक्शन, C++ टेम्प्लेट तकनीक द्वारा निर्भर ऑब्जेक्ट को टेम्प्लेट पैरामीटर के रूप में UserService को पास करता है। टेम्प्लेट के इंस्टैंशिएशन के समय विशिष्ट HTTP क्लाइंट कार्यान्वयन निर्दिष्ट किया जाता है। यह तरीका संकलन के समय ही निर्भरता समस्या हल कर देता है — वर्चुअल फंक्शन कॉल की आवश्यकता नहीं, जिससे प्रदर्शन बढ़ता है। साथ ही, UserService क्लास विभिन्न HTTP क्लाइंट कार्यान्वयनों के साथ लचीले ढंग से जुड़ सकती है तथा यूनिट टेस्ट करना भी सरल है।

template <typename THttpClient>
class UserService {
 private:
  THttpClient m_httpClient;
};

इस स्थिति में परीक्षण करना अपेक्षाकृत सरल है, उदाहरण के लिए:

UserService<MockHttpClient> userService;

इस तरीके के निम्नलिखित लाभ हैं:

  • टेम्प्लेट इंस्टैंशिएशन के दौरान निर्भरताएँ इंजेक्ट करना
  • वर्चुअल कॉल की आवश्यकता नहीं (ध्यान दें — THttpClient इंटरफ़ेस नहीं है, इसलिए कॉल संकलन के समय ही निर्धारित हो जाती है)

यही इस अनुभाग की सारी सामग्री थी; इस अनुभाग का पूरा कोड प्रीमियम कम्युनिटी में रखा गया है — सदस्यता लेकर डाउनलोड करने के लिए आपका स्वागत है!

संबंधित विषय

टिप्पणियाँ