আপনি যদি অ্যান্ড্রয়েড অ্যাপ ডেভেলপমেন্টের সাথে জড়িত থাকেন, তাহলে প্রজেক্টকে সম্পূর্ণ বিশৃঙ্খলার হাত থেকে বাঁচাতে আপনার ক্লাসগুলোকে আরও ভালোভাবে সাজানোর প্রয়োজন সম্ভবত অনুভব করেছেন। এখানেই... নির্ভরতা ইনজেকশনএটি একটি ডিজাইন প্যাটার্ন, যা প্রথম দর্শনে জাদুর মতো মনে হলেও, মূলত প্রতিটি ক্লাসকে তার প্রয়োজনীয় অবজেক্টগুলো সরবরাহ করার একটি উপায়, যেখানে ক্লাসটিকে নিজে থেকে সেগুলো তৈরি করতে হয় না।
ড্যাগারের জটিলতা থেকে আমাদের উদ্ধার করতে হিল্ট আবির্ভূত হয়, যা এমন একটি উপরিভাগের স্তর প্রদান করে যা নির্ভরতা সন্নিবেশকে মানসম্মত করেজেটপ্যাকের সাথে সংযুক্ত হওয়ার মাধ্যমে, হিল্ট স্বয়ংক্রিয়ভাবে কন্টেইনার এবং লাইফসাইকেল পরিচালনা করে, ফলে আমরা ঘর বদলানোর মতো করে অবজেক্ট এদিক-ওদিক না করে বিজনেস লজিকের উপর মনোযোগ দিতে পারি।
প্রাথমিক পরিবেশ কনফিগারেশন
Hilt ব্যবহার শুরু করার জন্য, প্রথম কাজটি হলো Gradle-এ ভূখণ্ড প্রস্তুত করা। এটি যোগ করা অপরিহার্য। হিল্ট-অ্যান্ড্রয়েড-গ্রেডল-প্লাগইন প্রজেক্ট-লেভেল ফাইলে। তারপর, অ্যাপ্লিকেশন মডিউল ফাইলে, আমাদের অবশ্যই প্লাগইনটি প্রয়োগ করতে হবে এবং সংশ্লিষ্ট ডিপেন্ডেন্সিগুলো যোগ করতে হবে, এবং নিশ্চিত করতে হবে যে কম্পাইলারটি (kapt বা KSP ব্যবহার করে) সঠিকভাবে কনফিগার করা আছে।
একটি বিষয় আমরা উপেক্ষা করতে পারি না যে, সবকিছু সুষ্ঠুভাবে চলার জন্য, প্রকল্পটি অবশ্যই ব্যবহারের জন্য কনফিগার করতে হবে। জাভা 17 (অথবা পুরোনো সংস্করণগুলোতে জাভা ৮), কারণ এটি Hilt-এর জন্য একটি অপরিহার্য পূর্বশর্ত। জেটপ্যাক রচনা সমন্বয়ের সাথে কাজ করুন। যদি আপনি লক্ষ্য করেন যে প্লাগইনটি সক্রিয় করার পরেও প্রোগ্রামটি কম্পাইল হচ্ছে না, তবে Kotlin এবং KSP-এর ভার্সন হুবহু এক কিনা তা পরীক্ষা করুন, কারণ সামান্য অমিলও সম্পূর্ণ কম্পাইলেশন প্রক্রিয়াটিকে ব্যাহত করতে পারে।
হিল্টের হৃদয়: আবেদন শ্রেণী
যে কোনো অ্যাপ যা এই লাইব্রেরির সুবিধা নিতে চায়, তাতে অবশ্যই একটি কাস্টম Application ক্লাস থাকতে হবে। শুধু এটি তৈরি করলেই হবে না; এটিকে অবশ্যই অ্যানোটেশন দিয়ে চিহ্নিত করতে হবে। @HiltAndroidAppএই লাইনটি Hilt-এর কোড জেনারেশন চালু করে এবং অ্যাপ্লিকেশনটির রুট কন্টেইনার তৈরি করে।
এই শীর্ষ উপাদানটি অত্যন্ত গুরুত্বপূর্ণ, কারণ এটি অ্যাপটির সামগ্রিক জীবনচক্রের সাথে যুক্ত এবং এর ভিত্তি হিসেবে কাজ করে। অন্যান্য সমস্ত উপাদান তারা এই স্তরে সংজ্ঞায়িত ডিপেন্ডেন্সিগুলো অ্যাক্সেস করতে পারবে। অবশ্যই, AndroidManifest.xml ফাইলে name অ্যাট্রিবিউট ব্যবহার করে এই ক্লাসটি রেজিস্টার করতে ভুলবেন না, নইলে Hilt একেবারেই অলক্ষিত থেকে যাবে।
অ্যান্ড্রয়েড কম্পোনেন্টগুলিতে ডিপেন্ডেন্সি যুক্ত করা
অ্যাপ্লিকেশনটি প্রস্তুত হয়ে গেলে, আমরা অ্যাক্টিভিটি, ফ্র্যাগমেন্ট, ভিউ বা সার্ভিসে ডিপেন্ডেন্সি ইনজেক্ট করা শুরু করতে পারি। এটি করার জন্য, আমরা অ্যানোটেশন ব্যবহার করি। @অ্যান্ড্রয়েডএন্ট্রিপয়েন্টএটি হিল্টকে জানিয়ে দেয় যে এই ক্লাসটি একটি এন্ট্রি পয়েন্ট এবং এর জন্য একটি নির্দিষ্ট কম্পোনেন্ট তৈরি করতে হবে।
যখন আমরা কোনো অ্যাক্টিভিটির মধ্যে একটি নির্দিষ্ট ডিপেন্ডেন্সি পেতে চাই, তখন আমরা ব্যবহার করি ফিল্ড ইনজেকশন @Inject অ্যানোটেশন ব্যবহার করে। এটা মনে রাখা খুবই গুরুত্বপূর্ণ যে এই ক্ষেত্রগুলো ব্যক্তিগত হতে পারে না।আপনি যদি `private` মডিফায়ারটি ব্যবহার করার চেষ্টা করেন, তাহলে কম্পাইলার কোনো দ্বিধা ছাড়াই একটি এরর দেখাবে। Jetpack Compose-এর ক্ষেত্রে, শুধু রুট অ্যাক্টিভিটিকে অ্যানোটেট করলেই কম্পোজেবল ফাংশনগুলোর মধ্যে সরাসরি ViewModel-গুলো অ্যাক্সেস করা যায়।
সংযোগ নির্ধারণের কৌশল
আমরা যে বস্তুগুলোর অনুরোধ করি, সেগুলো কীভাবে তৈরি করতে হয় তা হিল্টকে জানতে হবে। সবচেয়ে সরাসরি উপায় হলো... বিল্ডার ইনজেকশনযেখানে আমরা ক্লাস কনস্ট্রাক্টরের ঠিক আগে @Inject ব্যবহার করি। এভাবে, Hilt প্যারামিটারগুলো বিশ্লেষণ করে এবং সেই ডিপেন্ডেন্সিগুলোর প্রত্যেকটি কীভাবে সরবরাহ করতে হবে তা খুঁজে বের করে।
কিন্তু অবশ্যই, এমন কিছু ক্ষেত্র আছে যেখানে ক্লাসের উপর আমাদের সম্পূর্ণ নিয়ন্ত্রণ থাকে না, যেমন যখন আমরা Retrofit বা OkHttpClient-এর মতো বাহ্যিক লাইব্রেরি ব্যবহার করি। এর জন্য, আমাদের আছে... হিল্ট মডিউলএকটি মডিউল হলো @Module অ্যানোটেশনযুক্ত একটি ক্লাস এবং এতে অবশ্যই @InstallIn অন্তর্ভুক্ত থাকতে হবে, যা নির্দেশ করে যে কোন কম্পোনেন্টের সেই ডিপেন্ডেন্সিটি প্রয়োজন।
- @Provides-এর ব্যবহার: এটি তখন ব্যবহৃত হয় যখন ক্লাসটি থার্ড-পার্টি হয় অথবা এর জন্য একটি জটিল গঠন পদ্ধতির প্রয়োজন হয়। এখানে আমরা এমন একটি ফাংশন সংজ্ঞায়িত করি যা প্রয়োজনীয় ইনস্ট্যান্সটি রিটার্ন করে।
- @Binds ব্যবহার করে: যখন আমরা কোনো ইন্টারফেসকে একটি কংক্রিট ইমপ্লিমেন্টেশনের সাথে লিঙ্ক করতে চাই, তখন এটিই আদর্শ বিকল্প। এটিকে একটি অ্যাবস্ট্রাক্ট ফাংশন হিসেবে সংজ্ঞায়িত করা হয় যা Hilt-কে বলে: "যখন কেউ এই ইন্টারফেসটির জন্য অনুরোধ করবে, তখন তাকে এই ইমপ্লিমেন্টেশনটি দাও।"
পরিধি এবং জীবনচক্র ব্যবস্থাপনা
ডিফল্টরূপে, প্রতিবার কোনো ডিপেন্ডেন্সি অনুরোধ করা হলে Hilt একটি নতুন ইনস্ট্যান্স তৈরি করে। তবে, কখনও কখনও আমাদের প্রয়োজন হয় যে একটি অবজেক্ট অ্যাপ বা স্ক্রিনের জীবনকাল জুড়ে একই থাকবে। তার জন্য, আমরা ব্যবহার করি... উপাদানগুলির পরিধি.
যদি আমরা একটি ক্লাস চিহ্নিত করি @সিঙ্গেলটন আর যদি আমরা এটিকে SingletonComponent-এ ইনস্টল করি, তাহলে আমাদের একটিমাত্র গ্লোবাল ইনস্ট্যান্স থাকবে। যদি আমরা চাই যে অবজেক্টটি শুধুমাত্র অ্যাক্টিভিটির সময়কালের জন্য বিদ্যমান থাকুক, তাহলে আমরা ব্যবহার করি @ActivityScoped ActivityComponent-এর মধ্যে। স্কোপের অতিরিক্ত ব্যবহার না করা অত্যন্ত গুরুত্বপূর্ণ, কারণ অবজেক্টগুলোকে বেশিক্ষণ মেমরিতে রেখে দিলে তা শেষ পর্যন্ত অ্যাপ্লিকেশনের পারফরম্যান্সকে প্রভাবিত করতে পারে।
বিশেষ ক্ষেত্র এবং যোগ্যতা
কখনও কখনও আমাদের একই ইন্টারফেসের দুটি ভিন্ন ইমপ্লিমেন্টেশন ইনজেক্ট করার প্রয়োজন হয়। কম্পাইলারের উপর অতিরিক্ত চাপ এড়াতে, আমরা ব্যবহার করি বাছাইপর্বকোয়ালিফায়ার মূলত একটি কাস্টম অ্যানোটেশন যা একটি নির্দিষ্ট বাইন্ডিংকে লেবেল করতে ব্যবহৃত হয়, যার মাধ্যমে আমরা, উদাহরণস্বরূপ, অথেনটিকেশনের জন্য ব্যবহৃত একটি HTTP ক্লায়েন্ট এবং সাধারণ অনুরোধের জন্য ব্যবহৃত ক্লায়েন্টের মধ্যে পার্থক্য করতে পারি।
তাছাড়া, হিল্ট কিছু পূর্বনির্ধারিত কোয়ালিফায়ারের মাধ্যমে আমাদের জীবনকে আরও সহজ করে তোলে, যেমন— @ApplicationContext এবং @ActivityContext, যা আমাদেরকে এর জন্য ম্যানুয়ালি মডিউল কনফিগার না করেই অ্যান্ড্রয়েড কনটেক্সট পেতে সাহায্য করে। পরিশেষে, যেসব ক্লাস Hilt স্বাভাবিকভাবে সমর্থন করে না (যেমন ContentProviders), সেগুলোর জন্য আমরা অ্যানোটেশনটি ব্যবহার করতে পারি। @এন্ট্রি পয়েন্টহিল্ট গ্রাফ থেকে নির্ভরতাগুলো বের করার জন্য একটি ম্যানুয়াল ব্রিজ তৈরি করা হচ্ছে। তথ্যটি শেয়ার করুন, তাহলে আরও বেশি ব্যবহারকারী বিষয়টি সম্পর্কে জানতে পারবে।