021-88881776

آموزش خدمات (Services) و Dependency Injection در Angular

اگر قصد دارید آموزش Angular را به‌طور کامل فرا بگیرید، درک عمیق از مفاهیمی مانند خدمات (Services) و Dependency Injection در Angular بسیار ضروری است. این مفاهیم، نقش کلیدی در سازمان‌دهی کد و مدیریت وابستگی‌ها در برنامه‌های Angular ایفا می‌کنند. در این مقاله، ابتدا با مفهوم خدمات آشنا می‌شویم، سپس به جزئیات وابستگی‌ها و نحوه کارکرد Dependency Injection (DI) می‌پردازیم.

خدمات (Services) و Dependency Injection در Angular چیست؟

خدمات (Services) در Angular واحدهایی از کد هستند که به منظور مدیریت منطق تجاری و عملیات مشترک در یک برنامه ایجاد می‌شوند. به‌جای نوشتن منطق تکراری در کامپوننت‌ها، می‌توان این منطق را در یک سرویس قرار داد و از آن در کامپوننت‌های مختلف استفاده کرد. این روش به شما کمک می‌کند تا کدی تمیزتر، قابل نگهداری‌تر، و مقیاس‌پذیر داشته باشید.

چرا از خدمات (Services) استفاده می‌کنیم؟

جداسازی منطق تجاری: سرویس‌ها به ما امکان می‌دهند که منطق تجاری را از کامپوننت‌ها جدا کنیم. این امر باعث کاهش پیچیدگی کامپوننت‌ها می‌شود.
قابلیت اشتراک‌گذاری: یک سرویس می‌تواند داده‌ها یا توابع خود را بین چندین کامپوننت به اشتراک بگذارد.
قابلیت تست‌پذیری: سرویس‌ها به‌صورت مستقل از کامپوننت‌ها تعریف می‌شوند و تست واحد برای آن‌ها آسان‌تر است.
افزایش انعطاف‌پذیری: با تغییر منطق در سرویس، رفتار تمام کامپوننت‌هایی که از آن استفاده می‌کنند به‌روزرسانی می‌شود.

Dependency Injection (DI) چیست؟

Dependency Injection (DI) یک الگوی طراحی است که وابستگی‌های مورد نیاز یک کلاس (مانند سرویس‌ها) را به‌جای اینکه خود کلاس آن‌ها را ایجاد کند، از بیرون به آن تزریق می‌کند. این الگو باعث کاهش Coupling (وابستگی) بین کلاس‌ها می‌شود و انعطاف‌پذیری کد را افزایش می‌دهد.

ارتباط خدمات و Dependency Injection

در Angular، سرویس‌ها اغلب به کمک DI به کامپوننت‌ها یا سایر سرویس‌ها تزریق می‌شوند. زمانی که یک کامپوننت نیاز به دسترسی به یک سرویس داشته باشد، Angular به‌طور خودکار نمونه‌ای از آن سرویس را ایجاد و تزریق می‌کند. این فرآیند با استفاده از دکوریتور @Injectable() و تنظیمات Providers در ماژول‌ها یا کامپوننت‌ها مدیریت می‌شود.

نقش Services و DI در معماری Angular

Angular مبتنی بر معماری Component-Based است که در آن هر کامپوننت مسئول یک بخش از رابط کاربری (UI) است. برای جلوگیری از نوشتن کدهای پیچیده و غیرقابل

نگهداری در کامپوننت‌ها:

Services وظایف مشترک مانند مدیریت داده‌ها، منطق API، یا ذخیره‌سازی موقت اطلاعات را بر عهده می‌گیرند.
DI فرآیند ارائه و تزریق این خدمات به کامپوننت‌ها یا سایر بخش‌های برنامه را مدیریت می‌کند.

یک مثال ساده از Services و DI در Angular

فرض کنید برنامه‌ای دارید که لیستی از کاربران را از یک API دریافت می‌کند. به جای نوشتن این منطق در کامپوننت، آن را در یک سرویس قرار می‌دهید:

سرویس:

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';

