Front End

4 ago, 2017

Injetando interfaces no Typescript

Publicidade

Para quem já trabalha com linguagens server side e está familiarizado com orientação a objetos, deve saber que o uso de interfaces em sua aplicação é uma prática altamente recomendada, por conta de diversos motivos, sendo o principal para mim, o desacoplamento entre classes.

O Typescript é um Superset do JavaScript que permite escrevermos códigos com estrutura fortemente tipada, com uma sintaxe muito próxima ao do C#, e que no final das contas, tudo será compilado para JavaScript puro, funcionando em todos os browsers.

Quando usamos Services no Angular 4 (como utilizar Services no Angular 4), utilizamos a Injeção de Dependência nos módulos em que iremos consumir nosso serviço, e em algumas situações desejamos injetar uma interface, pois a implementação desse nosso método poderá ocorrer de maneiras diferentes e não interessa ao nosso módulo saber como isso ocorre.

O problema que temos nessa abordagem, é que Interfaces não são suportadas na injeção de dependência, isso por que o JavaScript não possui essa feature e ocorrerá erro ao executar a compilação.

Para solucionar esse problema, utilizaremos Keys para injetar nossa interface. Vamos lá:

Crie um projeto através do Angular CLI e dê o nome de tutorial- interface, conforme comando abaixo:

ng new tutorial-interfaces

Nota: Caso o angular CLI não crie a pasta node_modules, execute o comando npm install.

Com nosso projeto criado, abra-o em seu editor preferido, no meu caso o VS Code.

Na pasta Src, selecione o arquivo app.component.html e altere para o código abaixo:

<div style="text-align:center">
<h1>
    Tutorial de Injeção de Dependência de Interfaces
</h1>
</div>
 
<h2>Estamos chamando o método: buscarDadosNoBanco() : {{retorno}} </h2>

Feito isso, vamos criar nosso serviço IDadosService, que será uma interface, e declarar o método buscarDadosNoBanco, conforme código abaixo:

export interface IDadosService{
    buscarDadosNoBanco():string;
}

Agora, criaremos duas novas classes que irão implementar esse nosso método buscarDadosNoBanco, DadosSQL.ts e DadosOracle.ts.

import { Injectable } from '@angular/core';
import { IDadosService} from './IDadosService';
 
@Injectable()
export class DadosSQL implements IDadosService{
    buscarDadosNoBanco():string{
      return"Buscamos os dados no banco SQL Server";
    }
}

 

import { Injectable } from '@angular/core';
import { IDadosService } from './IDadosService';
 
@Injectable()
export class DadosOracle implements IDadosService {
    buscarDadosNoBanco():string{
        return "Buscamos os dados no banco ORACLE";
    }
}

Note que usamos a marcação @Injectable(), para informar que essa classe pode ser injetada em nossos módulos.

Pronto! Agora temos nossa interface sendo implementada tanto no banco SQL, quanto no Oracle.

O próximo passo é alterarmos nosso módulo para receber nosso serviço e atualizar nosso texto na tela. Vamos ao arquivo app.component.ts e substitua pelo código a seguir:

import { Component } from '@angular/core';
import { IDadosService } from './IDadosService';
import { Inject  } from '@angular/core';
 
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
 
export class AppComponent {
  retorno:string;
 
  constructor(@Inject('IDadosServiceToken') private dadosService: IDadosService ){
    this.retorno = this.dadosService.buscarDadosNoBanco();
  }
}
Explicando nosso módulo:
import { IDadosService } from './IDadosService';
import { Inject } from '@angular/core';
Aqui, fazemos o import da nossa interface e do módulo Inject do Angular.
constructor(@Inject('IDadosServiceToken') private dadosService: IDadosService ){
    this.retorno = this.dadosService.buscarDadosNoBanco();
  }

Injetamos no nosso construtor a interface IDadosService, utilizando uma Key ‘IDadosServiceToken’, que será definida no próximo passo.

Para finalizar e testar se tudo funciona, vamos no arquivo app.modules.ts e altere para o código abaixo:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { DadosSQL } from './DadosSQL';
import { DadosOracle } from './DadosOracle';
 
import { AppComponent } from './app.component';
 
@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule
  ],
  providers: [{provide: 'IDadosServiceToken', useClass: DadosSQL}],
  bootstrap: [AppComponent],
   
})
export class AppModule { }

O que fizemos acima foi, em primeiro lugar, importar nossas classes que serão utilizadas.
Depois, em providers, adicionamos nossa Key, e indicamos qual classe estamos utilizando para implementar nosso método.

Pronto! Rode a aplicação e o resultado será o seguinte:

Experimente trocar no provider, para utilizar a classe Oracle.

Até a próxima!