I am trying to wire up DI on angular2. I basically have all my services which I expect to be singletons in the providers array in my app.module.ts.
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}
]
I also want to have a ReflectiveInjector that will be in charge of creating instances of objects I need. I created it like this:
this.injector = ReflectiveInjector.resolveAndCreate([
{ provide: 'IComment', useClass: Comment },
{ provide: 'ICommentList', useClass: CommentList },
{ provide: 'IPic', useClass: Pic },
{ provide: 'IPost', useClass: Post },
{ provide: 'IUser', useClass: User }
]);
My issue is that for example Post requires a PostService and when I ask this injector for a Post it errors out because it can't find the PostService, which makes sense because it's separate injector trees.
I ask the injector like this:
this.injector.get('IPost');
This is part of my Post class:
@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();
}
I omitted irrelevant functions. I expect IPostService, IUserService to be the singleton declared in the module but IUser, IPic and ICommentList should be new instances every time.
The error is:
Error in ./TabsPage class TabsPage - caused by: No provider for IPostService! (IPost -> IPostService)
How can I accomplish this?
Thanks!
PS: This is an angular problem but I'm using Ionic in case it matters.
You probably want
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);
Multiple calls to
this.injector.get('IPost');
will get you the same Post
instance though.
Angular2 DI maintains a single instance per provider. If you want to get a different instance for each call, you can provide a factory, get this factory from DI and call the factory to get a new instance. If you need more details on this approach leave a comment.
See also