@Injectable({
  providedIn: 'root',
})
export class UserService {
  private apiUrl = 'https://jsonplaceholder.typicode.com/users';

  constructor(private http: HttpClient) {}

  getUsers(): Observable<any[]> {
    return this.http.get<any[]>(this.apiUrl);
  }
}

کامپوننت:

import { Component, OnInit } from '@angular/core';
import { UserService } from './user.service';

@Component({
  selector: 'app-user-list',
  template: `
    <ul>
      <li *ngFor="let user of users">{{ user.name }}</li>
    </ul>
  `,
})
export class UserListComponent implements OnInit {
  users: any[] = [];

  constructor(private userService: UserService) {}

  ngOnInit() {
    this.userService.getUsers().subscribe((data) => (this.users = data));
  }
}

در این مثال:

منطق دریافت داده‌ها از API در UserService تعریف شده است.
UserListComponent این سرویس را با استفاده از DI به سازنده خود تزریق می‌کند و از آن برای دریافت داده‌ها استفاده می‌کند.

استفاده از خدمات (Services) و Dependency Injection در Angular یک اصل اساسی است که باعث بهبود طراحی، تست‌پذیری، و نگهداری کدهای شما می‌شود.

ایجاد و استفاده از Services: تعریف خدمات با @Injectable()

در Angular، ایجاد و استفاده از Services یکی از مهم‌ترین اصول طراحی است که امکان مدیریت منطقی و اشتراک‌گذاری داده‌ها بین کامپوننت‌ها را فراهم می‌کند. برای تعریف خدمات، از یک کلاس TypeScript همراه با دکوریتور @Injectable() استفاده می‌کنیم. این دکوریتور به Angular اعلام می‌کند که این کلاس یک سرویس است و می‌تواند وابستگی‌ها را تزریق کند.

گام‌های ایجاد و استفاده از Services

1. ایجاد فایل سرویس

Angular به‌طور خودکار ابزارهایی برای ساخت سرویس‌ها ارائه می‌دهد. برای ایجاد یک سرویس جدید، از دستور زیر در CLI استفاده کنید:

ng generate service my-service

این دستور یک فایل TypeScript جدید همراه با ساختار اولیه سرویس ایجاد می‌کند.

2. تعریف سرویس با @Injectable()

دکوریتور @Injectable() نقش اصلی را در تعریف خدمات در Angular ایفا می‌کند. این دکوریتور مشخص می‌کند که سرویس در کدام سطح از برنامه در دسترس است. به‌طور پیش‌فرض، بیشتر سرویس‌ها با providedIn: ‘root’ تعریف می‌شوند، به این معنا که در سطح ریشه (Root) برای کل برنامه قابل دسترسی هستند.

نمونه کد سرویس ساده:

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

@Injectable({
  providedIn: 'root', // سرویس در سطح ریشه در دسترس است
})
export class MyService {
  getMessage(): string {
    return 'سلام از MyService!';
  }
}

در این مثال:

دکوریتور @Injectable() به Angular اعلام می‌کند که MyService یک سرویس است.
کلیدواژه providedIn: ‘root’ تضمین می‌کند که این سرویس به صورت Singleton (یک نمونه) در کل برنامه استفاده می‌شود.

3. استفاده از سرویس در کامپوننت

برای استفاده از یک سرویس، آن را به کمک Dependency Injection (DI) به کامپوننت تزریق می‌کنیم. این فرآیند با افزودن سرویس به سازنده کلاس انجام می‌شود.

مثال استفاده از سرویس در کامپوننت:

import { Component } from '@angular/core';
import { MyService } from './my-service.service';

@Component({
  selector: 'app-root',
  template: `<h1>{{ message }}</h1>`,
})
export class AppComponent {
  message: string;

  constructor(private myService: MyService) {
    this.message = this.myService.getMessage(); // فراخوانی متد سرویس
  }
}

تزریق وابستگی: سرویس MyService به کمک سازنده (Constructor) به کلاس AppComponent تزریق شده است.
دسترسی به متدها: کامپوننت از متد getMessage برای دریافت داده‌ها استفاده می‌کند.

