I would like to implement Strategy pattern in Angular/Typescript and use a service in component; service takes a strategy interface as constructor parameter. Also, constraint is that service is dependent on some other injected service at angular level.
I'm digging through the docs but unable to find a way to do it. I would like not to end up in over-engineered code, searching for simple solution to have a Strategy pattern implemented.
Please see below in mocked-up code:
export interface IStrategy {
calculate(a,b): number;
}
export class MinusStrategy implements IStrategy {
calculate(a,b): number {
return a - b;
}
}
export class PlusStrategy implements IStrategy {
calculate(a,b): number {
return a + b;
}
}
@Injectable()
export class CalculatorService {
// I understand it is not possible to have DI of the Interface here for calcStrategy
constructor(private http: HttpClient; private calcStrategy: IStrategy);
getByCalc() {
this.http.get('someurl?calc=' + calcStrategy.calculate(1,1));
}
}
@Component(// skipped config here...)
export class MyComponent implements OnInit {
// How to inject appropriate concrete strategy (and either autowire or provide httpClient?)
constructor(private service: new CalculatorService(httpClient, new MinusStrategy()));
useInComponent() {
this.service.getByCalc();
}
}
My two cents - You cannot rely on DI to provide concrete instance in such case. DI has no way to know which type of instance is needed in each context.
I'd suggest using factory pattern here. For example -
@Injectable()
export class StrategyFactory {
createStrategy<T extends IStrategy>(c: new () => T): T {
return new c();
}
}
//then you can inject StrategyFactory in your service class, use it like -
factory.createStrategy(MinusStrategy).calculate(2, 1);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With