2016-12-17 2 views
1

Я пытаюсь подключить DI к угловому2. У меня в основном есть все мои сервисы, которые я ожидаю, чтобы синглеты в массиве поставщиков в моем приложении.module.ts.Угловая 2 Идентификация зависимостей Singleton/new экземпляры

providers: [ 
    { provide: ErrorHandler, useClass: IonicErrorHandler }, 
    { provide: 'ICommentService', useClass: CommentService }, 
    { provide: 'IPostService', useClass: PostService }, 
    { provide: 'IQueryParamsService', useClass: QueryParamsService }, 
    { provide: 'IUserService', useClass: UserService }, 
    { provide: 'IInjectorService', useClass: InjectorService}, 
    { provide: 'IPostFactory', useClass: PostFactory} 
] 

Я также хочу иметь ReflectiveInjector, который будет отвечать за создание экземпляров объектов, в которых я нуждаюсь. Я создал это так:

this.injector = ReflectiveInjector.resolveAndCreate([ 
    { provide: 'IComment', useClass: Comment }, 
    { provide: 'ICommentList', useClass: CommentList }, 
    { provide: 'IPic', useClass: Pic }, 
    { provide: 'IPost', useClass: Post }, 
    { provide: 'IUser', useClass: User }    
]); 

Моя проблема заключается в том, что, например, сообщение требует PostService и когда я задаю этот инжектор на пост ошибки его, потому что он не может найти PostService, что имеет смысл, потому что это отдельный инжекторные деревья.

Я спрашиваю инжектор, как это:

this.injector.get('IPost'); 

Это часть моего класса Поста:

@Injectable() 
export class Post extends DBObject implements IPost{ 
    private title: string; 
    private body:string; 
    //private comments:ICommentList; 
    //private img:IPic; 
    //private author:IUser; 
    private authorId: number; 
    private date:Date; 

    constructor(
     @Inject('IPostService') private PostService:IPostService, 
     @Inject('IUserService') private UserService:IUserService, 
     @Inject('IUser') private author:IUser, 
     @Inject('IPic') private img: IPic, 
     @Inject('ICommentList') private comments:ICommentList 
    ){ 
     super(); 
    } 

Я опустил несущественные функции. Я ожидаю, что IPostService, IUserService будет объявлен в модуле singleton, но IUser, IPic и ICommentList должны быть новыми экземплярами каждый раз.

Ошибка:

Error in ./TabsPage class TabsPage - caused by: No provider for IPostService! (IPost -> IPostService) 

Как я могу это сделать?

Спасибо!

PS: Это угловатая проблема, но я использую ионный, если это имеет значение.

ответ

2

Вы, вероятно, хотите

constructor(injector:Injector) { 
    resolvedProviders = ReflectiveInjector.resolve([ 
    { provide: 'IComment', useClass: Comment }, 
    { provide: 'ICommentList', useClass: CommentList }, 
    { provide: 'IPic', useClass: Pic }, 
    { provide: 'IPost', useClass: Post }, 
    { provide: 'IUser', useClass: User }    
    ]); 
    let this.injector = ReflectiveInjector.fromResolvedProviders(resolvedProviders, injector); 

несколько вызовов

this.injector.get('IPost'); 

получит вам тот же Post экземпляр, хотя.

Angular2 DI поддерживает один экземпляр для провайдера. Если вы хотите получить другой экземпляр для каждого вызова, вы можете предоставить фабрику, получить эту фабрику от DI и вызвать фабрику, чтобы получить новый экземпляр. Если вам нужна дополнительная информация об этом подходе, оставьте комментарий.

Смотрите также

+0

Этот подход хорошо выглядит. Поэтому я могу использовать useClass для сервисов и useFactory для объектов, которые я хочу создать. Откуда возникает инжектор в конструкторе? – yafrack

+0

Да, используйте 'useClass', чтобы позволить Angulars DI создать экземпляр для вас. 'useFactory' сам по себе не создает новые экземпляры, он просто позволяет настроить, как DI должен создать один экземпляр. Чтобы получить несколько экземпляров, вам нужно ввести функцию, которая при вызове создает новый экземпляр, а затем вы вызываете его один раз для каждого нового экземпляра, который вам нужен. –

+0

Да, я имею то же самое, что и в ссылке, которую вы передаете (возвратите новый Object()) на фабриках, и это должно быть сделано. Я сделал это в инжекторной службе, поэтому могу делать что-то вроде InjectorService.getInjector(). Get («IPost»). Эта услуга находится в app.module.ts (в главном посте). Я не уверен, откуда идет инжектор в вашем конструкторе или как его передать. – yafrack

Смежные вопросы