اشتراک‌گذاری داده‌ها بین کامپوننت‌ها با استفاده از خدمات

یکی از مزایای کلیدی ایجاد و استفاده از Services در Angular، امکان اشتراک‌گذاری داده‌ها بین کامپوننت‌ها است. این کار به کمک متغیرها و متدهایی که در سرویس تعریف شده‌اند انجام می‌شود.

تعریف سرویس برای اشتراک‌گذاری داده‌ها:

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

@Injectable({
  providedIn: 'root',
})
export class DataService {
  private data: string = ''; // متغیر برای ذخیره داده

  setData(newData: string) {
    this.data = newData; // تنظیم داده
  }

  getData(): string {
    return this.data; // دریافت داده
  }
}

اشتراک‌گذاری داده‌ها بین دو کامپوننت

کامپوننت فرستنده (SenderComponent):

import { Component } from '@angular/core';
import { DataService } from './data.service';

@Component({
  selector: 'app-sender',
  template: `<button (click)="sendData()">ارسال پیام</button>`,
})
export class SenderComponent {
  constructor(private dataService: DataService) {}

  sendData() {
    this.dataService.setData('سلام!'); // ارسال پیام
  }
}

کامپوننت گیرنده (ReceiverComponent):

import { Component, OnInit } from '@angular/core';
import { DataService } from './data.service';

@Component({
  selector: 'app-receiver',
  template: `<h2>{{ message }}</h2>`,
})
export class ReceiverComponent implements OnInit {
  message: string = '';

  constructor(private dataService: DataService) {}

  ngOnInit() {
    this.message = this.dataService.getData(); // دریافت پیام
  }
}

نکات مهم

استفاده از خدمات (Services) و @Injectable() باعث مدیریت بهتر منطق و کاهش تکرار کد می‌شود.
ایجاد و استفاده از Services روشی استاندارد برای اشتراک‌گذاری داده‌ها و پیاده‌سازی الگوی Dependency Injection است.
در صورت نیاز به سطح دسترسی محدودتر برای یک سرویس، می‌توانید آن را در سطح یک ماژول یا کامپوننت خاص ارائه دهید. این روش‌ها به شما کمک می‌کنند که ساختار برنامه‌ای مقیاس‌پذیر و قابل نگهداری را در Angular طراحی کنید.

مفهوم Dependency Injection (DI) و نحوه کار آن در Angular

Dependency Injection (DI) یکی از اصول اصلی طراحی در Angular است که برای مدیریت وابستگی‌ها به کار می‌رود. این الگو، وابستگی‌های یک کلاس را از طریق تزریق خارجی فراهم می‌کند و بدین ترتیب ساختار کد را ساده‌تر، قابل مدیریت‌تر، و قابل تست‌تر می‌سازد.

تعریف Dependency Injection (DI)

به زبان ساده، Dependency Injection (DI) به معنای تزریق وابستگی‌ها از بیرون به یک کلاس است، به‌جای اینکه کلاس به‌طور مستقیم این وابستگی‌ها را ایجاد یا مدیریت کند. وابستگی‌ها معمولاً شامل سرویس‌ها، داده‌ها، یا هر مورد دیگری هستند که کلاس برای انجام وظایف خود به آن نیاز دارد.

چرا DI در Angular مهم است؟

تفکیک وظایف (Separation of Concerns):
کامپوننت‌ها و سرویس‌ها فقط بر روی وظایف خود تمرکز می‌کنند، در حالی که وابستگی‌ها توسط Angular مدیریت می‌شوند.

افزایش قابلیت تست‌پذیری:
با تزریق وابستگی‌ها، می‌توان نسخه‌های شبیه‌سازی شده (Mock) وابستگی‌ها را برای تست استفاده کرد.

انعطاف‌پذیری و مقیاس‌پذیری:
تغییر در وابستگی‌ها نیاز به تغییر مستقیم در کلاس‌ها ندارد، که این امر توسعه و نگهداری کد را آسان‌تر می‌کند.

نحوه کار DI در Angular

Angular از یک Injector برای مدیریت وابستگی‌ها استفاده می‌کند. این فرایند شامل مراحل زیر است:

ایجاد وابستگی‌ها (Services):
ابتدا وابستگی‌ها در قالب سرویس تعریف می‌شوند.

ثبت وابستگی‌ها (Providers):
وابستگی‌ها در یک ماژول یا کامپوننت ثبت می‌شوند. این کار معمولاً با استفاده از providedIn: ‘root’ در دکوریتور @Injectable() انجام می‌شود.

تزریق وابستگی‌ها:
Angular از طریق سازنده کلاس (constructor) وابستگی‌ها را به کامپوننت‌ها یا دیگر سرویس‌ها تزریق می‌کند.

مثال ساده از Dependency Injection در Angular

مرحله 1: تعریف سرویس (وابستگی):

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

@Injectable({
  providedIn: 'root',
})
export class MyService {
  getMessage(): string {
    return 'پیام از MyService!';
  }
}

مرحله 2: استفاده از سرویس در یک کامپوننت:

import { Component } from '@angular/core';
import { MyService } from './my-service.service';

@Component({
  selector: 'app-root',
  template: `<h1>{{ message }}</h1>`,
})
export class AppComponent {
  constructor(private myService: MyService) {}

  get message(): string {
    return this.myService.getMessage();
  }
}

توضیحات کد:

MyService یک سرویس است که با استفاده از @Injectable() تعریف شده است.
در کامپوننت AppComponent، سرویس MyService از طریق سازنده (constructor) تزریق شده است.
کامپوننت به کمک متد getMessage پیام را از سرویس دریافت می‌کند.

نحوه تنظیم Providers

Providers به Angular اعلام می‌کنند که چگونه یک وابستگی را ایجاد و مدیریت کند. می‌توان آن‌ها را در سطح ماژول، کامپوننت یا سرویس تعریف کرد.

ثبت سرویس در سطح ریشه (Root):

این روش معمول‌ترین روش است و از طریق providedIn: ‘root’ در دکوریتور @Injectable() انجام می‌شود.
سرویس در کل برنامه به‌عنوان یک Singleton قابل دسترسی خواهد بود.

ثبت سرویس در سطح ماژول:
اگر بخواهید سرویسی فقط در یک ماژول خاص قابل دسترسی باشد، می‌توانید آن را در آرایه providers ماژول ثبت کنید:

@NgModule({
  providers: [MyService],
})
export class MyModule {}

ثبت سرویس در سطح کامپوننت:
در این حالت، هر بار که کامپوننت نمونه‌سازی شود، یک نمونه جدید از سرویس ایجاد می‌شود:

@Component({
  providers: [MyService],
})
export class MyComponent {}

نکات پیشرفته در استفاده از Dependency Injection در Angular

DI در سرویس‌ها:
شما می‌توانید وابستگی‌ها را به سرویس‌ها نیز تزریق کنید. این کار با استفاده از سازنده سرویس انجام می‌شود:

constructor(private httpClient: HttpClient) {}

استفاده از Token برای DI:
با استفاده از InjectionToken می‌توان وابستگی‌های خاصی را مدیریت کرد:

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

export const API_URL = new InjectionToken<string>('API_URL');

Hierarchical Injectors:
Angular از ساختار سلسله مراتبی برای Injectors استفاده می‌کند. وابستگی‌ها می‌توانند در سطوح مختلف (ریشه، ماژول، کامپوننت) تعریف شوند.

Dependency Injection (DI) در Angular یکی از ابزارهای کلیدی برای مدیریت وابستگی‌ها است. این الگو نه‌تنها کد را ساده‌تر و مقیاس‌پذیرتر می‌کند، بلکه توسعه‌دهندگان را قادر می‌سازد تا از بهترین شیوه‌های طراحی نرم‌افزار بهره‌مند شوند. با درک کامل DI، می‌توانید کدی انعطاف‌پذیر، تست‌پذیر و قابل نگهداری بنویسید.

تنظیم ارائه‌دهندگان (Providers) در ماژول‌ها و کامپوننت‌ها

