Вот мой взгляд на это и возможное решение проблемы с отсутствующим поставщиком.
В моем случае у нас есть охранник, который принимает разрешение или список разрешений в качестве параметра, но это то же самое, что имеет роль.
У нас есть класс для работы с охранниками авторизации с разрешения или без разрешения:
@Injectable()
export class AuthGuardService implements CanActivate {
checkUserLoggedIn() { ... }
Это касается проверки активного сеанса пользователя и т. Д.
Он также содержит метод, используемый для получения настраиваемой защиты разрешений, которая фактически зависит от AuthGuardService
самого
static forPermissions(permissions: string | string[]) {
@Injectable()
class AuthGuardServiceWithPermissions {
constructor(private authGuardService: AuthGuardService) { } // uses the parent class instance actually, but could in theory take any other deps
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
// checks typical activation (auth) + custom permissions
return this.authGuardService.canActivate(route, state) && this.checkPermissions();
}
checkPermissions() {
const user = ... // get the current user
// checks the given permissions with the current user
return user.hasPermissions(permissions);
}
}
AuthGuardService.guards.push(AuthGuardServiceWithPermissions);
return AuthGuardServiceWithPermissions;
}
Это позволяет нам использовать метод для регистрации некоторых настраиваемых охранников на основе параметра разрешений в нашем модуле маршрутизации:
....
{ path: 'something',
component: SomeComponent,
canActivate: [ AuthGuardService.forPermissions('permission1', 'permission2') ] },
Интересная часть forPermission
заключается AuthGuardService.guards.push
в том, что это в основном гарантирует, что каждый раз, когда forPermissions
вызывается для получения настраиваемого класса защиты, он также сохраняет его в этом массиве. Это также статично для основного класса:
public static guards = [ ];
Затем мы можем использовать этот массив для регистрации всех охранников - это нормально, если мы убедимся, что к тому времени, когда модуль приложения зарегистрирует этих поставщиков, маршруты были определены и все классы защиты были созданы (например, проверьте порядок импорта и держите этих провайдеров как можно ниже в списке - помогает наличие модуля маршрутизации):
providers: [
// ...
AuthGuardService,
...AuthGuardService.guards,
]
Надеюсь это поможет.