Angular’da, “servis” terimi, bir uygulama boyunca kullanılabilen veri veya fonksiyonları kapsayan, genellikle sınıf bazlı bir yapıyı ifade eder. “Bağımlılık Enjeksiyonu” (Dependency Injection, DI) ise, bir bileşenin veya servisin bağımlı olduğu diğer servisleri otomatik olarak sağlama mekanizmasıdır.
Angular Servisler
Angular servisler, veritabanı işlemleri, HTTP istekleri, yerel depolama işlemleri veya herhangi bir veri işleme görevi gibi uygulama içinde tekrar tekrar kullanılacak fonksiyonaliteleri merkezi bir yerde yönetmek için kullanılır.
Genellikle sınıf tabanlıdır ve @Injectable() dekoratörü ile tanımlanırlar. Bu dekoratör, sınıfın Angular’ın DI sistemine enjekte edilebileceğini belirtir.
Örnek: Product Servisinin Oluşturulması
Bu serviste, basit CRUD (Create, Read, Update, Delete) işlemlerini simüle edeceğiz:
product.service.ts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
@Injectable({ providedIn: 'root' }) export class ProductService { private products = []; // Ürün Oluşturma create(product) { this.products.push(product); } // Tüm Ürünleri Alma read() { return this.products; } // Ürün Güncelleme update(id, updatedProduct) { const index = this.products.findIndex(product => product.id === id); if (index !== -1) { this.products[index] = updatedProduct; } } // Ürün Silme delete(id) { const index = this.products.findIndex(product => product.id === id); if (index !== -1) { this.products.splice(index, 1); } } } |
Bağımlılık enjeksiyonuna geçmeden önce Injectable konusuna biraz detaylı değinelim.
Angular’da bir servisin nasıl sağlandığı (provide edildiği) ve bu servisin nerede kullanılabilir olduğu önemlidir.
@Injectable({ providedIn: ‘root’ }) dekoratörü ile işaretlenen bir servisi uygulamanın her yerinden enjekte edebilirsiniz ve bu servis uygulama seviyesinde tek bir örnek (singleton) olarak oluşturulur.
Dekoratörde kullanılan providedIn özelliği, servisin nerede sağlandığına dair bilgi verir. ‘root‘ değerini kullanarak bu servisin uygulamanın ana modülüne bağlı olduğunu ve global olarak kullanılabileceğini belirtiyoruz.
Eğer @Injectable() dekoratörünü providedIn özelliği olmadan kullanırsanız, bu servisi bir modülde açıkça sağlamanız gerekir. Bunu providers dizisi içinde yaparsınız:
1 2 3 4 5 6 7 |
@NgModule({ providers: [YourService] }) export class YourModule { } |
Bu yaklaşım, servisin sadece belirli bir modül içinde kullanılmasını istediğinizde kullanışlıdır.
Ne zaman kullanılmalı?
Global bir servis oluşturmak istediğinizde: Eğer servisin uygulamanın her yerinde kullanılmasını ve aynı servis örneğinin paylaşılmasını istiyorsanız, providedIn: ‘root’ kullanılmalıdır.
Modül bazında bir servis oluşturmak istediğinizde: Eğer servisin sadece belirli bir modülde kullanılmasını istiyorsanız, servisi bu modülde providers dizisi içinde sağlamalısınız.
Özetle,
@Injectable({ providedIn: ‘root’ }): Servisi global olarak enjekte eder. Uygulama boyunca sadece bir örnek oluşturulur (singleton).
Modülde providers içinde sağlama: Servisi sadece bu modül içinde enjekte eder. Farklı modüllerde aynı servisi sağlarsanız, her modül için ayrı bir örnek oluşturulur.
Bağımlılık Enjeksiyonu (Dependency Injection)
Bağımlılık Enjeksiyonu, bir bileşenin veya servisin bağımlı olduğu diğer servisleri otomatik olarak sağlama mekanizmasıdır. Bağımlılık Enjeksiyonu, bileşenlerin ve servislerin daha test edilebilir olmasını ve daha az bağlılık içermesini sağlar.
Bir bileşenin bir servisi kullanabilmesi için, bu servisin bileşene enjekte edilmesi gerekir.
Örnek: Product Servisinin Bileşene Enjekte Edilmesi
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
import { Component } from '@angular/core'; import { ProductService } from './product.service'; @Component({ selector: 'app-product', template: ` <div *ngFor="let product of products"> {{ product.name }} </div> ` }) export class ProductComponent { products = []; constructor(private productService: ProductService) { this.products = this.productService.read(); } addProduct(product) { this.productService.create(product); this.products = this.productService.read(); } updateProduct(id, product) { this.productService.update(id, product); this.products = this.productService.read(); } removeProduct(id) { this.productService.delete(id); this.products = this.productService.read(); } } |
Bu bileşende, ProductService servisinden gelen CRUD metodlarını kullanarak ürün işlemlerini gerçekleştirdik. Bileşenin constructor’ında servis, DI ile enjekte edilir ve bu sayede servisteki metodlara erişim sağlanır.
Servislerin Kullanım Alanları
Veri Paylaşımı: Farklı bileşenler arasında veri paylaşmak için servisler kullanılır.
HTTP İstekleri: HTTP istekleri yapmak için servisler aracılığıyla HTTPClient modülü kullanılır.
Yerel Depolama İşlemleri: Uygulamada yerel depolama işlemleri (LocalStorage, SessionStorage) için merkezi bir yönetim oluşturmak adına servisler oluşturulabilir.
Uygulama Durum Yönetimi: Uygulama genelinde bir durum yönetimi yapısı oluşturmak için servisler tercih edilebilir.
Servisler ve bağımlılık enjeksiyonu, Angular’ın çekirdek konseptlerinden biridir. Bu sayede uygulamaların daha modüler, test edilebilir ve bakımı daha kolay hale gelir. Angular, bu konseptleri kullanarak geliştiricilere güçlü, ölçeklenebilir ve etkili frontend uygulamaları oluşturma yeteneği sunar.
Umarım “Angular Servisler ve Bağımlılık Enjeksiyonu” başlıklı yazım sizin için faydalı olmuştur.
Şu yazılar da ilginizi çekebilir.
Angular Data Binding: Tek Yönlü ve Çift Yönlü Veri Bağlama
Yeni bir yazımda görüşmek üzere.
Happy coding!