در Angular، Providers یکی از اجزای کلیدی سیستم Dependency Injection (DI) هستند. آن‌ها مشخص می‌کنند که چگونه Angular باید نمونه‌ای از یک سرویس یا وابستگی را مدیریت کند و در کدام محدوده (scope) در دسترس قرار دهد. با تنظیم صحیح Providers می‌توان کنترل دقیقی بر طول عمر و نحوه دسترسی به سرویس‌ها داشت.

تنظیم Providers در سطح ماژول

زمانی که نیاز دارید یک سرویس در کل برنامه در دسترس باشد، باید آن را در سطح ماژول تعریف کنید. این روش معمولاً برای سرویس‌های مشترک و سراسری برنامه استفاده می‌شود.

مثال: ثبت Provider در سطح ماژول

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { MyService } from './my-service.service';

@NgModule({
  declarations: [AppComponent],
  imports: [BrowserModule],
  providers: [MyService], // ارائه‌دهنده سرویس در سطح ماژول
  bootstrap: [AppComponent],
})
export class AppModule {}

در این مثال:

MyService به عنوان یک ارائه‌دهنده (Provider) در سطح ماژول تعریف شده است.
این سرویس به صورت Singleton در کل برنامه در دسترس خواهد بود.

تنظیم Providers در سطح کامپوننت

اگر بخواهید یک سرویس تنها در یک کامپوننت خاص و فرزندان آن استفاده شود، می‌توانید آن را در سطح همان کامپوننت تعریف کنید. در این حالت، برای هر نمونه از کامپوننت، یک نمونه جدید از سرویس ایجاد می‌شود. این روش برای محدود کردن دسترسی به سرویس‌ها در یک محدوده خاص کاربرد دارد.

مثال: ثبت Provider در سطح کامپوننت

import { Component } from '@angular/core';
import { MyService } from './my-service.service';

@Component({
  selector: 'app-child',
  template: `<p>Child works!</p>`,
  providers: [MyService], // این سرویس فقط در این کامپوننت و فرزندانش معتبر است
})
export class ChildComponent {
  constructor(private myService: MyService) {
    console.log(this.myService.getMessage());
  }
}

در این مثال:

MyService فقط در کامپوننت ChildComponent و فرزندان آن در دسترس است.
این روش برای جداسازی وظایف و جلوگیری از اشتراک‌گذاری ناخواسته داده‌ها مفید است.

ثبت سرویس به صورت Singleton در سطح ریشه

در Angular نسخه 6 به بعد، می‌توانید سرویس‌ها را به طور مستقیم در سطح ریشه ثبت کنید. این کار با استفاده از ویژگی providedIn: ‘root’ در دکوریتور @Injectable() انجام می‌شود. این روش باعث ساده‌تر شدن کدنویسی و بهینه‌سازی اندازه نهایی باندل برنامه می‌شود.

مثال:

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

@Injectable({
  providedIn: 'root', // سرویس به طور خودکار در سطح ریشه ثبت می‌شود
})
export class MyService {
  getMessage(): string {
    return 'سلام از MyService!';
  }
}

مزیت این روش:

نیازی به افزودن سرویس به آرایه providers در ماژول نیست.
Angular به طور خودکار وابستگی‌ها را مدیریت کرده و از ایجاد نمونه‌های غیرضروری جلوگیری می‌کند.

نکات مهم درباره تنظیم Providers

اگر یک سرویس را در سطح ماژول ثبت کنید، تنها یک نمونه از آن در کل برنامه ایجاد می‌شود.
ثبت سرویس در سطح کامپوننت باعث می‌شود برای هر نمونه از کامپوننت، یک نمونه جدید از سرویس ایجاد شود.
استفاده از گزینه providedIn: ‘root’ در دکوریتور @Injectable() راهکار پیش‌فرض و پیشنهادی Angular برای مدیریت سرویس‌ها در سطح ریشه است.تنظیم Providers در Angular یکی از بخش‌های اساسی مدیریت وابستگی‌ها است. انتخاب سطح مناسب برای ثبت سرویس‌ها، تأثیر قابل توجهی در عملکرد و سازماندهی کدهای برنامه شما دارد. درک صحیح این تنظیمات به شما کمک می‌کند تا برنامه‌هایی مقیاس‌پذیر، کارآمد، و با ساختار منطقی طراحی کنید.

