Angular’da Servisler ve Dependency Injection

Angular, bileşenler arasında veri paylaşımı, iş mantığı yürütme ve dış kaynaklara erişim gibi görevleri gerçekleştirmek için servislerin kullanılmasını teşvik eder. Servisler, Angular uygulamalarında önemli bir rol oynar ve kodunuzun daha modüler, sürdürülebilir ve test edilebilir olmasını sağlar. Bu blog yazısında, Angular’da servislerin temellerini ve dependency injection (bağımlılık enjeksiyonu) ile nasıl kullanıldığını ele alacak ve ipuçları sağlayacağız. Aşağıda, Angular’da servisler ve dependency injection konusunu örneklerle anlatacağız.

  • Servislerin Oluşturulması: Angular’da servisler, @Injectable dekoratörü ile işaretlenmiş sınıflardır. Servisler, genellikle özellikle veri işleme, veri kaynağından veri alma veya dış servislere istek gönderme gibi iş mantığıyla ilgili görevleri yerine getirir. İşte bir örnek:

import { Injectable } from '@angular/core';

@Injectable()
export class DataService {
  private data: string[];

  constructor() {
    this.data = ['Veri 1', 'Veri 2', 'Veri 3'];
  }

  getData(): string[] {
    return this.data;
  }

  addData(newData: string): void {
    this.data.push(newData);
  }
}

Yukarıdaki örnekte, DataService adında bir servis oluşturduk. @Injectable dekoratörü, Angular’a bu sınıfın bir servis olduğunu bildirir. Servisimiz, data adında bir diziye sahiptir ve getData ve addData metotlarıyla bu verilere erişebilir ve yeni veri ekleyebilir.

  • Servisin Bağımlılıklarının Enjekte Edilmesi: Dependency injection (bağımlılık enjeksiyonu), bir bileşenin veya başka bir servisin, ihtiyaç duyduğu başka bir bileşeni veya servisi otomatik olarak almasını sağlar. Angular, servislerin bağımlılıklarını otomatik olarak enjekte edebilmek için bir enjektör sistemi sağlar. İşte bir örnek:
import { Component } from '@angular/core'; 
import { DataService } from './data.service'; 
@Component({ 
 selector: 'app-my-component', 
 template: `
 <h1>{{ data }}</h1>  
 <button (click)="addNewData()">Yeni Veri Ekle</button>  ` 
}) 
export class MyComponent { 
 data: string[]; 
 constructor(private dataService: DataService) { 
 this.data = this.dataService.getData(); 
 } 

 addNewData(): void { 
 this.dataService.addData('Yeni Veri'); 
 this.data = this.dataService.getData(); 
 } 
} 

Yukarıdaki örnekte, MyComponent adında bir bileşen var. DataService servisinin bağımlılığını constructor içinde enjekte ediyoruz. Böylece, dataService üzerinden getData ve addData metotlarına erişebiliriz. Bileşenimizde, data adında bir değişken tanımlayarak servisin verilerini gösteriyoruz ve addNewData metoduyla yeni bir veri ekleyebiliyoruz.

  • Servislerin Kapsamı: Angular’da servislerin kapsamı, servis örneğinin nasıl oluşturulup yönetileceğini belirler. Kapsam, @Injectable dekoratöründe providedIn seçeneğiyle belirlenir. Yaygın olarak kullanılan kapsam seçenekleri şunlardır:
  • providedIn: 'root': Servis, uygulamanın kök modülü tarafından sağlanır. Her bileşen için tek bir örnek oluşturulur ve uygulama boyunca paylaşılır.
    • providedIn: SomeModule: Servis, belirli bir modül tarafından sağlanır. Her modül için tek bir örnek oluşturulur ve o modül içinde paylaşılır.
    
    import { Injectable } from '@angular/core';
    
    @Injectable({
      providedIn: 'root'
    })
    export class MyService {
      // Servis fonksiyonları ve özellikleri burada tanımlanır
    }
    
    

    Yukarıdaki örnekte, MyService adında bir servis oluşturulmuştur ve providedIn seçeneğiyle kapsamı belirlenmiştir. Bu örnek, servisin uygulamanın kök modülü tarafından sağlandığını gösterir.

    • Servislerin Test Edilmesi:

    Angular, servislerin kolayca test edilebilmesi için sağlam bir altyapı sunar. Servis fonksiyonları ve bağımlılıkları, bileşenlerin providers özelliği aracılığıyla sahte (mock) sürümlerle değiştirilebilir. Böylece, servislerin test edilmesi sırasında dış bağımlılıklara gerçek erişim sağlanmaz. İşte bir örnek:

    
    import { TestBed } from '@angular/core/testing';
    import { DataService } from './data.service';
    
    describe('DataService', () => {
      let service: DataService;
    
      beforeEach(() => {
        TestBed.configureTestingModule({});
        service = TestBed.inject(DataService);
      });
    
      it('should be created', () => {
        expect(service).toBeTruthy();
      });
    
      it('should return data', () => {
        const data = service.getData();
        expect(data).toEqual(['Veri 1', 'Veri 2', 'Veri 3']);
      });
    
      it('should add new data', () => {
        service.addData('Yeni Veri');
        const data = service.getData();
        expect(data).toContain('Yeni Veri');
      });
    });
    
    

    Yukarıdaki örnek, DataService servisinin test edilmesini gösterir. TestBed sınıfı, testlerde servis ve bağımlılıklarının enjekte edilmesini sağlar. beforeEach bloğunda test için gerekli yapılandırmalar yapılır ve TestBed.inject metoduyla servis örneği alınır. Ardından, çeşitli test senaryoları tanımlanır. Örneğin, verilerin doğru şekilde döndürüldüğünü veya yeni veri eklemesi yapıldığını doğrulayabiliriz.

    Sonuç: Angular’da servisler ve dependency injection, uygulamanızın modülerliğini, sürdürülebilirliğini ve test edilebilirliğini artıran önemli bir bileşendir. Bu blog yazısında, servislerin oluşturulması, bağımlılık enjeksiyonu, servislerin kapsamı ve servislerin test edilmesi gibi temel konuları ele aldık. Angular’da servisleri etkin bir şekilde kullanarak, uygulamanızın performansını ve kod kalitesini artırabilirsiniz.

    Bir yanıt yazın

    E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir