Bağımlılık Enjeksiyonu (DI), bağımlılıkları oluşturma ve yönetme kontrolünün uygulamadan harici bir varlığa aktarıldığı Kontrolün Tersine Çevrilmesi'ni (IoC) uygulamak için kullanılan bir tasarım desenidir. Bu, daha modüler, test edilebilir ve sürdürülebilir kod oluşturmaya yardımcı olur. Nesneleri oluşturma sorumluluğunun kodun diğer bölümlerine aktarıldığı bir tekniktir. Bu, gevşek bağlantıyı teşvik ederek kodu daha modüler ve yönetilmesi daha kolay hale getirir.
Sınıfların düzgün çalışması için sıklıkla diğer sınıflara referanslara ihtiyacı vardır. Örneğin, Book
sınıfı gerektiren bir Library
sınıfını düşünün. Bu gerekli sınıflar bağımlılıklar olarak bilinir. Library
sınıfının çalışması için Book
sınıfının bir örneğine sahip olması gerekir.
Bir sınıfın ihtiyaç duyduğu nesneleri elde etmesinin üç temel yolu vardır:
Library
sınıfı Book
sınıfının kendi örneğini oluşturur ve başlatır.Context
getters ve getSystemService()
gibi bazı Android API'leri bu şekilde çalışır.Library
kurucusu bir Book
örneğini parametre olarak alır.Üçüncü seçenek bağımlılık enjeksiyonudur! DI ile, sınıf örneğinin bunları kendisi edinmesi yerine, sınıfın bağımlılıklarını siz sağlarsınız.
DI olmadan, kendi Book
bağımlılığını oluşturan bir Library
şu şekilde görünebilir:
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(); } }
Bu bir DI örneği değildir çünkü Library
sınıfı kendi Book
oluşturur. Bu sorunlu olabilir çünkü:
Library
ve Book
sıkı bir şekilde bağlıdır. Library
örneği bir tür Book
kullanır ve bu da alt sınıfların veya alternatif uygulamaların kullanılmasını zorlaştırır.Book
olan sert bağımlılık, testi daha zorlu hale getirir. Library
Book
gerçek bir örneğini kullanır ve farklı test durumları için Book
değiştirmek için test kopyalarının kullanılmasını önler. DI ile, Library
her örneği kendi Book
nesnesini oluşturmak yerine, kurucusunda bir Book
nesnesini parametre olarak alır:
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(); }
Ana işlev Library
kullanır. Library
, Book
bağlı olduğundan, uygulama Book
bir örneğini oluşturur ve ardından bunu Library
bir örneğini oluşturmak için kullanır. Bu DI tabanlı yaklaşımın faydaları şunlardır:
Library
Yeniden Kullanılabilirliği : Book
farklı uygulamalarını Library
geçirebilirsiniz. Örneğin, Library
kullanmasını istediğiniz Book
EBook
adında yeni bir alt sınıfını tanımlayabilirsiniz. DI ile, EBook
bir örneğini Library
geçirmeniz yeterlidir ve başka bir değişiklik yapmadan çalışır.Library
Kolay Test Edilmesi : Farklı senaryoları test etmek için test kopyalarını gönderebilirsiniz. Bir NotificationService
sınıfının bir Notification
sınıfına dayandığı bir senaryoyu düşünün. DI olmadan, NotificationService
doğrudan bir Notification
örneği oluşturur ve bu da farklı bildirim türlerini kullanmayı veya hizmeti çeşitli bildirim uygulamalarıyla test etmeyi zorlaştırır.
DI'ı açıklamak için bu örneği yeniden düzenleyelim:
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(); } }
Artık NotificationService
belirli bir sınıftan ziyade Notification
arayüzüne bağlıdır. Bu, Notification
farklı uygulamalarının birbirinin yerine kullanılabilmesine olanak tanır. Kullanmak istediğiniz uygulamayı sendNotification
yöntemi aracılığıyla ayarlayabilirsiniz:
NotificationService service = new NotificationService(); service.sendNotification(new EmailNotification()); service.sendNotification(new SMSNotification());
DI’nin üç ana türü vardır:
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. Alan Enjeksiyonu (veya Ayarlayıcı Enjeksiyonu) : Aktiviteler ve parçalar gibi belirli Android çerçeve sınıfları sistem tarafından örneklendirilir, bu nedenle oluşturucu enjeksiyonu mümkün değildir. Alan enjeksiyonuyla, bağımlılıklar sınıf oluşturulduktan sonra örneklendirilir.
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. Metot Enjeksiyonu : Bağımlılıklar, çoğunlukla @Inject
notasyonu kullanılarak metotlar aracılığıyla sağlanır.
Önceki örnekte, bir kütüphane kullanmadan farklı sınıfların bağımlılıklarını manuel olarak oluşturdunuz, sağladınız ve yönettiniz. Bu yaklaşıma manuel bağımlılık enjeksiyonu denir. Basit durumlar için işe yarasa da, bağımlılık ve sınıf sayısı arttıkça zahmetli hale gelir. Manuel bağımlılık enjeksiyonunun birkaç dezavantajı vardır:
Kütüphaneler sizin için bağımlılıklar oluşturarak ve sağlayarak bu süreci otomatikleştirebilir. Bu kütüphaneler iki kategoriye ayrılır:
Dagger, Google tarafından yönetilen Java, Kotlin ve Android için popüler bir bağımlılık enjeksiyon kütüphanesidir. Dagger, sizin için bağımlılık grafiğini oluşturarak ve yöneterek uygulamanızdaki DI'ı basitleştirir. Guice gibi yansıma tabanlı çözümlerle ilişkili birçok geliştirme ve performans sorununu ele alan tamamen statik, derleme zamanı bağımlılıkları sağlar.
Bu çerçeveler bağımlılıkları çalışma zamanında birbirine bağlar:
Bu çerçeveler, derleme zamanında bağımlılıkları bağlamak için kod üretir:
Bağımlılık enjeksiyonuna bir alternatif, servis konum belirleyici örüntüsüdür. Bu tasarım örüntüsünün ayrıca sınıfları somut bağımlılıklarından ayırmaya yardımcı olur. Bağımlılıkları oluşturan ve depolayan, bunları talep üzerine sağlayan servis konum belirleyici olarak bilinen bir sınıf yaratırsınız.
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() }
Hizmet konum belirleme kalıbı, bağımlılıkların nasıl tüketildiği konusunda bağımlılık enjeksiyonundan farklıdır. Hizmet konum belirleme kalıbıyla, sınıflar ihtiyaç duydukları bağımlılıkları ister; bağımlılık enjeksiyonuyla, uygulama gerekli nesneleri proaktif olarak sağlar.
Dagger 2, Android için popüler bir DI çerçevesidir. Derleme zamanı kod üretimi kullanır ve yüksek performansıyla bilinir. Dagger 2, bağımlılıkları işlemek için gerekli kodu üreterek bağımlılık enjeksiyonu sürecini basitleştirir, kalıpları azaltır ve verimliliği artırır.
Dagger 2, Android'de bağımlılık enjeksiyonu için açıklama tabanlı bir kütüphanedir. İşte temel açıklamalar ve amaçları:
ApiClient
sağlayabilir.@Module
ve @Inject
arasında köprü kuran bir arayüz. Tüm modülleri içerir ve uygulama için oluşturucu sağlar.@Provides
benzer ancak daha özdür. Dagger, projeniz için bir bağımlılık grafiği üretebilir ve bu sayede ihtiyaç duyulduğunda bağımlılıkların nereden alınacağını belirleyebilir. Bunu etkinleştirmek için bir arayüz oluşturmanız ve onu @Component
ile açıklamanız gerekir.
@Component
arayüzünde, ihtiyaç duyduğunuz sınıfların örneklerini döndüren yöntemleri tanımlarsınız (örneğin, BookRepository
). @Component
açıklaması, Dagger'a ifşa ettiği türleri karşılamak için gereken tüm bağımlılıkları içeren bir kapsayıcı oluşturmasını söyler. Bu kapsayıcı bir Dagger bileşeni olarak bilinir ve Dagger'ın bağımlılıklarıyla birlikte nasıl sağlayacağını bildiği nesnelerin bir grafiğini içerir.
LibraryRepository
içeren bir örneği ele alalım:
LibraryRepository
örneğini nasıl oluşturacağını bilmesi için LibraryRepository
oluşturucusuna bir @Inject
açıklaması ekleyin. 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. Bağımlılıkları Açıklama : Benzer şekilde, bağımlılıkların ( LocalLibraryDataSource
ve RemoteLibraryDataSource
) oluşturucularını da açıklama ekleyerek Dagger'ın bunları nasıl oluşturacağını bilmesini sağlayın.
public class LocalLibraryDataSource { @Inject public LocalLibraryDataSource() { // Initialization code } } public class RemoteLibraryDataSource { private final LibraryService libraryService; @Inject public RemoteLibraryDataSource(LibraryService libraryService) { this.libraryService = libraryService; } }
3. Bileşeni Tanımlayın : Bağımlılık grafiğini tanımlamak için @Component
ile açıklamalı bir arayüz oluşturun.
@Component public interface ApplicationComponent { LibraryRepository getLibraryRepository(); }
Projeyi derlediğinizde Dagger sizin için ApplicationComponent
arayüzünün bir uygulamasını üretir, genellikle DaggerApplicationComponent
olarak adlandırılır.
Artık oluşturulan bileşeni, bağımlılıkları otomatik olarak eklenen sınıflarınızın örneklerini elde etmek için kullanabilirsiniz:
public class MainApplication extends Application { private ApplicationComponent applicationComponent; @Override public void onCreate() { super.onCreate(); applicationComponent = DaggerApplicationComponent.create(); } public ApplicationComponent getApplicationComponent() { return applicationComponent; } }
Etkinliğinizde veya parçanızda LibraryRepository
örneğini alabilirsiniz:
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. Modüller
∘ Modüllerin Temel Kavramları
∘ Bileşenlere Modüller Dahil Etme
2. Kapsamlar
3. Bileşenler
4. Bileşen Bağımlılıkları
5. Çalışma Zamanı Bağlamaları
Dagger 2'deki modüller, bileşenlere bağımlılıklar sağlayan @Module
ile açıklanan sınıflardır. Bağımlılıkların nasıl oluşturulacağını ve sağlanacağını belirtmek için @Provides
veya @Binds
ile açıklanan yöntemler içerirler. Modüller, uygulamanızın ihtiyaç duyduğu nesnelerin oluşturulmasını organize etmek ve yönetmek için önemlidir.
@Provides
Provides'tan daha özlüdür ve modül soyut bir sınıf olduğunda kullanılır.Bir Modül Örneği
@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(); } }
Bu örnekte, NetworkModule
@Module
ile açıklanan bir sınıftır. Retrofit
ve OkHttpClient
örneklerini oluşturan ve döndüren @Provides
ile açıklanan iki yöntem içerir.
@Binds Kullanımı
Bir arayüz ve uygulaması olduğunda, uygulamayı arayüze bağlamak için @Binds
kullanabilirsiniz. Bu, @Provides
kullanmaktan daha özlüdür.
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); }
Bu örnekte, ApiModule
@Module
ile açıklanan soyut bir sınıftır. bindApiService
yöntemi ApiServiceImpl
ApiService
bağlamak için @Binds
ile açıklanmıştır.
Modüller sağladıkları işlevselliğe göre düzenlenebilir. Örneğin, ağ işlemleri, veritabanı işlemleri ve kullanıcı arayüzüyle ilgili bağımlılıklar için ayrı modülleriniz olabilir.
Örnek:
Retrofit
ve OkHttpClient
gibi ağ ile ilgili bağımlılıkları sağlar.RoomDatabase
gibi veritabanıyla ilgili bağımlılıkları sağlar.ViewModel
ve Presenter
gibi UI ile ilgili bağımlılıkları sağlar.Modüller, ihtiyaç duyan sınıflara bağımlılıklar sağlamak için bileşenlere dahil edilir. İşte nasıl kurabileceğiniz:
UygulamaBileşeni.java:
@Singleton @Component(modules = {NetworkModule.class, DatabaseModule.class}) public interface ApplicationComponent { void inject(MyApplication application); }
Bu örnekte ApplicationComponent
, uygulamaya bağımlılıklar sağlamak için NetworkModule
ve DatabaseModule
içerir.
Dagger 2'deki kapsamlar, bağımlılıkların yaşam döngüsünü tanımlayan açıklamalardır. Tek bir bağımlılık örneğinin belirli bir kapsam içinde oluşturulmasını ve paylaşılmasını sağlarlar. Bu, belleğin verimli bir şekilde yönetilmesine ve bağımlılıkların uygun yerlerde yeniden kullanılmasının sağlanmasına yardımcı olur.
1. Tekil Kapsam
Tanım : @Singleton
kapsamı, bir bağımlılığın tek bir örneğinin oluşturulmasını ve uygulamanın tüm yaşam döngüsü boyunca paylaşılmasını sağlar.
Bu kapsam genellikle ağ istemcileri, veritabanı örnekleri veya paylaşılan tercihler gibi tüm uygulama genelinde paylaşılması gereken bağımlılıklar için kullanılır.
Örnek:
@Singleton @Component(modules = {NetworkModule.class, DatabaseModule.class}) public interface ApplicationComponent { void inject(MyApplication application); }
Bu örnekte @Singleton
ek açıklaması, NetworkModule
ve DatabaseModule
tarafından sağlanan Retrofit
ve Database
örneklerinin tekil olmasını ve tüm uygulama genelinde paylaşılmasını sağlar.
2. Faaliyet Kapsamı
Tanım : @ActivityScope
(özel kapsam), bir bağımlılığın tek bir örneğinin bir aktivitenin yaşam döngüsü içerisinde oluşturulmasını ve paylaşılmasını sağlar.
Bu kapsam, bir etkinliğe özgü olan ve etkinlik her yeniden oluşturulduğunda yeniden oluşturulması gereken sunucular veya görünüm modelleri gibi bağımlılıklar için yararlıdır.
Örnek :
@Scope @Retention(RetentionPolicy.RUNTIME) public @interface ActivityScope { } @ActivityScope @Component(dependencies = ApplicationComponent.class, modules = ActivityModule.class) public interface ActivityComponent { void inject(MainActivity mainActivity); }
Bu örnekte, @ActivityScope
açıklaması, ActivityModule
tarafından sağlanan bağımlılıkların etkinliğin yaşam döngüsüne göre kapsamlandırılmasını sağlar.
3. Parça Kapsamı
Tanım : @FragmentScope
(başka bir özel kapsam), bir bağımlılığın tek bir örneğinin bir parçanın yaşam döngüsü içinde oluşturulmasını ve paylaşılmasını sağlar.
Kullanım Durumu: Bu kapsam, parçaya özgü olan ve parça her yeniden oluşturulduğunda yeniden oluşturulması gereken bağımlılıklar (parçaya özgü sunucular veya görünüm modelleri gibi) için yararlıdır.
Örnek :
@Scope @Retention(RetentionPolicy.RUNTIME) public @interface FragmentScope { } @FragmentScope @Component(dependencies = ActivityComponent.class, modules = FragmentModule.class) public interface FragmentComponent { void inject(MyFragment myFragment); }
Bu örnekte, @FragmentScope
açıklaması, FragmentModule
tarafından sağlanan bağımlılıkların parçanın yaşam döngüsüne göre kapsamlandırılmasını sağlar.
Bileşen bağımlılıkları, bir bileşenin diğerine bağımlı olmasını sağlayarak bağımlılıkların yeniden kullanılmasını sağlar. İki ana bileşen bağımlılığı türü vardır:
1. Uygulama Bileşeni
Tanım : Uygulama Bileşeni, tüm uygulama boyunca ihtiyaç duyulan bağımlılıkları sağlar. Genellikle, bağımlılıkların uygulama genelinde paylaşıldığından emin olmak için @Singleton
ile kapsamlandırılır.
Bu bileşen, ağ istemcileri, veritabanı örnekleri veya paylaşılan tercihler gibi küresel olarak kullanılabilir olması gereken bağımlılıklar için kullanılır.
Örnek :
@Singleton @Component(modules = {NetworkModule.class, DatabaseModule.class}) public interface ApplicationComponent { void inject(MyApplication application); }
Bu örnekte ApplicationComponent
, tüm uygulama genelinde paylaşılan Retrofit
ve Database
örneklerini sağlamaktan sorumludur.
2. Etkinlik Bileşeni
Tanım : Etkinlik Bileşeni, belirli bir etkinlik içinde ihtiyaç duyulan bağımlılıkları sağlar. Genellikle, etkinlik her yeniden oluşturulduğunda bağımlılıkların yeniden oluşturulmasını sağlamak için @ActivityScope
gibi özel bir kapsamla kapsamlandırılır.
Bu bileşen, sunucular veya görünüm modelleri gibi bir etkinliğe özgü bağımlılıklar için kullanılır.
Örnek :
@ActivityScope @Component(dependencies = ApplicationComponent.class, modules = ActivityModule.class) public interface ActivityComponent { void inject(MainActivity mainActivity); }
Bu örnekte ActivityComponent
, ApplicationComponent
bağımlıdır ve MainActivity
özgü bağımlılıklar sağlar.
Bileşen bağımlılıkları, bir bileşenin diğerine bağımlı olmasını sağlayarak bağımlılıkların yeniden kullanılmasını sağlar. İki ana bileşen bağımlılığı türü vardır:
1. Alt bileşenler:
Bir alt bileşen, başka bir bileşenin çocuğudur ve üst bileşeninin bağımlılıklarına erişebilir. Alt bileşenler üst bileşen içinde tanımlanır ve kapsamını devralabilir.
Örnek :
@ActivityScope @Subcomponent(modules = ActivityModule.class) public interface ActivitySubcomponent { void inject(MainActivity mainActivity); }
Bu örnekte ActivitySubcomponent
, ana bileşenin bir alt bileşenidir ve onun bağımlılıklarına erişebilir.
2. Bağımlılık Niteliği
Bu, bir bileşenin alt bileşen olmadan başka bir bileşene bağımlı olmasını sağlar. Bağımlı bileşen, ana bileşen tarafından sağlanan bağımlılıklara erişebilir.
Örnek :
@ActivityScope @Component(dependencies = ApplicationComponent.class, modules = ActivityModule.class) public interface ActivityComponent { void inject(MainActivity mainActivity); }
Bu örnekte ActivityComponent
, ApplicationComponent
bağımlıdır ve onun bağımlılıklarına erişebilir.
Dagger 2'deki çalışma zamanı bağlamaları, ihtiyaç duyuldukları bağlama göre çalışma zamanında oluşturulan ve yönetilen bağımlılıkların sağlanması anlamına gelir.
1. Uygulama Bağlamı
Tanım : Uygulama bağlamı, tüm uygulamanın yaşam döngüsüne bağlı bir bağlamdır. Uygulamanın kendisi kadar uzun süre yaşaması gereken bağımlılıklar için kullanılır.
Tüm uygulama genelinde paylaşılan ve her etkinlik veya parça için yeniden oluşturulması gerekmeyen bağımlılıklar. Örnekler arasında ağ istemcileri, veritabanı örnekleri ve paylaşılan tercihler bulunur.
Örnek :
@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(); } }
Bu örnekte, AppModule
uygulama bağlamını tekil bir bağımlılık olarak sağlar. provideApplicationContext
yöntemi, sağlanan bağlamın uygulamanın yaşam döngüsüne bağlı olduğundan emin olur.
2. Etkinlik Bağlamı
Tanım : Etkinlik bağlamı, belirli bir etkinliğin yaşam döngüsüne bağlı bir bağlamdır. Etkinliğin kendisi kadar uzun süre yaşaması gereken bağımlılıklar için kullanılır.
Bir aktiviteye özgü olan ve aktivite her yeniden oluşturulduğunda yeniden oluşturulması gereken bağımlılıklar. Örnekler arasında görünüm modelleri, sunucular ve kullanıcı arayüzüyle ilgili bağımlılıklar bulunur.
Örnek :
@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; } }
Bu örnekte, ActivityModule
etkinlik bağlamını kapsamlı bir bağımlılık olarak sağlar. provideActivityContext
yöntemi, sağlanan bağlamın etkinliğin yaşam döngüsüne bağlı olduğundan emin olur.
Bu çalışma zamanı bağlamalarını kullanmak için bileşenlerinize ilgili modülleri eklemeniz gerekir:
Uygulama Bileşeni :
@Singleton @Component(modules = {AppModule.class, NetworkModule.class}) public interface ApplicationComponent { void inject(MyApplication application); Context getApplicationContext(); }
Etkinlik Bileşeni :
@ActivityScope @Component(dependencies = ApplicationComponent.class, modules = ActivityModule.class) public interface ActivityComponent { void inject(MainActivity mainActivity); Context getActivityContext(); }
Bağlamları Enjekte Etmek
Bileşenlerinizi ve modüllerinizi kurduktan sonra, ihtiyaç duyduğunuzda bağlamları sınıflarınıza ekleyebilirsiniz.
Bir Aktivitede Örnek :
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); } }
Bu örnekte, MainActivity
hem etkinlik bağlamını hem de uygulama bağlamını bağımlılık enjeksiyonu yoluyla alır. Bu, etkinliğin bağımlılıkların belirli ihtiyaçlarına göre uygun bağlamı kullanmasına olanak tanır.
Dagger 2'yi projenizde kullanmak için build.gradle
dosyanıza aşağıdaki bağımlılıkları eklemeniz gerekiyor:
dependencies { implementation 'com.google.dagger:dagger:2.x' annotationProcessor 'com.google.dagger:dagger-compiler:2.x' }
2.x
Dagger 2'nin son sürümüyle değiştirin.
Bağımlılıkları sağlamak için bir modül oluşturun. Örneğin, Retrofit
örneği sağlamak için bir NetworkModule
:
@Module public class NetworkModule { @Provides @Singleton Retrofit provideRetrofit() { return new Retrofit.Builder() .baseUrl("https://api.example.com") .addConverterFactory(GsonConverterFactory.create()) .build(); } }
Modül ile bağımlılıklara ihtiyaç duyan sınıflar arasında köprü kuracak bir bileşen oluşturun:
@Singleton @Component(modules = {NetworkModule.class}) public interface ApplicationComponent { void inject(MyApplication application); }
Bileşeni, sınıflarınıza bağımlılıklar enjekte etmek için kullanın. Örneğin, Application
sınıfınızda:
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; } }
Artık enjekte edilen bağımlılıkları sınıflarınızda kullanabilirsiniz. Örneğin, bir 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 // ... } }
Konuyu özetleyelim: