Here's my use case:
I have an interface with 4 different implementations WorkflowA
, WorkflowB
, WorkflowC
and WorkflowD
.
export interface IWorkflow {
getQuestions();
validateQuestions();
getWorkflowSteps();
}
I have a WorkflowManager
class that returns the appropriate workflow based on an input variable (Factory pattern?)
export class WorkflowManager {
workflow:IWorkflow;
getWorkflow(workflow){
switch (workflow) {
case 'workflowA':
return new workflowA();
case 'workflowB':
return new workflowB();
case 'workflowC':
return new workflowC();
case 'workflowD':
return new workflowD();
default:
throw new Error(`Unrecognized workflow: ${workflow}`);
}
}
}
I also have a component WorkflowComponent
that gets loaded
Example:
/workflow=WorkflowA
loads WorkflowComponent
. The component then extracts the routeparam workflow
and based on the value, it then passes it to the WorkflowManager
which returns the appropriate workflow.
Here's a snippet of my component
@Component({
...
})
export class Workflow implements OnInit {
workflowInstance: IWorkflow;
constructor(
private route: ActivatedRoute,
private workflowManager: WorkflowManager,
) {
}
ngOnInit() {
this.route.params.subscribe(params => {
let regType: string = params['workflow'];
this.workflowInstance = this.workflowManager.getWorkflow(workflow);
});
}
}
But I don't like the idea of manually instantiating Workflow*
classes. How can I improve this so I wire it using Angular2 supplied API so that it can be managed/injected in to other components?
Also in my current implementation, I will have to make ajax calls outside of Angular framework which I don't think is the best thing to do.
Any ideas on how to take advantage of the Angular framework and improve this?
One way is to inject an injector and acquire the workflow instance imperatively like:
@Injectable()
export class WorkflowManager {
constructor(private injector:Injector) {}
workflow:IWorkflow;
getWorkflow(workflow){
switch (workflow) {
case 'workflowA':
return this.injector.get(workflowA);
case 'workflowB':
return this.injector.get(workflowB);
case 'workflowC':
return this.injector.get(workflowC);
case 'workflowD':
return this.injector.get(workflowD);
default:
throw new Error(`Unrecognized workflow: ${workflow}`);
}
}
}
Alternatively you can inject workflowA
, workflowB
, workflowC
, workflowA
and just return the right one depending on the workflow
but I think using the injector is a better fit for this use case.
Ensure you provide workflowA
, workflowB
, workflowC
.