Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular: Injecting classes without @Injectable decorator

Tags:

angular

I have some classes that come from a library, e..g.:

class Foo {
   // ...
}
class Bar {
   constructor(private foo: Foo) { }
   // ...
}

These classes don't have the @Injectable decorator because the library isn't Angular-specific. However, I want to use them in my app as services.

My solution so far has been to create derived classes, e.g.:

@Injectable()
class InjectableFoo extend Foo {
  constructor() { super(); }
}
@Injectable()
class InjectableBar extends Bar {
  constructor(foo: InjectableFoo) {
    super(foo);
  }
}

I'm not very thrilled with this solution, because it requires extra boiler-plate code that adds no real value, and the person consuming these services in a component has to know to use the "Injectable" versions instead of the (simpler) base classes. In a perfect world I'd like to be able to tell Angular that Foo and Bar should be injectable.

Is this possible?

like image 968
fr0 Avatar asked Dec 02 '25 10:12

fr0


1 Answers

You can provide them in the NgModule using a factory provider, and a value provider.

https://angular.io/api/core/FactoryProvider

https://angular.io/api/core/ValueProvider

class Foo {
   // ...
}
class Bar {
   constructor(private foo: Foo) { }
   // ...
}

@NgModule({
   providers: [
      {provide: Foo, useValue: new Foo()},
      {provide: Bar, useFactory: (foo) => new Bar(foo), deps: [Foo]}
   ]
});

In the above example you can use useValue: new Foo(), but the key here is that the deps: [Foo] allows you to inject foo into the factory function for Bar since it is a dependency.

Later in the components you can just do the following.

@Component({...})
export class MyComponent {
    constructor(foo: Foo, bar: Bar) { }
}
like image 84
Reactgular Avatar answered Dec 05 '25 01:12

Reactgular



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!