একটি অ্যান্ড্রয়েড অ্যাপে ম্যানুয়াল নির্ভরতা ইনজেকশন বা পরিষেবা লোকেটারগুলি আপনার প্রকল্পের আকারের উপর নির্ভর করে সমস্যাযুক্ত হতে পারে। নির্ভরতা পরিচালনার জন্য ড্যাগার ব্যবহার করে আপনি আপনার প্রকল্পের জটিলতা সীমাবদ্ধ করতে পারেন কারণ এটি বৃদ্ধি পায়।
ড্যাগার স্বয়ংক্রিয়ভাবে কোড তৈরি করে যা আপনার হাতে লেখা কোডের অনুকরণ করে। যেহেতু কোডটি কম্পাইলের সময় তৈরি করা হয়, এটি Guice- এর মতো অন্যান্য প্রতিফলন-ভিত্তিক সমাধানগুলির চেয়ে খুঁজে পাওয়া যায় এবং আরও কার্যকর।
ড্যাগার ব্যবহারের সুবিধা
ড্যাগার আপনাকে ক্লান্তিকর এবং ত্রুটি-প্রবণ বয়লারপ্লেট কোড লেখা থেকে মুক্ত করে:
AppContainer
কোড (অ্যাপ্লিকেশন গ্রাফ) তৈরি করা যা আপনি ম্যানুয়াল DI বিভাগে ম্যানুয়ালি প্রয়োগ করেছেন।অ্যাপ্লিকেশন গ্রাফে উপলব্ধ ক্লাসের জন্য কারখানা তৈরি করা। এইভাবে নির্ভরশীলতা অভ্যন্তরীণভাবে সন্তুষ্ট হয়।
একটি নির্ভরতা পুনঃব্যবহার বা স্কোপ ব্যবহারের মাধ্যমে একটি নতুন দৃষ্টান্ত তৈরি করার সিদ্ধান্ত নেওয়া।
নির্দিষ্ট প্রবাহের জন্য কন্টেইনার তৈরি করা যেমন আপনি ডেগার সাবকম্পোনেন্ট ব্যবহার করে পূর্ববর্তী বিভাগে লগইন প্রবাহের সাথে করেছিলেন। এটি মেমরিতে অবজেক্ট রিলিজ করে আপনার অ্যাপের কর্মক্ষমতা উন্নত করে যখন সেগুলির আর প্রয়োজন হয় না।
যতক্ষণ না আপনি একটি শ্রেণির নির্ভরতা ঘোষণা করেন এবং টীকা ব্যবহার করে কীভাবে তাদের সন্তুষ্ট করবেন তা নির্দিষ্ট করে বিল্ড টাইমে ড্যাগার স্বয়ংক্রিয়ভাবে এই সব করে। ড্যাগার আপনি ম্যানুয়ালি যা লিখতেন তার অনুরূপ কোড তৈরি করে। অভ্যন্তরীণভাবে, ড্যাগার বস্তুর একটি গ্রাফ তৈরি করে যা এটি একটি ক্লাসের উদাহরণ প্রদানের উপায় খুঁজে বের করতে উল্লেখ করতে পারে। গ্রাফের প্রতিটি ক্লাসের জন্য, ড্যাগার একটি ফ্যাক্টরি-টাইপ ক্লাস তৈরি করে যা এই ধরনের উদাহরণ পেতে অভ্যন্তরীণভাবে ব্যবহার করে।
নির্মাণের সময়, ড্যাগার আপনার কোডের মধ্য দিয়ে চলে এবং:
নির্ভরতা গ্রাফ তৈরি করে এবং যাচাই করে, নিশ্চিত করে যে:
- প্রতিটি বস্তুর নির্ভরতা সন্তুষ্ট হতে পারে, তাই কোন রানটাইম ব্যতিক্রম নেই।
- কোন নির্ভরতা চক্র বিদ্যমান নেই, তাই কোন অসীম লুপ নেই।
প্রকৃত বস্তু এবং তাদের নির্ভরতা তৈরি করতে রানটাইমে ব্যবহৃত ক্লাসগুলি তৈরি করে।
ড্যাগারে একটি সাধারণ ব্যবহারের ক্ষেত্রে: একটি কারখানা তৈরি করা
আপনি কীভাবে ড্যাগারের সাথে কাজ করতে পারেন তা প্রদর্শন করতে, আসুন নিম্নলিখিত চিত্রে দেখানো UserRepository
ক্লাসের জন্য একটি সাধারণ কারখানা তৈরি করি:
নিম্নলিখিত হিসাবে UserRepository
সংজ্ঞায়িত করুন:
কোটলিন
class UserRepository( private val localDataSource: UserLocalDataSource, private val remoteDataSource: UserRemoteDataSource ) { ... }
জাভা
public class UserRepository { private final UserLocalDataSource userLocalDataSource; private final UserRemoteDataSource userRemoteDataSource; public UserRepository(UserLocalDataSource userLocalDataSource, UserRemoteDataSource userRemoteDataSource) { this.userLocalDataSource = userLocalDataSource; this.userRemoteDataSource = userRemoteDataSource; } ... }
UserRepository
কনস্ট্রাক্টরে একটি @Inject
টীকা যোগ করুন যাতে Dagger জানে কিভাবে একটি UserRepository
তৈরি করতে হয়:
কোটলিন
// @Inject lets Dagger know how to create instances of this object class UserRepository @Inject constructor( private val localDataSource: UserLocalDataSource, private val remoteDataSource: UserRemoteDataSource ) { ... }
জাভা
public class UserRepository { private final UserLocalDataSource userLocalDataSource; private final UserRemoteDataSource userRemoteDataSource; // @Inject lets Dagger know how to create instances of this object @Inject public UserRepository(UserLocalDataSource userLocalDataSource, UserRemoteDataSource userRemoteDataSource) { this.userLocalDataSource = userLocalDataSource; this.userRemoteDataSource = userRemoteDataSource; } }
কোডের উপরের স্নিপেটে, আপনি ড্যাগারকে বলছেন:
@Inject
টীকাযুক্ত কনস্ট্রাক্টরের সাথে কীভাবে একটিUserRepository
উদাহরণ তৈরি করবেন।এর নির্ভরতাগুলি কী:
UserLocalDataSource
এবংUserRemoteDataSource
।
এখন ড্যাগার জানে কিভাবে UserRepository
এর একটি উদাহরণ তৈরি করতে হয়, কিন্তু এটি কীভাবে তার নির্ভরতা তৈরি করতে হয় তা জানে না। আপনি যদি অন্যান্য ক্লাসগুলিও টীকা করেন, ড্যাগার জানেন কিভাবে সেগুলি তৈরি করতে হয়:
কোটলিন
// @Inject lets Dagger know how to create instances of these objects class UserLocalDataSource @Inject constructor() { ... } class UserRemoteDataSource @Inject constructor() { ... }
জাভা
public class UserLocalDataSource { @Inject public UserLocalDataSource() { } } public class UserRemoteDataSource { @Inject public UserRemoteDataSource() { } }
ড্যাগার উপাদান
ড্যাগার আপনার প্রজেক্টের নির্ভরতাগুলির একটি গ্রাফ তৈরি করতে পারে যা এটি প্রয়োজনের সময় সেই নির্ভরতাগুলি কোথায় পাওয়া উচিত তা খুঁজে বের করতে ব্যবহার করতে পারে। ড্যাগারকে এটি করতে, আপনাকে একটি ইন্টারফেস তৈরি করতে হবে এবং এটি @Component
এর সাথে টীকা করতে হবে। ড্যাগার একটি ধারক তৈরি করে যেমন আপনি ম্যানুয়াল নির্ভরতা ইনজেকশন দিয়ে করতেন।
@Component
ইন্টারফেসের ভিতরে, আপনি এমন ফাংশনগুলিকে সংজ্ঞায়িত করতে পারেন যা আপনার প্রয়োজনীয় ক্লাসগুলির উদাহরণ প্রদান করে (যেমন UserRepository
)। @Component
ড্যাগারকে বলে যে এটি যে ধরনের প্রকাশ করে তা পূরণ করার জন্য প্রয়োজনীয় সমস্ত নির্ভরতা সহ একটি ধারক তৈরি করতে। একে ড্যাগার উপাদান বলা হয়; এটিতে এমন একটি গ্রাফ রয়েছে যা সেই বস্তুগুলি নিয়ে গঠিত যা ড্যাগার জানে কিভাবে প্রদান করতে হয় এবং তাদের নিজ নিজ নির্ভরতা।
কোটলিন
// @Component makes Dagger create a graph of dependencies @Component interface ApplicationGraph { // The return type of functions inside the component interface is // what can be provided from the container fun repository(): UserRepository }
জাভা
// @Component makes Dagger create a graph of dependencies @Component public interface ApplicationGraph { // The return type of functions inside the component interface is // what can be consumed from the graph UserRepository userRepository(); }
আপনি যখন প্রকল্পটি তৈরি করেন, ড্যাগার আপনার জন্য ApplicationGraph
ইন্টারফেসের একটি বাস্তবায়ন তৈরি করে: DaggerApplicationGraph
। এর টীকা প্রসেসরের সাহায্যে, ড্যাগার একটি নির্ভরতা গ্রাফ তৈরি করে যা তিনটি শ্রেণীর মধ্যে সম্পর্ক নিয়ে গঠিত ( UserRepository
, UserLocalDatasource
, এবং UserRemoteDataSource
) শুধুমাত্র একটি এন্ট্রি পয়েন্ট সহ: একটি UserRepository
ইনস্ট্যান্স পাওয়া। আপনি নিম্নলিখিত হিসাবে এটি ব্যবহার করতে পারেন:
কোটলিন
// Create an instance of the application graph val applicationGraph: ApplicationGraph = DaggerApplicationGraph.create() // Grab an instance of UserRepository from the application graph val userRepository: UserRepository = applicationGraph.repository()
জাভা
// Create an instance of the application graph ApplicationGraph applicationGraph = DaggerApplicationGraph.create(); // Grab an instance of UserRepository from the application graph UserRepository userRepository = applicationGraph.userRepository();
প্রতিবার অনুরোধ করা হলে ড্যাগার UserRepository
এর একটি নতুন উদাহরণ তৈরি করে।
কোটলিন
val applicationGraph: ApplicationGraph = DaggerApplicationGraph.create() val userRepository: UserRepository = applicationGraph.repository() val userRepository2: UserRepository = applicationGraph.repository() assert(userRepository != userRepository2)
জাভা
ApplicationGraph applicationGraph = DaggerApplicationGraph.create(); UserRepository userRepository = applicationGraph.userRepository(); UserRepository userRepository2 = applicationGraph.userRepository(); assert(userRepository != userRepository2)
কখনও কখনও, আপনার একটি পাত্রে নির্ভরতার একটি অনন্য উদাহরণ থাকতে হবে। আপনি বিভিন্ন কারণে এটি চাইতে পারেন:
আপনি একই ধরনের ইনস্ট্যান্স শেয়ার করার জন্য নির্ভরতা হিসাবে এই ধরনের অন্যান্য ধরনের চান, যেমন একই
LoginUserData
ব্যবহার করে লগইন প্রবাহে একাধিকViewModel
অবজেক্ট।একটি বস্তু তৈরি করা ব্যয়বহুল এবং প্রতিবার এটিকে নির্ভরতা হিসাবে ঘোষণা করা হলে আপনি একটি নতুন উদাহরণ তৈরি করতে চান না (উদাহরণস্বরূপ, একটি JSON পার্সার)।
উদাহরণে, আপনি গ্রাফে UserRepository
এর একটি অনন্য উদাহরণ পেতে চাইতে পারেন যাতে আপনি যখনই একটি UserRepository
জন্য জিজ্ঞাসা করেন, আপনি সর্বদা একই উদাহরণ পান। এটি আপনার উদাহরণে উপযোগী কারণ একটি বাস্তব-জীবনের অ্যাপ্লিকেশনে আরও জটিল অ্যাপ্লিকেশন গ্রাফ সহ, আপনার কাছে UserRepository
এর উপর নির্ভর করে একাধিক ViewModel
অবজেক্ট থাকতে পারে এবং প্রতিবার UserRepository
প্রদান করার প্রয়োজন হলে আপনি UserLocalDataSource
এবং UserRemoteDataSource
এর নতুন উদাহরণ তৈরি করতে চান না। .
ম্যানুয়াল ডিপেন্ডেন্সি ইনজেকশনে, আপনি ViewModel ক্লাসের কনস্ট্রাক্টরদের কাছে UserRepository
এর একই উদাহরণে পাস করে এটি করেন; কিন্তু ড্যাগারে, যেহেতু আপনি সেই কোডটি ম্যানুয়ালি লিখছেন না, আপনাকে ড্যাগারকে জানাতে হবে যে আপনি একই উদাহরণ ব্যবহার করতে চান। এটি সুযোগ টীকা দিয়ে করা যেতে পারে।
ড্যাগার সঙ্গে স্কোপিং
আপনি স্কোপ টীকা ব্যবহার করতে পারেন একটি বস্তুর জীবনকালকে তার উপাদানের জীবদ্দশায় সীমাবদ্ধ করতে। এর মানে হল যে টাইপ প্রদান করার প্রয়োজন হলে প্রতিবার নির্ভরতার একই উদাহরণ ব্যবহার করা হয়।
আপনি যখন ApplicationGraph
এ রিপোজিটরির জন্য জিজ্ঞাসা করেন একটি UserRepository
এর একটি অনন্য উদাহরণ পেতে, @Component
ইন্টারফেস এবং UserRepository
জন্য একই সুযোগের টীকা ব্যবহার করুন। আপনি @Singleton
টীকাটি ব্যবহার করতে পারেন যা ইতিমধ্যে javax.inject
প্যাকেজের সাথে আসে যা Dagger ব্যবহার করে:
কোটলিন
// Scope annotations on a @Component interface informs Dagger that classes annotated // with this annotation (i.e. @Singleton) are bound to the life of the graph and so // the same instance of that type is provided every time the type is requested. @Singleton @Component interface ApplicationGraph { fun repository(): UserRepository } // Scope this class to a component using @Singleton scope (i.e. ApplicationGraph) @Singleton class UserRepository @Inject constructor( private val localDataSource: UserLocalDataSource, private val remoteDataSource: UserRemoteDataSource ) { ... }
জাভা
// Scope annotations on a @Component interface informs Dagger that classes annotated // with this annotation (i.e. @Singleton) are scoped to the graph and the same // instance of that type is provided every time the type is requested. @Singleton @Component public interface ApplicationGraph { UserRepository userRepository(); } // Scope this class to a component using @Singleton scope (i.e. ApplicationGraph) @Singleton public class UserRepository { private final UserLocalDataSource userLocalDataSource; private final UserRemoteDataSource userRemoteDataSource; @Inject public UserRepository(UserLocalDataSource userLocalDataSource, UserRemoteDataSource userRemoteDataSource) { this.userLocalDataSource = userLocalDataSource; this.userRemoteDataSource = userRemoteDataSource; } }
বিকল্পভাবে, আপনি একটি কাস্টম স্কোপ টীকা তৈরি এবং ব্যবহার করতে পারেন। আপনি নিম্নলিখিত হিসাবে একটি সুযোগ টীকা তৈরি করতে পারেন:
কোটলিন
// Creates MyCustomScope @Scope @MustBeDocumented @Retention(value = AnnotationRetention.RUNTIME) annotation class MyCustomScope
জাভা
// Creates MyCustomScope @Scope @Retention(RetentionPolicy.RUNTIME) public @interface MyCustomScope {}
তারপর, আপনি এটি আগের মত ব্যবহার করতে পারেন:
কোটলিন
@MyCustomScope @Component interface ApplicationGraph { fun repository(): UserRepository } @MyCustomScope class UserRepository @Inject constructor( private val localDataSource: UserLocalDataSource, private val service: UserService ) { ... }
জাভা
@MyCustomScope @Component public interface ApplicationGraph { UserRepository userRepository(); } @MyCustomScope public class UserRepository { private final UserLocalDataSource userLocalDataSource; private final UserRemoteDataSource userRemoteDataSource; @Inject public UserRepository(UserLocalDataSource userLocalDataSource, UserRemoteDataSource userRemoteDataSource) { this.userLocalDataSource = userLocalDataSource; this.userRemoteDataSource = userRemoteDataSource; } }
উভয় ক্ষেত্রেই, অবজেক্টটি @Component
ইন্টারফেস টীকা করতে ব্যবহৃত একই সুযোগ প্রদান করা হয়। সুতরাং, যতবার আপনি applicationGraph.repository()
কল করবেন, আপনি UserRepository
এর একই উদাহরণ পাবেন।
কোটলিন
val applicationGraph: ApplicationGraph = DaggerApplicationGraph.create() val userRepository: UserRepository = applicationGraph.repository() val userRepository2: UserRepository = applicationGraph.repository() assert(userRepository == userRepository2)
জাভা
ApplicationGraph applicationGraph = DaggerApplicationGraph.create(); UserRepository userRepository = applicationGraph.userRepository(); UserRepository userRepository2 = applicationGraph.userRepository(); assert(userRepository == userRepository2)
উপসংহার
আপনি আরও জটিল পরিস্থিতিতে এটি ব্যবহার করার আগে ড্যাগারের সুবিধা এবং এটি কীভাবে কাজ করে তার মূল বিষয়গুলি সম্পর্কে সচেতন হওয়া গুরুত্বপূর্ণ।
পরের পৃষ্ঠায় , আপনি শিখবেন কিভাবে একটি অ্যান্ড্রয়েড অ্যাপ্লিকেশনে ড্যাগার যোগ করতে হয়।