چرا از Dependency Injection استفاده کنیم؟

Dependency Injection (DI) یک الگوی طراحی بسیار قدرتمند است که در Angular برای مدیریت وابستگی‌ها از آن استفاده می‌شود. این الگو کمک می‌کند تا وابستگی‌ها از بیرون کلاس‌ها به آن‌ها تزریق شوند، به جای اینکه در داخل کلاس‌ها ساخته شوند. استفاده از DI در Angular مزایای بسیاری دارد که در اینجا به مهم‌ترین آن‌ها اشاره خواهیم کرد.

۱. افزایش تست‌پذیری

یکی از بزرگ‌ترین مزایای استفاده از Dependency Injection، افزایش تست‌پذیری است. در Angular، با استفاده از DI، وابستگی‌ها به صورت خودکار و از بیرون به کامپوننت‌ها یا سرویس‌ها تزریق می‌شوند، بنابراین شما می‌توانید هر وابستگی را در زمان نوشتن تست‌ها، به راحتی شبیه‌سازی (mock) کنید.

چرا تست‌پذیری افزایش می‌یابد؟

کاهش وابستگی‌های مستقیم: در DI، وابستگی‌ها مستقیماً در داخل کلاس‌ها ایجاد نمی‌شوند، بلکه از بیرون به آن‌ها تزریق می‌شوند. این به شما اجازه می‌دهد تا به راحتی از شبیه‌سازهای وابستگی (mock services) در تست‌ها استفاده کنید.
ایجاد تست‌های جداگانه: شما می‌توانید به‌صورت مستقل از سایر بخش‌های برنامه، کامپوننت‌ها و سرویس‌ها را تست کنید. به‌عنوان مثال، می‌توانید فقط منطق یک سرویس را تست کنید بدون اینکه نیاز باشد آن را به کامپوننت یا دیگر سرویس‌ها متصل کنید.

مثال:

فرض کنید سرویس AuthService را داریم که در کامپوننت LoginComponent استفاده می‌شود. در تست، شما می‌توانید AuthService را به راحتی شبیه‌سازی کرده و بدون نیاز به وابستگی به API‌های واقعی، رفتار آن را تست کنید.

import { TestBed } from '@angular/core/testing';
import { LoginComponent } from './login.component';
import { AuthService } from './auth.service';

describe('LoginComponent', () => {
  let component: LoginComponent;
  let authService: AuthService;

  beforeEach(() => {
    authService = { login: () => 'mocked login' } as any;
    TestBed.configureTestingModule({
      declarations: [LoginComponent],
      providers: [{ provide: AuthService, useValue: authService }]
    });
    component = TestBed.createComponent(LoginComponent).componentInstance;
  });

  it('should call login method', () => {
    component.login();
    expect(authService.login).toHaveBeenCalled();
  });
});

۲. قابلیت استفاده مجدد

Dependency Injection به شما این امکان را می‌دهد که سرویس‌ها را در پروژه‌های مختلف به‌راحتی به اشتراک بگذارید. وقتی سرویس‌ها به صورت خودکار از طریق DI مدیریت می‌شوند، دیگر نیازی به نوشتن مجدد منطق تجاری یا ویژگی‌های یکسان برای هر کامپوننت یا پروژه جدید نیست. این به ویژه در پروژه‌های بزرگ یا پروژه‌هایی که نیاز به گسترش و مقیاس‌پذیری دارند، بسیار مفید است.

چرا قابلیت استفاده مجدد افزایش می‌یابد؟

سرویس‌های قابل اشتراک‌گذاری: شما می‌توانید یک سرویس را در یک ماژول یا کامپوننت خاص ایجاد کرده و آن را به‌راحتی در سایر بخش‌های برنامه یا حتی پروژه‌های دیگر استفاده کنید.
کاهش تکرار کد: از آنجا که سرویس‌ها مستقل از کامپوننت‌ها طراحی می‌شوند، نیازی به نوشتن دوباره همان منطق در چندین مکان ندارید.

