Dependency Injection (DI) হল একটি ডিজাইন প্যাটার্ন যা অ্যাপ্লিকেশনের কোডে ডিপেন্ডেন্সির (অথবা বাহ্যিক অবজেক্ট) ইনজেকশন বা সরবরাহকে সহজতর করে। এর মাধ্যমে কোডের পুনঃব্যবহারযোগ্যতা, টেস্টেবলিটি এবং ডিকাপলিং বৃদ্ধি পায়। Zend Framework (এখন Laminas) এ Dependency Injection ব্যবহারের মাধ্যমে কোডের গঠন এবং নির্ভরশীলতা আরও পরিষ্কার এবং কার্যকরী হয়।
এই লেখায় আমরা Dependency Injection এর কনসেপ্ট এবং Zend Framework এ এর প্রয়োগ নিয়ে আলোচনা করব।
১. Dependency Injection কনসেপ্ট
Dependency Injection হল একটি টেকনিক যেখানে একটি ক্লাস তার প্রয়োজনীয় ডিপেন্ডেন্সি (অথবা অন্য ক্লাসের অবজেক্ট) সরাসরি তৈরি না করে, বরং বাহ্যিকভাবে ইনজেক্ট করে নেয়। এর ফলে ক্লাসটি তার নির্ভরশীলতার ব্যাপারে স্বাধীন এবং পরীক্ষা করা সহজ হয়।
ডিপেন্ডেন্সি ইনজেকশন তিনটি প্রধান উপায়ে করা যায়:
- Constructor Injection: ক্লাসের কনস্ট্রাক্টরে ডিপেন্ডেন্সি পাস করা হয়।
- Setter Injection: মেথড ব্যবহার করে ডিপেন্ডেন্সি সেট করা হয়।
- Interface Injection: ইন্টারফেসের মাধ্যমে ডিপেন্ডেন্সি ইনজেক্ট করা হয়।
২. Zend Framework এ Dependency Injection
Zend Framework এ Dependency Injection ব্যবস্থাপনা করার জন্য Zend\ServiceManager ব্যবহৃত হয়। এটি একটি সার্ভিস কন্টেইনার যা আপনার অ্যাপ্লিকেশনের ডিপেন্ডেন্সিগুলিকে ম্যানেজ করে এবং সেগুলি সরবরাহ করে।
২.১. Zend\ServiceManager কনফিগারেশন
Zend Framework এর Dependency Injection ব্যবস্থাপনার জন্য Zend\ServiceManager সার্ভিস কন্টেইনার ব্যবহার করা হয়। সার্ভিস কন্টেইনার মূলত একটি অ্যাবজেক্ট কন্টেইনার যেখানে আপনার প্রয়োজনীয় সার্ভিস এবং ডিপেন্ডেন্সিগুলো রেজিস্টার করা থাকে। সার্ভিস কন্টেইনার এ ডিপেন্ডেন্সিগুলোর ইনজেকশন সহজ করে দেয়।
২.১.১. সার্ভিস কন্টেইনার কনফিগারেশন ফাইল
একটি সাধারণ কনফিগারেশন ফাইলে service_manager এর অধীনে আপনার সার্ভিস এবং ডিপেন্ডেন্সি রেজিস্টার করতে হবে।
config/module.config.php:
<?php
namespace MyModule;
return [
'service_manager' => [
'factories' => [
'MyModule\Service\SomeService' => 'MyModule\Factory\SomeServiceFactory',
],
],
];
এখানে, MyModule\Service\SomeService সার্ভিসটি একটি factory এর মাধ্যমে তৈরি করা হবে, যা ডিপেন্ডেন্সি ইনজেকশন পরিচালনা করবে।
৩. Dependency Injection প্রয়োগ
এখন আমরা দেখব কীভাবে Zend Framework এ Dependency Injection প্রয়োগ করা হয়। আমরা একটি কেস স্টাডি তৈরি করব যেখানে একটি Controller একটি সার্ভিস ব্যবহার করবে এবং এই সার্ভিসটি DI এর মাধ্যমে ইনজেক্ট করা হবে।
৩.১. সার্ভিস ক্লাস তৈরি
প্রথমে, আমরা একটি সার্ভিস ক্লাস তৈরি করব যা কিছু ব্যবসায়িক লজিক প্রক্রিয়া করবে।
module/MyModule/src/Service/SomeService.php:
<?php
namespace MyModule\Service;
class SomeService
{
public function getMessage()
{
return "Hello from SomeService!";
}
}
এটি একটি সিম্পল সার্ভিস ক্লাস যা একটি মেসেজ রিটার্ন করে।
৩.২. সার্ভিস ফ্যাক্টরি তৈরি
এখন, সার্ভিস কনটেইনারের মাধ্যমে SomeService ক্লাস ইনস্ট্যানশিয়েট করতে একটি ফ্যাক্টরি তৈরি করতে হবে।
module/MyModule/src/Factory/SomeServiceFactory.php:
<?php
namespace MyModule\Factory;
use MyModule\Service\SomeService;
use Laminas\ServiceManager\Factory\FactoryInterface;
use Interop\Container\ContainerInterface;
class SomeServiceFactory implements FactoryInterface
{
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
return new SomeService();
}
}
এখানে, SomeServiceFactory ক্লাসটি FactoryInterface ইমপ্লিমেন্ট করে এবং SomeService ক্লাসের ইনস্ট্যান্স তৈরি করে।
৩.৩. কন্ট্রোলার তৈরি
এখন, একটি কন্ট্রোলার তৈরি করা যাক, যেটি SomeService সার্ভিসটি ব্যবহার করবে। এখানে SomeService সার্ভিসটি কনস্ট্রাক্টর ইনজেকশন এর মাধ্যমে কন্ট্রোলারে ইনজেক্ট করা হবে।
module/MyModule/src/Controller/IndexController.php:
<?php
namespace MyModule\Controller;
use Laminas\Mvc\Controller\AbstractActionController;
use Laminas\View\Model\ViewModel;
use MyModule\Service\SomeService;
class IndexController extends AbstractActionController
{
protected $someService;
public function __construct(SomeService $someService)
{
$this->someService = $someService;
}
public function indexAction()
{
return new ViewModel([
'message' => $this->someService->getMessage()
]);
}
}
এখানে, SomeService কন্ট্রোলারের কনস্ট্রাক্টরে ইনজেক্ট করা হচ্ছে। কন্ট্রোলারের indexAction() মেথডে আমরা সার্ভিসের getMessage() মেথড কল করে মেসেজ রিটার্ন করছি।
৩.৪. সার্ভিস কন্টেইনারে কন্ট্রোলার রেজিস্টার করা
এখন, কন্ট্রোলারটি Zend\ServiceManager সার্ভিস কন্টেইনারে রেজিস্টার করতে হবে, যাতে DI এর মাধ্যমে SomeService ইনজেক্ট করা যায়।
config/module.config.php:
<?php
namespace MyModule;
return [
'controllers' => [
'factories' => [
'MyModule\Controller\Index' => function($container) {
$someService = $container->get('MyModule\Service\SomeService');
return new \MyModule\Controller\IndexController($someService);
},
],
],
'service_manager' => [
'factories' => [
'MyModule\Service\SomeService' => 'MyModule\Factory\SomeServiceFactory',
],
],
];
এখানে, IndexController ক্লাসটি কনস্ট্রাক্টরের মাধ্যমে SomeService ইনজেক্ট করছে এবং এই সার্ভিসটি কন্ট্রোলারের ফ্যাক্টরি মেথডে সরবরাহ করা হচ্ছে।
৪. সার্ভিস কন্টেইনার এবং Dependency Injection
Zend Framework এর Zend\ServiceManager সার্ভিস কন্টেইনার ব্যবহার করে Dependency Injection খুবই সহজ এবং কার্যকরীভাবে পরিচালনা করা যায়। সার্ভিস কন্টেইনারের মাধ্যমে ডিপেন্ডেন্সিগুলোর তৈরি, পরিচালনা এবং ইনজেকশন আরও মডুলার এবং পরিষ্কার হয়। এর মাধ্যমে কোডের টেস্টিং সহজ হয়, কারণ আপনি যে ক্লাসটি টেস্ট করতে চান, সেটি ডিপেন্ডেন্সি হিসেবে আলাদা সার্ভিস ইনজেক্ট করে টেস্ট করা সম্ভব।
সারাংশ
Dependency Injection (DI) ডিজাইন প্যাটার্নটি Zend Framework (এখন Laminas) এ কোডের ডিপেন্ডেন্সিগুলো ম্যানেজ করার জন্য খুবই গুরুত্বপূর্ণ। Zend\ServiceManager সার্ভিস কন্টেইনার ব্যবহার করে আমরা সহজে ডিপেন্ডেন্সিগুলো ইনজেক্ট এবং ম্যানেজ করতে পারি। এর মাধ্যমে কোডের পুনঃব্যবহারযোগ্যতা, টেস্টযোগ্যতা এবং মডুলারিটি বাড়ে। DI ব্যবহারে অ্যাপ্লিকেশনটি আরও সুসংগঠিত, পরিষ্কার এবং স্কেলেবল হয়ে ওঠে।
Read more