dependency injection for interfaces

Issue

I have a component which contains a generic popup, it implements therefore the interface PopupParent

@Injectable()
@Component(
    //...
)
class SubjectListComponent implements OnInit, PopupParent {
}

The generic class InfoPopup needs to deal abstractly with its parent (that implements PopupParent), so I would like to take get the parent injected by its interface (instead of being injected by its concrete class SubjectListComponent)

class InfoPopup {
  final PopupParent _parent;

  InfoPopup(this._parent);
  //...non relevant code
}

The issue is that the SubjectListComponent was registred by class in the injector, so the injector won’t find what to inject into the InfoPopup class.

If I try to declare my SubjectListComponent manually, I found that it has to be done in the providers constants. but I still don’t have my instance of SubjectListComponent when I declare my component…

How could I do that?

I also tried to pass the parent to an @Input:

@Component(
    selector: 'info-popup',
    templateUrl: 'info_popup.html',
    styleUrls: const ['info_popup.css'],
)
class InfoPopup {
  @Input()
  final PopupParent parent;

  InfoPopup(this._parent);
  //...non relevant code
}

But then I got stuck on how to inject the this instance from the component client :

subject_list_comp.html:

<div>
  <info-popup [parent]="this"></info-popup>
</div>

since dart angular doesn’t recognize this as a keyword, but it searches for a property called this in SubjectListComponent.dart

Two issues were created for this question:
https://github.com/dart-lang/site-webdev/issues/514
https://github.com/dart-lang/site-webdev/issues/515

Solution

This can be accomplished by providing aliases. multi: true allows to add more than one alias. There is no way to make automatically derive the interfaces.

@Component(
  providers: [
      const Provider(PopupParent, useExisting: SubjectListComponent, multi: true),
      const Provider(PopupParent, useExisting: FooComponent, multi: true)

  ]
)
class InfoPoupup ...

update

To make

[parent]="this" 

work, you could add a getter to the component

get self => this; 

and then use

[parent]="self"

Answered By – Günter Zöchbauer

Answer Checked By – Pedro (FlutterFixes Volunteer)

Leave a Reply

Your email address will not be published.