Usługa Angular 6 z frontendem


Tworzę aplikację w Angular (
6.0.7
) i próbuję utworzyć usługę za pomocą nowej:
@Injectable({
providedIn: 'root'
})

Ale jak mogę wstrzyknąć za pomocą interfejsu?

Problem

Mam 2 usługi,

Authentication.service

i

SessionStorage.service
... Chcę wstrzyknąć pamięć sesji do usługi uwierzytelniania. Można to zrobić za pomocą:
constructor(private sessionStorage: SessionStorage) {
}

Nie ma problemu. Ale dla celów obiektowych chcę mieć
interfejs
nad tą usługą (aby móc zaimplementować zarówno usługę localstorage, jak i usługę sessionstorage). Więc ma sens, że chcę wprowadzić wstrzykniętą klasę z interfejsem, ale nie można tego zrobić w taki sam sposób, jak

Kątowy 5 i niższy
https://coderoad.ru/40068456/
.
Jak więc mogę wstrzyknąć tę globalną usługę za pomocą mojego interfejsu?

próbowałem

Typy usług kątowych opisują
InjectableProvider
, ale to nie pasuje do żadnego z rodzeństwa
InjectableProvider
, więc powoduje błąd kompilatora (i tslint).
@Injectable({
providedIn: 'root'
}, {provide: IStorageService, useClass: SessionStorage})

Zaproszony:
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Można to zrobić za pomocą
InjectionToken
, który zastępuje przestarzały
OpaqueToken
export const AuthenticationProvider = new InjectionToken( "AuthenticationProvider",
{ providedIn: "root", factory: () => new CognitoAuthenticationProvider() });...@Injectable()
export class CognitoAuthenticationProvider implements IAuthenticationProvider {...@Injectable({
providedIn: "root"
})
export class AuthenticationService {
constructor( @Inject(AuthenticationProvider)
private authenticationProvider: IAuthenticationProvider,
private http: HttpClient
) {}
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Użyłem czegoś takiego jak poniżej, aby rozwiązać ten problem

app.module.ts

providers: [
{ provide: AlmostInterface, useClass: environment.concrete }
...
]


AlmostInterface.ts

export abstract class AlmostInterface {
abstract myMethod();
}


MyConcrete.ts

export class MyConcrete implements AlmostInterface {
myMethod() { ... };// implementation
}export class MyConcreteAlternative implements AlmostInterface {
myMethod() { ... };// implementation
}


environment.ts

export const environment = {
production: false,
concrete: MyConcreteAlternative
};


environment.prod.ts

export const environment = {
production: true,
concrete: MyConcrete
};
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Myślę, że nie można używać interfejsów maszynopisu do wstrzykiwania zależności, ponieważ

interfejsy maszynopisu nie istnieją

w czasie wykonywania (tylko bezpieczeństwo typu w czasie kompilacji).

Sugerowałbym użycie do tego

Klasa abstrakcyjna

.
EDIT:
Wygląda na to, że możesz użyć
useClass
w

pierwszy

parametr @Injectable, a nie w drugim, jak w przykładzie. Połączenie tego z odpowiedzią @ k0zakinio daje:
@Injectable({
providedIn: 'root',
useClass: environment.concrete,
deps: []
})
export abstract class SessionStorage { }

Wygląda również na to, że musisz zadeklarować swoje zależności przez
deps
lub
inject
, sprawdź to

problem
https://github.com/angular/angular/issues/23592
github. Mam nadzieję, że tym razem moja odpowiedź pomoże bardziej.
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Możesz użyć czegoś takiego jak -
[{ provide: InterfaceName, useClass: ClassName}]

Aby odpowiedzieć na pytania, Zaloguj się lub Zarejestruj się