Angular 14’de Dependency Injection İçin Gelen inject Fonksiyonu
Merhaba,
Angular mimarisi, 14. sürümde çok ilginç özelliklerin yanında ekstradan inject
fonksiyonu eşliğinde dependency injection’a yeni bir yaklaşım getirmiş bulunmaktadır. Bu içeriğimizde hem bu fonksiyonu değerlendirecek hem de kullanım alanları üzerine irdelemede bulunuyor olacağız. Ee o halde buyurun başlayalım…
inject Fonksiyonu
Angular 14 ile gelen ve @angular/core path’i altından erişilebilen inject
fonksiyonu sayesinde component, directive ve pipe’lar da dependency injection’ı farklı bir yaklaşımla kullanabilmekteyiz. Şöyle ki;
import { Component, inject } from '@angular/core'; import { HttpClient } from '@angular/common/http'; function getUrl(url: string) { return inject(HttpClient).get(url); } @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { data$ = getUrl("https://jsonplaceholder.typicode.com/todos/1").subscribe({ next: data => { console.log(data) } }); }
Yukarıda, basit bir get işlemi için ‘HttpClient’ nesnesine olan ihtiyacımızı constructor’a gerek kalmaksızın direkt inject
fonksiyonuyla giderdiğimizi görüyoruz. İşte burada inject
fonksiyonu kullanıldığı yapının injector’ını kullanarak dependency injection ile ilgili nesneyi talep etmekte ve işlemlerin gerçekleştirilmesini sağlamaktadır.
inject
fonksiyonu kullanıldığı yapının constructor seviyesinde çağrılmalıdır. Aksi taktirde hata verecektir. Misal olarak aşağıdaki gibi bir kullanıma meyledersek;
function getUrl(url: string) { return inject(HttpClient).get(url); } . . . export class AppComponent implements OnInit { ngOnInit(): void { const data$ = getUrl("https://jsonplaceholder.typicode.com/todos/1").subscribe({ next: data => { console.log(data) } }); } }
bahsedildiği gibi constructor seviyesinde tetiklenmediği için bizleri aşağıdaki hatayla karşılayacaktır.
Lakin aşağıdaki gibi yaklaşım sergilenirse hatasız çalışacaktır;
function getUrl(url: string) { return inject(HttpClient).get(url); } . . . export class AppComponent implements OnInit { data$ = getUrl("https://jsonplaceholder.typicode.com/todos/1"); ngOnInit(): void { const data = this.data$.subscribe({ next: data => { console.log(data) } }) } }
Dikkat ederseniz eğer özellikle servis sınıflarında constructor’ı haddinden fazla şişirecek olan dependency injection operasyonlarını inject
fonksiyonuyla törpüleyerek daha kullanılabilir bir hale getirebiliriz.
inject Fonksiyonunun Avantajları Nelerdir?
inject
fonksiyonunun bir çok faydası söz konusudur. Ama özellikle iki farklı durumda avantajlarını net bir şekilde gözlemleyebilmekteyiz. Bu durumların ilki abstract class’larda dependency injection operasyonu iken, diğeri ise ön konfigürasyon gerektiren çalışmaların olduğu durumlardır. Şimdi gelin her iki durumu da sırasıyla inceleyelim.
Normal şartlarda abstract class’lar da dependency injection’ı gerçekleştirirken aşağıdaki gibi bir davranış sergileyebiliyoruz;
@Directive() export abstract class BaseComponent { constructor(protected activatedRote: ActivatedRoute, protected router: Router) { } }
Bu şekilde constructor’ı parametreli bir abstract class @Directive
dekoratörü ile işaretliyse direkt aşağıdaki gibi kalıtımsal durumlarda kullanılabiliyor.
export class AppComponent extends BaseComponent { }
Yani burada @Directive
dekoratörü sayesinde abstract class olan ‘BaseComponent’in constructor’ına aşağıdaki gibi super
fonksiyonu aracılığıyla değer göndermek zorunda kalmıyoruz.
export class AppComponent extends BaseComponent { constructor(activatedRote: ActivatedRoute, router: Router) { super(activatedRote, router); } }
Tabi eğer ki bu sınıfta dependency injection üzerinden farklı bir instance talebinde bulunulacaksa işte o zaman super
fonksiyonu aşağıdaki gibi zoraki call edilmek mecburiyetinde kalınacaktır.
export class AppComponent extends BaseComponent { constructor(private service: ServiceWorker, activatedRote: ActivatedRoute, router: Router) { super(activatedRote, router); } }
Velhasıl işte bu tarz kurallı durumlardan inject
fonksiyonu sayesinde kurtulabilmekte ve aşağıdaki gibi çalışma gerçekleştirebilmekteyiz.
@Directive() export abstract class BaseComponent { protected readonly activatedRoute: ActivatedRoute = inject(ActivatedRoute); protected readonly router: Router = inject(Router); }
export class AppComponent extends BaseComponent { }
Bu vaziyette ‘AppComonent’te farklı bir dependency injection’a ihtiyaç duyulursa kalıtım mevzu bahis olduğu için base class’ın constructor’ı super
fonksiyonu ile call edilecek lakin herhangi bir parametre verilmek mecburiyetinde kalınmayacaktır.
Bir diğer avantajlı duruma ise ön konfigürasyon gerektiren çalışmalar demiştik. Şöyle ki;
function injectIcon() { const iconRegistry = inject(MatIconRegistry); const domSanitizer = inject(DomSanitizer); const url = domSanitizer.bypassSecurityTrustResourceUrl("assest/icons/icon.svg"); iconRegistry.addSvgIcon("github", url); } . . . export class AppComponent { constructor() { injectIcon(); } }
Yukarıda, Angular material kütüphanesinin ‘MatIconRegistry’ modülünde icon özelleştirmesini gerçekleştirdiğimiz örnek bir kod bloğunu görmektesiniz. Bu çalışmanın sonradan ihtiyaç olmadığından uygulamadan kaldırılacağını varsayarsak eğer bu kütüphanelerle ilgilenmek zorunluluğu kalınmayacak ve sadece bu fonksiyonun çağrıldığı noktadan kaldırılması yeterli olacaktır. Böylece uygulamada bu gün var olup yarın olmayabilecek çalışmaların, ihtiyaç kalmadığı taktirde uygulama genelinde temizlenme/kaldırılma gibi side effect’leriyle uğraşılmayacaktır. İşte avantajlarından biri de budur…
Evet… Böylece Angular 14 ile gelen yeniliklerden birini daha incelemiş olduk.
Okuyarak eşlik ettiğiniz için teşekkür ederim.
İlgilenenlerin faydalanması dileğiyle…
Sonraki yazılarımda görüşmek üzere…
İyi çalışmalar…
Hocam selamlar merk ettiğim birşey var bnu kadar bilgiyi hem inceleyip hem yazıp hem de nasıl derinlemesine bilebiliyorsunuz hiç uyumuyor musunuz yad dışarı cıkmıyor musunuz merak ettiğim şey bu kadr hızlı öğrenmenin yolu zira ben cok yavaş olduuğumu hisediyorum size göre
Merhaba,
Ben hızlı öğrenmiyorum. Sadece merak ettiğim her konuya gerekli zamanı ayırmayı ve onun için çabalamayı seviyorum. Yani anlayacağınız severek çalışıyorum. Ayrıca yazılım dışında farklı işlerle ilgileniyorum, farklı araştırmalar yapıyorum bu da benim o anki konuya daha rahat odaklanmamı sağlıyor. Amma velakin tüm bunları yaparken yüksek lisans tezimi yazacak vakitte bulamıyorum tabi ki. Yani hayatta bir tarafı artılarken illaki başka bir taraftan eksilerimiz oluyor.
Sevgiler.