Guice-এ AbstractModule হলো একটি প্রধান ক্লাস, যা ডিপেনডেন্সি ইনজেকশনের জন্য বেসিক কনফিগারেশন প্রদান করে। Guice-এর মাধ্যমে আপনি কোন ইন্টারফেস কোন ইমপ্লিমেন্টেশনের সাথে যুক্ত করবেন এবং কীভাবে ডিপেনডেন্সি তৈরি হবে তা AbstractModule ক্লাস ব্যবহার করে নির্ধারণ করেন।
AbstractModule কী?
AbstractModule হলো Guice ফ্রেমওয়ার্কের একটি অ্যাবস্ট্রাক্ট ক্লাস, যা ডিপেনডেন্সি কনফিগারেশনের জন্য configure() মেথড প্রদান করে। এই মেথডে আপনি ডিপেনডেন্সি ম্যানেজমেন্টের নিয়মাবলী (bindings) সংজ্ঞায়িত করেন।
AbstractModule-এর ভূমিকা এবং ব্যবহার
1. Bindings তৈরি করা
AbstractModule-এর configure() মেথডে ইন্টারফেস এবং তার ইমপ্লিমেন্টেশন ক্লাসের মধ্যে সম্পর্ক নির্ধারণ করা হয়।
import com.google.inject.AbstractModule;
public class MyModule extends AbstractModule {
@Override
protected void configure() {
bind(MyService.class).to(MyServiceImpl.class);
}
}
এখানে:
bind(MyService.class).to(MyServiceImpl.class): এটি নির্দেশ করে যে, যখনMyServiceএর ডিপেনডেন্সি চাওয়া হবে, তখনMyServiceImplইনস্ট্যান্স তৈরি করা হবে।
2. Singleton Scope ব্যবহার করা
আপনার ক্লাসকে Singleton হিসাবে ব্যবহার করতে পারেন যাতে একবার মাত্র ইনস্ট্যান্স তৈরি হয়।
import com.google.inject.AbstractModule;
import com.google.inject.Singleton;
public class MyModule extends AbstractModule {
@Override
protected void configure() {
bind(MyService.class).to(MyServiceImpl.class).in(Singleton.class);
}
}
3. Custom Providers ব্যবহার করা
আপনার যদি ডিপেনডেন্সি তৈরির প্রক্রিয়া কাস্টমাইজ করতে হয়, তাহলে @Provides ব্যবহার করতে পারেন।
import com.google.inject.AbstractModule;
import com.google.inject.Provides;
public class MyModule extends AbstractModule {
@Override
protected void configure() {
// অন্যান্য bindings
}
@Provides
public MyService provideMyService() {
return new MyServiceImpl("Custom Initialization");
}
}
4. Constructor Binding ব্যবহার করা
ক্লাসের কনস্ট্রাক্টর যদি নির্দিষ্ট ডিপেনডেন্সি ইনজেক্ট করে, তাহলে কনস্ট্রাক্টর বাইন্ডিং করা যায়।
import com.google.inject.AbstractModule;
public class MyModule extends AbstractModule {
@Override
protected void configure() {
bind(MyService.class).toInstance(new MyServiceImpl("Initialized with Constructor"));
}
}
5. Interface to Multiple Implementations
একটি ইন্টারফেসের জন্য ভিন্ন ভিন্ন ইমপ্লিমেন্টেশন প্রদান করতে চাইলে @Named বা Annotations ব্যবহার করা হয়।
import com.google.inject.AbstractModule;
import com.google.inject.name.Names;
public class MyModule extends AbstractModule {
@Override
protected void configure() {
bind(MyService.class).annotatedWith(Names.named("ServiceA")).to(ServiceAImpl.class);
bind(MyService.class).annotatedWith(Names.named("ServiceB")).to(ServiceBImpl.class);
}
}
এরপর নির্দিষ্ট ইমপ্লিমেন্টেশন ইনজেক্ট করতে পারেন:
import com.google.inject.Inject;
import com.google.inject.name.Named;
public class Client {
private final MyService service;
@Inject
public Client(@Named("ServiceA") MyService service) {
this.service = service;
}
public void execute() {
service.execute();
}
}
6. Dependency Injection-এর Example
Step 1: ইন্টারফেস এবং ইমপ্লিমেন্টেশন তৈরি করুন
public interface MyService {
void execute();
}
public class MyServiceImpl implements MyService {
@Override
public void execute() {
System.out.println("Service is executed!");
}
}
Step 2: Module তৈরি করুন
import com.google.inject.AbstractModule;
public class MyModule extends AbstractModule {
@Override
protected void configure() {
bind(MyService.class).to(MyServiceImpl.class);
}
}
Step 3: Main Application
import com.google.inject.Guice;
import com.google.inject.Injector;
public class MainApp {
public static void main(String[] args) {
Injector injector = Guice.createInjector(new MyModule());
MyService myService = injector.getInstance(MyService.class);
myService.execute(); // Output: Service is executed!
}
}
উপকারিতা
- Flexible Configuration: AbstractModule ব্যবহার করে ডিপেনডেন্সি সম্পর্ক সহজেই কনফিগার করা যায়।
- Loose Coupling: ইন্টারফেস এবং ইমপ্লিমেন্টেশনের মধ্যে আলগা সংযোগ নিশ্চিত করে।
- Reusable Modules: একাধিক প্রজেক্টে একই Module ব্যবহার করা যায়।
- Scalability: বড় এবং জটিল অ্যাপ্লিকেশনেও সহজে পরিচালনা করা যায়।
AbstractModule Guice-এর মূল উপাদানগুলোর একটি, যা Dependency Injection বাস্তবায়নের সময় ডিপেনডেন্সি সম্পর্ক নির্ধারণে সহায়ক। এটি কোডকে আরো ক্লিন, মডুলার, এবং রিইউজেবল করতে সাহায্য করে।
Read more