Dependency injection is used to make a class independent of its dependencies or to create a loosely coupled program. It is useful for improving the reusability of code. Creating a multi step in LWC with dependency injection using custom metadata involves designing a component where each step can be configured through metadata, results in more flexible and dynamic multi step process.
Business Usecase : Creating an application using multi step architecture in LWC using metadata powered
We’ll build a multi step application where each step’s configuration—such as component name and order—is defined through custom metadata. This approach allows us to easily update the application steps without editing the underlying code, providing flexibility and ease of maintenance.
Code: multi step in LWC
- Custom meta data object named Dynamic LWC Configurations and api name Dynamic_LWC_Configuration__mdt
- Also create two custom field: Component_Name__c and Order__c as shown in below image

- Create Apex class with name LWCConfigurationService. LWCConfigurationService class fetch the meta data and provide it to the LWC to display on UI.
LWCConfigurationService.cls
public with sharing class LWCConfigurationService {
@AuraEnabled(cacheable=true)
public static List<Map<String, Object>> getConfigurations() {
List<Map<String, Object>> configList = new List<Map<String, Object>>();
for (Dynamic_LWC_Configuration__mdt config : [SELECT MasterLabel, Order__c, Component_Name__c
FROM Dynamic_LWC_Configuration__mdt
ORDER BY Order__c ASC])
{
Map<String, Object> step = new Map<String, Object>{
'label' => config.MasterLabel,
'order' => config.Order__c,
'componentName' => config.Component_Name__c
};
configList.add(step);
}
return configList;
}
}- We will create these LWC in Salesforce:
- loadAnyLwc : This component is dynamic and loads any component by dynmaically creating it in runtime. loadAnyLwc expect you to pass component name as attribute.
- multiPageLwc : This component makes an apex call to get the custom metadata object records and display the components by using loadAnyLwc LWC. It also has next and back button which display the component in order configured in metadata.
loadAnyLwc.html
lwc:component : To instantiate a component dynamically, use the <lwc:component> managed element with the lwc:is directive in a component’s HTML file. To instantiate a component dynamically, use the <lwc:component> managed element with the lwc:is directive in a component’s HTML file.
<template>
<div class="">
<lwc:component lwc:is={componentConstructor}></lwc:component>
</div>
</template>loadAnyLwc.js
Value change handler allows to trigger the load of the new component based on component name change. To understand more on it read this: value change handler in lwc
import { LightningElement, api } from 'lwc';
export default class LoadAnyLwc extends LightningElement {
componentConstructor;
lwcName;
@api get componentName() {
return this.lwcName;
}
set componentName(value) {
this.setAttribute('lwcName', value);
this.lwcName = value;
this.handleComponentNameChange();
}
handleComponentNameChange() {
if (this.lwcName) {
import(`c/${this.lwcName}`)
.then(({ default: ctor }) => this.componentConstructor = ctor)
.catch(err => console.log('Error importing component',err));
}
}
}loadAnyLwc.js-meta.xml
To instantiate a dynamic component, a component’s configuration file must include the lightning__dynamicComponent capability.
<?xml version="1.0"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>61.0</apiVersion>
<isExposed>true</isExposed>
<capabilities>
<capability>lightning__dynamicComponent</capability>
</capabilities>
</LightningComponentBundle>multiPageLwc.html
loadAnyLwc component is called in html file along with back and next button. currentPage attirbute are being calculated in js file and passed to the loadAnyLwc component.
<template>
<template if:true={currentPage}>
<c-load-any-lwc component-name={currentPage.componentName}></c-load-any-lwc>
</template>
<lightning-button label="Previous" onclick={handlePrevious}></lightning-button>
<lightning-button label="Next" onclick={handleNext} ></lightning-button>
</template>multiPageLwc.js
getConfigurations method from LWCConfigurationService class is called using wire service.
import { LightningElement, track, wire } from 'lwc';
import getConfigurations from '@salesforce/apex/LWCConfigurationService.getConfigurations';
export default class MultiPageLwc extends LightningElement {
@track pages = [];
@track currentPageIndex = 0;
@wire(getConfigurations)
wiredConfigs({ error, data }) {
if (data) {
this.pages = data;
this.currentPageIndex = 0;
} else if (error) {
console.error(error);
}
}
get currentPage() {
return this.pages[this.currentPageIndex];
}
handlePrevious() {
if (this.currentPageIndex > 0) {
this.currentPageIndex--;
}
}
handleNext() {
if (this.currentPageIndex < (this.pages.length - 1)) {
this.currentPageIndex++;
}
}
}multiPageLwc.js-meta.xml
The component is exposed to use with LIghtning App Builder. You can place the component on home page, record page or app page.
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>61.0</apiVersion>
<isExposed>true</isExposed>
<targets>
<target>lightning__AppPage</target>
<target>lightning__RecordPage</target>
<target>lightning__HomePage</target>
</targets>
</LightningComponentBundle>Demo – Creating an application using multi-step architecture in LWC using metadata powered Depedency Injection
For testing the component, First thing we need to make sure is create metadata records. For example i have setup as shown in image below. You need to make sure component exist in your org before using them here.

Now place your component in lightning page and test:
Do you need help?
Are you stuck while working on this requirement? Do you want to get review of your solution? Now, you can book dedicated 1:1 with me on Lightning Web Component completely free.
GET IN TOUCH
Schedule a 1:1 Meeting with me
Also checkout this https://salesforcediaries.com/category/lightning-web-component