مثال:

فرض کنید یک سرویس LoggingService برای ثبت لاگ‌ها دارید. این سرویس را می‌توانید در هر کامپوننت یا ماژولی از برنامه خود که نیاز به ثبت لاگ دارد، استفاده کنید. این سرویس قابل استفاده مجدد است و دیگر نیازی به نوشتن کد مشابه در هر کامپوننت نخواهید داشت.

۳. کاهش Coupling

یکی دیگر از مزایای کلیدی استفاده از Dependency Injection، کاهش coupling (وابستگی‌های زیاد بین اجزاء برنامه) است. در سیستم‌هایی که از DI استفاده می‌کنند، وابستگی‌ها به صورت شفاف و مدیریت‌شده از بیرون به کلاس‌ها تزریق می‌شوند، بنابراین کد شما مستقل‌تر، قابل نگهداری‌تر و مقیاس‌پذیرتر می‌شود.

چرا coupling کاهش می‌یابد؟

جدا شدن مسئولیت‌ها: در DI، کلاس‌ها مسئول ایجاد وابستگی‌های خود نیستند. این وابستگی‌ها از بیرون وارد می‌شوند و به این ترتیب هر کلاس فقط وظایف خاص خود را انجام می‌دهد.
مدیریت وابستگی‌ها: به جای اینکه هر کلاس وابستگی‌های خود را مدیریت کند، سیستم DI مسئول مدیریت این وابستگی‌ها است، که باعث کاهش پیچیدگی کد و تعاملات بین کلاس‌ها می‌شود.

مثال:

اگر شما یک سرویس NotificationService دارید که مسئول ارسال اعلان‌ها است، به جای اینکه آن را مستقیماً در هر کامپوننتی که نیاز به ارسال اعلان دارد، بسازید، می‌توانید این سرویس را از طریق DI تزریق کنید. این کار باعث می‌شود که کلاس‌ها از هم مستقل باشند و در نتیجه کد تمیزتر و با کیفیت‌تری داشته باشید.

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

@Injectable({
  providedIn: 'root',
})
export class NotificationService {
  sendNotification(message: string) {
    console.log('Notification:', message);
  }
}

Dependency Injection در Angular یکی از اصول طراحی قدرتمند است که می‌تواند به بهبود تست‌پذیری، قابلیت استفاده مجدد سرویس‌ها و کاهش coupling در پروژه‌های شما کمک کند. این ویژگی به شما اجازه می‌دهد تا وابستگی‌ها را به شکلی منظم و شفاف مدیریت کنید، که نه تنها باعث بهبود ساختار کد می‌شود بلکه توسعه و نگهداری آن را ساده‌تر می‌کند.

نتیجه‌گیری

در این مقاله، مفهوم خدمات (Services) و Dependency Injection در Angular را به طور جامع بررسی کردیم و نحوه استفاده از این الگو در توسعه برنامه‌های Angular را توضیح دادیم. استفاده از خدمات به ما این امکان را می‌دهد که منطق تجاری و داده‌ها را به طور مؤثری مدیریت کنیم و آن‌ها را بین کامپوننت‌ها به اشتراک بگذاریم. همچنین، Dependency Injection به ما کمک می‌کند تا وابستگی‌ها را به صورت شفاف و مؤثر مدیریت کنیم، که این کار به افزایش تست‌پذیری، کاهش coupling و بهبود قابلیت استفاده مجدد سرویس‌ها می‌انجامد.

با استفاده از خدمات (Services) و Dependency Injection در Angular، می‌توانیم کدی تمیزتر، مقیاس‌پذیرتر و قابل نگهداری‌تر بنویسیم که به توسعه‌دهندگان این امکان را می‌دهد تا پروژه‌های پیچیده‌تر را با کارایی بالاتر و خطاهای کمتر مدیریت کنند.

آموزش خدمات (Services) و Dependency Injection در Angular

دیدگاه های شما

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *