ডিপেনডেন্সি ইনজেকশন (DI) হল একটি ডিজাইন প্যাটার্ন যা ইনভারশন অফ কন্ট্রোল (IoC) বাস্তবায়নের জন্য ব্যবহৃত হয় যেখানে নির্ভরতা তৈরি এবং পরিচালনার নিয়ন্ত্রণ অ্যাপ্লিকেশন থেকে একটি বহিরাগত সত্তায় স্থানান্তরিত হয়। এটি আরও মডুলার, পরীক্ষাযোগ্য এবং রক্ষণাবেক্ষণযোগ্য কোড তৈরি করতে সহায়তা করে। এটি এমন একটি কৌশল যেখানে বস্তু তৈরির দায়িত্ব কোডের অন্যান্য অংশে স্থানান্তরিত হয়। এটি ঢিলেঢালা সংযোগের প্রচার করে, কোডটিকে আরও মডুলার এবং পরিচালনা করা সহজ করে তোলে।
ক্লাসগুলিকে সঠিকভাবে কাজ করার জন্য প্রায়ই অন্যান্য ক্লাসের রেফারেন্সের প্রয়োজন হয়। উদাহরণস্বরূপ, একটি Library
ক্লাস বিবেচনা করুন যার জন্য একটি Book
ক্লাস প্রয়োজন। এই প্রয়োজনীয় শ্রেণীগুলি নির্ভরতা হিসাবে পরিচিত। Library
ক্লাস পরিচালনা করার জন্য Book
ক্লাসের একটি উদাহরণ থাকার উপর নির্ভর করে।
একটি ক্লাসের প্রয়োজনীয় বস্তুগুলি পাওয়ার জন্য তিনটি প্রাথমিক উপায় রয়েছে:
Library
ক্লাস Book
ক্লাসের নিজস্ব উদাহরণ তৈরি করবে এবং শুরু করবে।Context
getters এবং getSystemService()
, এইভাবে কাজ করে।Library
কনস্ট্রাক্টর একটি প্যারামিটার হিসাবে একটি Book
উদাহরণ পাবেন।তৃতীয় বিকল্প নির্ভরতা ইনজেকশন! ডিআই-এর মাধ্যমে, আপনি ক্লাসের ইন্সট্যান্স নিজে থেকে পাওয়ার পরিবর্তে একটি ক্লাসের নির্ভরতা প্রদান করেন।
ডিআই ছাড়া, একটি Library
যা তার নিজস্ব Book
নির্ভরতা তৈরি করে তা দেখতে এইরকম হতে পারে:
class Library { private Book book = new Book(); void open() { book.read(); } } public class Main { public static void main(String[] args) { Library library = new Library(); library.open(); } }
এটি DI এর একটি উদাহরণ নয় কারণ Library
ক্লাস তার নিজস্ব Book
তৈরি করে। এটি সমস্যাযুক্ত হতে পারে কারণ:
Library
এবং Book
শক্তভাবে মিলিত হয়। Library
একটি উদাহরণ এক ধরনের Book
ব্যবহার করে, যার ফলে সাবক্লাস বা বিকল্প বাস্তবায়ন ব্যবহার করা কঠিন হয়।Book
উপর কঠোর নির্ভরতা পরীক্ষাকে আরও চ্যালেঞ্জিং করে তোলে। Library
Book
একটি বাস্তব উদাহরণ ব্যবহার করে, বিভিন্ন পরীক্ষার ক্ষেত্রে Book
পরিবর্তন করতে পরীক্ষার দ্বিগুণ ব্যবহার রোধ করে। DI এর সাথে, Library
প্রতিটি উদাহরণ তার নিজস্ব Book
অবজেক্ট তৈরি করার পরিবর্তে, এটি তার কনস্ট্রাক্টরে একটি প্যারামিটার হিসাবে একটি Book
অবজেক্ট গ্রহণ করে:
class Library { private Book book; Library(Book book) { this.book = book; } void open() { book.read(); } } public class Main { public static void main(String[] args) { Book book = new Book(); Library library = new Library(book); library.open(); }
প্রধান ফাংশন Library
ব্যবহার করে। যেহেতু Library
Book
উপর নির্ভর করে, অ্যাপটি Book
একটি দৃষ্টান্ত তৈরি করে এবং তারপর Library
একটি উদাহরণ তৈরি করতে এটি ব্যবহার করে। এই DI-ভিত্তিক পদ্ধতির সুবিধাগুলি হল:
Library
পুনঃব্যবহারযোগ্যতা : আপনি Book
বিভিন্ন বাস্তবায়নে Library
পাস করতে পারেন। উদাহরণস্বরূপ, আপনি EBook
নামক Book
একটি নতুন সাবক্লাস সংজ্ঞায়িত করতে পারেন যা আপনি Library
ব্যবহার করতে চান। DI-এর মাধ্যমে, আপনি সহজভাবে Library
EBook
এর একটি উদাহরণ পাস করেন এবং এটি আর কোনো পরিবর্তন ছাড়াই কাজ করে।Library
সহজ পরীক্ষা : আপনি বিভিন্ন পরিস্থিতিতে পরীক্ষা করতে দ্বিগুণ পরীক্ষায় উত্তীর্ণ হতে পারেন। এমন একটি পরিস্থিতি বিবেচনা করুন যেখানে একটি NotificationService
ক্লাস একটি Notification
ক্লাসের উপর নির্ভর করে। DI ছাড়া, NotificationService
সরাসরি Notification
একটি উদাহরণ তৈরি করে, যা বিভিন্ন ধরনের বিজ্ঞপ্তি ব্যবহার করা বা বিভিন্ন বিজ্ঞপ্তি বাস্তবায়নের মাধ্যমে পরিষেবা পরীক্ষা করা কঠিন করে তোলে।
DI ব্যাখ্যা করতে, আসুন এই উদাহরণটি রিফ্যাক্টর করি:
interface Notification { void send(); } class EmailNotification implements Notification { @Override public void send() { // Send email notification } } class SMSNotification implements Notification { @Override public void send() { // Send SMS notification } } class NotificationService { void sendNotification(Notification notification) { notification.send(); } }
এখন, NotificationService
একটি নির্দিষ্ট শ্রেণীর পরিবর্তে Notification
ইন্টারফেসের উপর নির্ভর করে। এটি Notification
বিভিন্ন বাস্তবায়নকে বিনিময়যোগ্যভাবে ব্যবহার করার অনুমতি দেয়। আপনি sendNotification
পদ্ধতির মাধ্যমে ব্যবহার করতে চান এমন বাস্তবায়ন সেট করতে পারেন:
NotificationService service = new NotificationService(); service.sendNotification(new EmailNotification()); service.sendNotification(new SMSNotification());
DI এর তিনটি প্রধান প্রকার রয়েছে:
class NotificationService { private final Notification notification; public NotificationService(Notification notification) { this.notification = notification; } public void sendNotification() { notification.send(); } } public class Main { public static void main(String[] args) { NotificationService service = new NotificationService(new EmailNotification()); service.sendNotification(); } }
3. ফিল্ড ইনজেকশন (বা সেটার ইনজেকশন) : কিছু কিছু অ্যান্ড্রয়েড ফ্রেমওয়ার্ক ক্লাস, যেমন কার্যকলাপ এবং টুকরো, সিস্টেম দ্বারা তাত্ক্ষণিক করা হয়, তাই কনস্ট্রাক্টর ইনজেকশন সম্ভব নয়। ফিল্ড ইনজেকশনের সাহায্যে, ক্লাস তৈরি হওয়ার পরে নির্ভরতাগুলি তাত্ক্ষণিকভাবে তৈরি করা হয়।
class NotificationService { private Notification notification; public Notification getNotification() { return notification; } public void setNotification(Notification notification) { this.notification = notification; } public void sendNotification() { notification.send(); } } public class Main { public static void main(String[] args) { NotificationService service = new NotificationService(); service.setNotification(new EmailNotification()); service.sendNotification(); } }
4. মেথড ইনজেকশন : নির্ভরতা পদ্ধতির মাধ্যমে প্রদান করা হয়, প্রায়ই @Inject
টীকা ব্যবহার করে।
পূর্ববর্তী উদাহরণে, আপনি লাইব্রেরি ব্যবহার না করেই বিভিন্ন শ্রেণীর নির্ভরতা তৈরি, প্রদান এবং পরিচালনা করেছেন। এই পদ্ধতিটি ম্যানুয়াল নির্ভরতা ইনজেকশন হিসাবে পরিচিত। যদিও এটি সাধারণ ক্ষেত্রে কাজ করে, নির্ভরতা এবং শ্রেণির সংখ্যা বৃদ্ধির সাথে সাথে এটি কষ্টকর হয়ে ওঠে। ম্যানুয়াল নির্ভরতা ইনজেকশনের বেশ কয়েকটি ত্রুটি রয়েছে:
লাইব্রেরিগুলি আপনার জন্য নির্ভরতা তৈরি এবং প্রদান করে এই প্রক্রিয়াটিকে স্বয়ংক্রিয় করতে পারে। এই লাইব্রেরি দুটি বিভাগে পড়ে:
ড্যাগার হল জাভা, কোটলিন এবং অ্যান্ড্রয়েডের জন্য একটি জনপ্রিয় নির্ভরতা ইনজেকশন লাইব্রেরি, যা Google দ্বারা রক্ষণাবেক্ষণ করে। আপনার জন্য নির্ভরতা গ্রাফ তৈরি এবং পরিচালনা করে ড্যাগার আপনার অ্যাপে DI কে সহজ করে তোলে। এটি সম্পূর্ণরূপে স্থির, কম্পাইল-টাইম নির্ভরতা প্রদান করে, যা Guice-এর মতো প্রতিফলন-ভিত্তিক সমাধানগুলির সাথে সম্পর্কিত অনেকগুলি উন্নয়ন এবং কর্মক্ষমতা সংক্রান্ত সমস্যার সমাধান করে।
এই ফ্রেমওয়ার্কগুলি রানটাইমে নির্ভরতাকে সংযুক্ত করে:
এই ফ্রেমওয়ার্কগুলি কম্পাইলের সময়ে নির্ভরতা সংযোগ করতে কোড তৈরি করে:
নির্ভরতা ইনজেকশনের একটি বিকল্প হল পরিষেবা লোকেটার প্যাটার্ন। এই নকশা প্যাটার্নটি তাদের কংক্রিট নির্ভরতা থেকে শ্রেণীগুলিকে দ্বিগুণ করতে সহায়তা করে। আপনি পরিষেবা লোকেটার নামে পরিচিত একটি শ্রেণী তৈরি করেন যা নির্ভরতা তৈরি করে এবং সঞ্চয় করে, চাহিদা অনুযায়ী সরবরাহ করে।
object ServiceLocator { fun getProcessor(): Processor = Processor() } class Computer { private val processor = ServiceLocator.getProcessor() fun start() { processor.run() } } fun main(args: Array<String>) { val computer = Computer() computer.start() }
পরিষেবা লোকেটার প্যাটার্ন নির্ভরতা ইনজেকশন থেকে ভিন্ন হয় কিভাবে নির্ভরতা গ্রহণ করা হয়। পরিষেবা লোকেটার প্যাটার্ন সহ, ক্লাসগুলি তাদের প্রয়োজনীয় নির্ভরতাগুলির জন্য অনুরোধ করে; নির্ভরতা ইনজেকশন সহ, অ্যাপটি সক্রিয়ভাবে প্রয়োজনীয় বস্তু সরবরাহ করে।
ড্যাগার 2 অ্যান্ড্রয়েডের জন্য একটি জনপ্রিয় ডিআই ফ্রেমওয়ার্ক। এটি কম্পাইল-টাইম কোড জেনারেশন ব্যবহার করে এবং এর উচ্চ কর্মক্ষমতার জন্য পরিচিত। ড্যাগার 2 নির্ভরতা পরিচালনার জন্য প্রয়োজনীয় কোড তৈরি করে, বয়লারপ্লেট হ্রাস করে এবং দক্ষতা উন্নত করে নির্ভরতা ইনজেকশনের প্রক্রিয়াটিকে সহজ করে।
ড্যাগার 2 অ্যান্ড্রয়েডে নির্ভরতা ইনজেকশনের জন্য একটি টীকা-ভিত্তিক লাইব্রেরি। এখানে মূল টীকা এবং তাদের উদ্দেশ্য আছে:
ApiClient
প্রদান করতে পারে।@Module
এবং @Inject
সেতু করে। এটিতে সমস্ত মডিউল রয়েছে এবং অ্যাপ্লিকেশনটির জন্য নির্মাতাকে সরবরাহ করে।@Provides
এর মতো কিন্তু আরও সংক্ষিপ্ত। ড্যাগার আপনার প্রকল্পের জন্য একটি নির্ভরতা গ্রাফ তৈরি করতে পারে, যেখানে প্রয়োজন হলে নির্ভরতা কোথায় পাওয়া যায় তা নির্ধারণ করতে দেয়। এটি সক্ষম করার জন্য, আপনাকে একটি ইন্টারফেস তৈরি করতে হবে এবং এটি @Component
এর সাথে টীকা করতে হবে।
@Component
ইন্টারফেসের মধ্যে, আপনি এমন পদ্ধতিগুলি সংজ্ঞায়িত করেন যা আপনার প্রয়োজনীয় ক্লাসগুলির উদাহরণ প্রদান করে (যেমন, BookRepository
)। @Component
টীকাটি ড্যাগারকে নির্দেশ দেয় যে এটি প্রকাশ করা প্রকারগুলিকে সন্তুষ্ট করার জন্য প্রয়োজনীয় সমস্ত নির্ভরতা সহ একটি ধারক তৈরি করতে। এই ধারকটি একটি ড্যাগার উপাদান হিসাবে পরিচিত, এবং এতে বস্তুর একটি গ্রাফ রয়েছে যা ড্যাগার তাদের নির্ভরতা সহ কীভাবে সরবরাহ করতে হয় তা জানে।
আসুন একটি LibraryRepository
জড়িত একটি উদাহরণ বিবেচনা করা যাক:
LibraryRepository
কনস্ট্রাক্টরে একটি @Inject
টীকা যোগ করুন যাতে Dagger LibraryRepository
এর একটি উদাহরণ তৈরি করতে জানে। public class LibraryRepository { private final LocalLibraryDataSource localDataSource; private final RemoteLibraryDataSource remoteDataSource; @Inject public LibraryRepository(LocalLibraryDataSource localDataSource, RemoteLibraryDataSource remoteDataSource) { this.localDataSource = localDataSource; this.remoteDataSource = remoteDataSource; } }
2. টীকা নির্ভরতা : একইভাবে, নির্ভরতাগুলির ( LocalLibraryDataSource
এবং RemoteLibraryDataSource
) কনস্ট্রাক্টরগুলিকে টীকা করুন যাতে ড্যাগার সেগুলি কীভাবে তৈরি করতে হয় তা জানে৷
public class LocalLibraryDataSource { @Inject public LocalLibraryDataSource() { // Initialization code } } public class RemoteLibraryDataSource { private final LibraryService libraryService; @Inject public RemoteLibraryDataSource(LibraryService libraryService) { this.libraryService = libraryService; } }
3. উপাদান সংজ্ঞায়িত করুন : নির্ভরতা গ্রাফ সংজ্ঞায়িত করতে @Component
দিয়ে টীকাযুক্ত একটি ইন্টারফেস তৈরি করুন।
@Component public interface ApplicationComponent { LibraryRepository getLibraryRepository(); }
আপনি যখন প্রকল্পটি তৈরি করেন, তখন ড্যাগার আপনার জন্য ApplicationComponent
ইন্টারফেসের একটি বাস্তবায়ন তৈরি করে, সাধারণত DaggerApplicationComponent
নামে।
আপনি এখন স্বয়ংক্রিয়ভাবে ইনজেক্ট করা নির্ভরতা সহ আপনার ক্লাসের দৃষ্টান্তগুলি পেতে জেনারেট করা উপাদান ব্যবহার করতে পারেন:
public class MainApplication extends Application { private ApplicationComponent applicationComponent; @Override public void onCreate() { super.onCreate(); applicationComponent = DaggerApplicationComponent.create(); } public ApplicationComponent getApplicationComponent() { return applicationComponent; } }
আপনার কার্যকলাপ বা খণ্ডে, আপনি LibraryRepository
উদাহরণ পুনরুদ্ধার করতে পারেন:
public class MainActivity extends AppCompatActivity { @Inject LibraryRepository libraryRepository; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ((MainApplication) getApplication()).getApplicationComponent().inject(this); // Use the injected libraryRepository } }
1. মডিউল
∘ মডিউলের মূল ধারণা
∘ উপাদানে মডিউল সহ
2. সুযোগ
3. উপাদান
4. উপাদান নির্ভরতা
5. রানটাইম বাইন্ডিং
ড্যাগার 2-এর মডিউলগুলি @Module
সাথে টীকাযুক্ত ক্লাস যা উপাদানগুলিতে নির্ভরতা প্রদান করে। কীভাবে নির্ভরতা তৈরি এবং সরবরাহ করতে হয় তা নির্দিষ্ট করতে তারা @Provides
বা @Binds
এর সাথে টীকাযুক্ত পদ্ধতি ধারণ করে। মডিউলগুলি আপনার অ্যাপ্লিকেশনের জন্য প্রয়োজনীয় বস্তুগুলিকে সংগঠিত এবং পরিচালনা করার জন্য অপরিহার্য।
@Provides
এর চেয়ে আরও সংক্ষিপ্ত এবং মডিউলটি একটি বিমূর্ত শ্রেণী হলে ব্যবহৃত হয়।একটি মডিউলের উদাহরণ
@Module public class NetworkModule { @Provides @Singleton Retrofit provideRetrofit() { return new Retrofit.Builder() .baseUrl("https://api.example.com") .addConverterFactory(GsonConverterFactory.create()) .build(); } @Provides @Singleton OkHttpClient provideOkHttpClient() { return new OkHttpClient.Builder() .addInterceptor(new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY)) .build(); } }
এই উদাহরণে, NetworkModule
হল @Module
এর সাথে টীকাযুক্ত একটি ক্লাস। এটিতে @Provides
এর সাথে টীকাযুক্ত দুটি পদ্ধতি রয়েছে যা Retrofit
এবং OkHttpClient
এর উদাহরণ তৈরি করে এবং ফেরত দেয়।
@Binds ব্যবহার করে
যখন আপনার একটি ইন্টারফেস এবং এর বাস্তবায়ন থাকে, আপনি ইন্টারফেসে বাস্তবায়নকে আবদ্ধ করতে @Binds
ব্যবহার করতে পারেন। এটি @Provides
ব্যবহার করার চেয়ে আরও সংক্ষিপ্ত।
public interface ApiService { void fetchData(); } public class ApiServiceImpl implements ApiService { @Override public void fetchData() { // Implementation } } @Module public abstract class ApiModule { @Binds abstract ApiService bindApiService(ApiServiceImpl apiServiceImpl); }
এই উদাহরণে, ApiModule
হল একটি বিমূর্ত শ্রেণী যা @Module
এর সাথে টীকা করা হয়েছে। bindApiService
পদ্ধতিটি @Binds
এর সাথে ApiServiceImpl
ApiService
এ আবদ্ধ করতে টীকা করা হয়েছে।
মডিউলগুলি তাদের প্রদান করা কার্যকারিতার উপর ভিত্তি করে সংগঠিত করা যেতে পারে। উদাহরণস্বরূপ, নেটওয়ার্ক অপারেশন, ডাটাবেস অপারেশন এবং UI-সম্পর্কিত নির্ভরতার জন্য আপনার আলাদা মডিউল থাকতে পারে।
উদাহরণ:
Retrofit
এবং OkHttpClient
এর মত নেটওয়ার্ক-সম্পর্কিত নির্ভরতা প্রদান করে।RoomDatabase
মতো ডাটাবেস-সম্পর্কিত নির্ভরতা প্রদান করে।ViewModel
এবং Presenter
মত UI- সম্পর্কিত নির্ভরতা প্রদান করে।মডিউলগুলি তাদের প্রয়োজনীয় ক্লাসগুলিতে নির্ভরতা প্রদানের জন্য উপাদানগুলির মধ্যে অন্তর্ভুক্ত করা হয়। আপনি কিভাবে এটি সেট আপ করতে পারেন তা এখানে:
ApplicationComponent.java:
@Singleton @Component(modules = {NetworkModule.class, DatabaseModule.class}) public interface ApplicationComponent { void inject(MyApplication application); }
এই উদাহরণে, ApplicationComponent
মধ্যে রয়েছে NetworkModule
এবং DatabaseModule
অ্যাপ্লিকেশনে নির্ভরতা প্রদান করতে।
ড্যাগার 2-এ স্কোপগুলি হল টীকা যা নির্ভরতার জীবনচক্রকে সংজ্ঞায়িত করে। তারা নিশ্চিত করে যে নির্ভরতার একটি একক উদাহরণ একটি নির্দিষ্ট সুযোগের মধ্যে তৈরি এবং ভাগ করা হয়েছে। এটি মেমরিকে দক্ষতার সাথে পরিচালনা করতে এবং নির্ভরতাগুলি যেখানে উপযুক্ত সেখানে পুনরায় ব্যবহার করা হয় তা নিশ্চিত করতে সহায়তা করে।
1. সিঙ্গেলটন স্কোপ
সংজ্ঞা : @Singleton
স্কোপ নিশ্চিত করে যে একটি নির্ভরতার একটি একক দৃষ্টান্ত তৈরি করা হয়েছে এবং সমগ্র অ্যাপ্লিকেশনের জীবনচক্র জুড়ে শেয়ার করা হয়েছে।
এই সুযোগটি সাধারণত নির্ভরতাগুলির জন্য ব্যবহৃত হয় যা সমগ্র অ্যাপ্লিকেশন জুড়ে শেয়ার করা প্রয়োজন, যেমন নেটওয়ার্ক ক্লায়েন্ট, ডাটাবেস উদাহরণ, বা ভাগ করা পছন্দগুলি।
উদাহরণ:
@Singleton @Component(modules = {NetworkModule.class, DatabaseModule.class}) public interface ApplicationComponent { void inject(MyApplication application); }
এই উদাহরণে, @Singleton
টীকা নিশ্চিত করে যে NetworkModule
এবং DatabaseModule
দ্বারা প্রদত্ত Retrofit
এবং Database
দৃষ্টান্তগুলি একক এবং সমগ্র অ্যাপ্লিকেশন জুড়ে শেয়ার করা হয়েছে।
2. কার্যকলাপের সুযোগ
সংজ্ঞা : @ActivityScope
(একটি কাস্টম স্কোপ) নিশ্চিত করে যে একটি নির্ভরতার একটি একক দৃষ্টান্ত একটি কার্যকলাপের জীবনচক্রের মধ্যে তৈরি এবং ভাগ করা হয়েছে।
এই সুযোগটি এমন নির্ভরতাগুলির জন্য উপযোগী যেগুলি একটি কার্যকলাপের জন্য নির্দিষ্ট এবং প্রতিবার ক্রিয়াকলাপটি পুনরায় তৈরি করার সময় পুনরায় তৈরি করা উচিত, যেমন উপস্থাপক বা মডেলগুলি দেখুন৷
উদাহরণ :
@Scope @Retention(RetentionPolicy.RUNTIME) public @interface ActivityScope { } @ActivityScope @Component(dependencies = ApplicationComponent.class, modules = ActivityModule.class) public interface ActivityComponent { void inject(MainActivity mainActivity); }
এই উদাহরণে, @ActivityScope
টীকা নিশ্চিত করে যে ActivityModule
দ্বারা প্রদত্ত নির্ভরতাগুলি কার্যকলাপের জীবনচক্রের জন্য স্কোপ করা হয়েছে।
3. ফ্র্যাগমেন্ট স্কোপ
সংজ্ঞা : @FragmentScope
(অন্য কাস্টম স্কোপ) নিশ্চিত করে যে একটি নির্ভরতার একটি একক দৃষ্টান্ত তৈরি করা হয়েছে এবং একটি খণ্ডের জীবনচক্রের মধ্যে ভাগ করা হয়েছে।
কেস ব্যবহার করুন: এই সুযোগটি এমন নির্ভরতাগুলির জন্য উপযোগী যেগুলি একটি খণ্ডের জন্য নির্দিষ্ট এবং প্রতিবার খণ্ডটি পুনরায় তৈরি করার সময় পুনরায় তৈরি করা উচিত, যেমন খণ্ড-নির্দিষ্ট উপস্থাপক বা ভিউ মডেল৷
উদাহরণ :
@Scope @Retention(RetentionPolicy.RUNTIME) public @interface FragmentScope { } @FragmentScope @Component(dependencies = ActivityComponent.class, modules = FragmentModule.class) public interface FragmentComponent { void inject(MyFragment myFragment); }
এই উদাহরণে, @FragmentScope
টীকাটি নিশ্চিত করে যে FragmentModule
দ্বারা প্রদত্ত নির্ভরতাগুলি ফ্র্যাগমেন্টের জীবনচক্রে স্কোপ করা হয়েছে।
উপাদান নির্ভরতা একটি উপাদানকে অন্যটির উপর নির্ভর করার অনুমতি দেয়, নির্ভরতাগুলির পুনঃব্যবহার সক্ষম করে। দুটি প্রধান ধরনের উপাদান নির্ভরতা আছে:
1. অ্যাপ্লিকেশন উপাদান
সংজ্ঞা : অ্যাপ্লিকেশন উপাদান নির্ভরতা প্রদান করে যা সমগ্র অ্যাপ্লিকেশন জুড়ে প্রয়োজন। নির্ভরতাগুলি অ্যাপ্লিকেশন জুড়ে ভাগ করা হয়েছে তা নিশ্চিত করার জন্য এটি সাধারণত @Singleton
এর সাথে স্কোপ করা হয়।
এই উপাদানটি নির্ভরতাগুলির জন্য ব্যবহৃত হয় যা বিশ্বব্যাপী উপলব্ধ হওয়া প্রয়োজন, যেমন নেটওয়ার্ক ক্লায়েন্ট, ডাটাবেস উদাহরণ, বা ভাগ করা পছন্দগুলি।
উদাহরণ :
@Singleton @Component(modules = {NetworkModule.class, DatabaseModule.class}) public interface ApplicationComponent { void inject(MyApplication application); }
এই উদাহরণে, ApplicationComponent
Retrofit
এবং Database
উদাহরণ প্রদানের জন্য দায়ী, যা সমগ্র অ্যাপ্লিকেশন জুড়ে ভাগ করা হয়।
2. কার্যকলাপ উপাদান
সংজ্ঞা : কার্যকলাপ উপাদান একটি নির্দিষ্ট কার্যকলাপের মধ্যে প্রয়োজনীয় নির্ভরতা প্রদান করে। এটি সাধারণত @ActivityScope
এর মতো একটি কাস্টম স্কোপের সাথে স্কোপ করা হয়, যাতে প্রতিবার ক্রিয়াকলাপটি পুনরায় তৈরি করার সময় নির্ভরতাগুলি পুনরায় তৈরি করা হয়।
এই উপাদানটি নির্ভরতাগুলির জন্য ব্যবহৃত হয় যা একটি কার্যকলাপের জন্য নির্দিষ্ট, যেমন উপস্থাপক বা দৃশ্য মডেল।
উদাহরণ :
@ActivityScope @Component(dependencies = ApplicationComponent.class, modules = ActivityModule.class) public interface ActivityComponent { void inject(MainActivity mainActivity); }
এই উদাহরণে, ActivityComponent
ApplicationComponent
উপর নির্ভর করে এবং MainActivity
এর জন্য নির্দিষ্ট নির্ভরতা প্রদান করে।
উপাদান নির্ভরতা একটি উপাদানকে অন্যটির উপর নির্ভর করার অনুমতি দেয়, নির্ভরতাগুলির পুনঃব্যবহার সক্ষম করে। দুটি প্রধান ধরনের উপাদান নির্ভরতা আছে:
1. উপ উপাদান:
একটি সাবকম্পোনেন্ট হল অন্য একটি উপাদানের একটি শিশু এবং তার পিতামাতার নির্ভরতা অ্যাক্সেস করতে পারে। উপ-কম্পোনেন্টগুলি মূল উপাদানের মধ্যে সংজ্ঞায়িত করা হয় এবং এর সুযোগ উত্তরাধিকারসূত্রে পেতে পারে।
উদাহরণ :
@ActivityScope @Subcomponent(modules = ActivityModule.class) public interface ActivitySubcomponent { void inject(MainActivity mainActivity); }
এই উদাহরণে, ActivitySubcomponent
হল প্যারেন্ট কম্পোনেন্টের একটি সাবকম্পোনেন্ট এবং এটির নির্ভরতা অ্যাক্সেস করতে পারে।
2. নির্ভরতা বৈশিষ্ট্য
এটি একটি কম্পোনেন্টকে সাবকম্পোনেন্ট না হয়ে অন্য কম্পোনেন্টের উপর নির্ভর করতে দেয়। নির্ভরশীল উপাদান অভিভাবক উপাদান দ্বারা প্রদত্ত নির্ভরতা অ্যাক্সেস করতে পারে।
উদাহরণ :
@ActivityScope @Component(dependencies = ApplicationComponent.class, modules = ActivityModule.class) public interface ActivityComponent { void inject(MainActivity mainActivity); }
এই উদাহরণে, ActivityComponent
ApplicationComponent
উপর নির্ভর করে এবং এর নির্ভরতা অ্যাক্সেস করতে পারে।
ড্যাগার 2-এ রানটাইম বাইন্ডিংগুলি নির্ভরতাগুলির বিধানকে নির্দেশ করে যা রানটাইমে তৈরি এবং পরিচালিত হয়, যে প্রেক্ষাপটে তাদের প্রয়োজন তার উপর ভিত্তি করে।
1. অ্যাপ্লিকেশন প্রসঙ্গ
সংজ্ঞা : অ্যাপ্লিকেশন প্রসঙ্গ হল একটি প্রসঙ্গ যা সমগ্র অ্যাপ্লিকেশনের জীবনচক্রের সাথে আবদ্ধ। এটি নির্ভরতাগুলির জন্য ব্যবহৃত হয় যেগুলি অ্যাপ্লিকেশনটির মতোই বেঁচে থাকতে হবে।
নির্ভরতা যা সমগ্র অ্যাপ্লিকেশন জুড়ে ভাগ করা হয়েছে এবং প্রতিটি কার্যকলাপ বা খণ্ডের জন্য পুনরায় তৈরি করার প্রয়োজন নেই। উদাহরণগুলির মধ্যে রয়েছে নেটওয়ার্ক ক্লায়েন্ট, ডাটাবেস দৃষ্টান্ত এবং ভাগ করা পছন্দগুলি।
উদাহরণ :
@Module public class AppModule { private final Application application; public AppModule(Application application) { this.application = application; } @Provides @Singleton Application provideApplication() { return application; } @Provides @Singleton Context provideApplicationContext() { return application.getApplicationContext(); } }
এই উদাহরণে, AppModule
একটি সিঙ্গলটন নির্ভরতা হিসাবে অ্যাপ্লিকেশন প্রসঙ্গ প্রদান করে। provideApplicationContext
পদ্ধতি নিশ্চিত করে যে প্রদত্ত প্রসঙ্গটি অ্যাপ্লিকেশনের জীবনচক্রের সাথে আবদ্ধ।
2. কার্যকলাপের প্রসঙ্গ
সংজ্ঞা : কার্যকলাপের প্রসঙ্গ একটি প্রসঙ্গ যা একটি নির্দিষ্ট কার্যকলাপের জীবনচক্রের সাথে আবদ্ধ। এটি নির্ভরতাগুলির জন্য ব্যবহৃত হয় যা ক্রিয়াকলাপ হিসাবে দীর্ঘকাল বেঁচে থাকতে হবে।
নির্ভরতা যা একটি কার্যকলাপের জন্য নির্দিষ্ট এবং প্রতিবার ক্রিয়াকলাপটি পুনরায় তৈরি করার সময় পুনরায় তৈরি করা উচিত। উদাহরণগুলির মধ্যে রয়েছে ভিউ মডেল, উপস্থাপক এবং UI- সম্পর্কিত নির্ভরতা।
উদাহরণ :
@Module public class ActivityModule { private final Activity activity; public ActivityModule(Activity activity) { this.activity = activity; } @Provides @ActivityScope Activity provideActivity() { return activity; } @Provides @ActivityScope Context provideActivityContext() { return activity; } }
এই উদাহরণে, ActivityModule
একটি স্কোপড নির্ভরতা হিসাবে কার্যকলাপের প্রসঙ্গ প্রদান করে। provideActivityContext
পদ্ধতি নিশ্চিত করে যে প্রদত্ত প্রসঙ্গটি কার্যকলাপের জীবনচক্রের সাথে আবদ্ধ।
এই রানটাইম বাইন্ডিংগুলি ব্যবহার করতে, আপনাকে আপনার উপাদানগুলিতে সংশ্লিষ্ট মডিউলগুলি অন্তর্ভুক্ত করতে হবে:
অ্যাপ্লিকেশন উপাদান :
@Singleton @Component(modules = {AppModule.class, NetworkModule.class}) public interface ApplicationComponent { void inject(MyApplication application); Context getApplicationContext(); }
কার্যকলাপ উপাদান :
@ActivityScope @Component(dependencies = ApplicationComponent.class, modules = ActivityModule.class) public interface ActivityComponent { void inject(MainActivity mainActivity); Context getActivityContext(); }
ইনজেকশন প্রসঙ্গ
একবার আপনি আপনার উপাদান এবং মডিউল সেট আপ করার পরে, আপনি প্রসঙ্গগুলিকে আপনার ক্লাসে প্রয়োজন অনুসারে ইনজেক্ট করতে পারেন।
একটি কার্যকলাপের উদাহরণ :
public class MainActivity extends AppCompatActivity { @Inject Context activityContext; @Inject Context applicationContext; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ApplicationComponent appComponent = ((MyApplication) getApplication()).getApplicationComponent(); ActivityComponent activityComponent = DaggerActivityComponent.builder() .applicationComponent(appComponent) .activityModule(new ActivityModule(this)) .build(); activityComponent.inject(this); // Use the injected contexts Log.d("MainActivity", "Activity Context: " + activityContext); Log.d("MainActivity", "Application Context: " + applicationContext); } }
এই উদাহরণে, MainActivity
নির্ভরতা ইনজেকশনের মাধ্যমে কার্যকলাপের প্রসঙ্গ এবং অ্যাপ্লিকেশন প্রসঙ্গ উভয়ই গ্রহণ করে। এটি নির্ভরতাগুলির নির্দিষ্ট চাহিদার উপর ভিত্তি করে উপযুক্ত প্রসঙ্গ ব্যবহার করার জন্য কার্যকলাপকে অনুমতি দেয়।
আপনার প্রকল্পে ড্যাগার 2 ব্যবহার করতে, আপনাকে আপনার build.gradle
ফাইলে নিম্নলিখিত নির্ভরতা যোগ করতে হবে:
dependencies { implementation 'com.google.dagger:dagger:2.x' annotationProcessor 'com.google.dagger:dagger-compiler:2.x' }
Dagger 2 এর সর্বশেষ সংস্করণ দিয়ে 2.x
প্রতিস্থাপন করুন।
নির্ভরতা প্রদানের জন্য একটি মডিউল তৈরি করুন। উদাহরণস্বরূপ, একটি Retrofit
উদাহরণ প্রদান করার জন্য একটি NetworkModule
:
@Module public class NetworkModule { @Provides @Singleton Retrofit provideRetrofit() { return new Retrofit.Builder() .baseUrl("https://api.example.com") .addConverterFactory(GsonConverterFactory.create()) .build(); } }
মডিউল এবং নির্ভরতা প্রয়োজন এমন ক্লাসগুলি ব্রিজ করার জন্য একটি উপাদান তৈরি করুন:
@Singleton @Component(modules = {NetworkModule.class}) public interface ApplicationComponent { void inject(MyApplication application); }
আপনার ক্লাসে নির্ভরতা ইনজেক্ট করতে উপাদানটি ব্যবহার করুন। উদাহরণস্বরূপ, আপনার Application
ক্লাসে:
public class MyApplication extends Application { private ApplicationComponent applicationComponent; @Override public void onCreate() { super.onCreate(); applicationComponent = DaggerApplicationComponent.builder() .networkModule(new NetworkModule()) .build(); applicationComponent.inject(this); } public ApplicationComponent getApplicationComponent() { return applicationComponent; } }
এখন আপনি আপনার ক্লাসে ইনজেকশন নির্ভরতা ব্যবহার করতে পারেন। উদাহরণস্বরূপ, একটি Activity
:
public class MainActivity extends AppCompatActivity { @Inject Retrofit retrofit; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ((MyApplication) getApplication()).getApplicationComponent().inject(this); // Use the injected Retrofit instance // ... } }
আসুন এই বিষয়টি সংক্ষিপ্ত করা যাক: