Recursive injection

As a final test of our DI framework, let's now inject the MailServiceDi class into another class. This means that our new class will be dependent on the IMailServiceDi interface, which is itself dependent on the ISystemSettings interface. This is an example of a recursive dependency tree.

We start by defining an interface for the MailServiceDi class itself, as follows:

export interface IMailServiceDi { 
    sendMail(to: string, subject: string, content: string) 
    : Promise<void>; 
} 
 
export class IIMailServiceDi { } 

Here, we have taken the definition of the sendMail function, which returns a Promise, and created an interface named IMailServiceDi. We have also created the class that will be used as a type lookup by our DI framework, named IIMailServiceDi.

With these interfaces in place, we can create a class that is dependent on the IMailServiceDi interface, as follows:

import { IMailServiceDi, IIMailServiceDi } from "./MailServiceDi"; 
import { ConstructorInject } from "./Decorators"; 
 
@ConstructorInject 
export class MailSender { 
    private mailService: IMailServiceDi | undefined; 
 
    constructor(mailService?: IIMailServiceDi) { } 
 
    async sendWelcomeMail(to: string) { 
        if (this.mailService) { 
            let response = await this.mailService 
           .sendMail(to, "Welcome", "Welcome from MailSender"); 
            console.log(`MailSender.sendMail returned : 
              ${response}`); 
        } 
    } 
} 

Here, we have created a class named MailSender, and used the ConstructorInject decorator to decorate the class. Our class has a private property named mailService, which is of type IMailServiceDi. This is the property that will be created by our DI framework. The constructor function simply uses the IIMailService class to indicate that the private mailService property should be injected. The MailSender class has a sendWelcomeMail function that uses an async await pattern to call the MailServiceDi sendMail function.

To test this class, we need to register the MailServiceDi class with our DI framework, and then create a new instance of the MailSender class, and call the sendWelcomeMail function as follows:

let mailServiceDi = new MailServiceDi(); 
ServiceLocatorGeneric.register(IIMailServiceDi, mailServiceDi); 
 
let mailSender = new MailSender(); 
mailSender.sendWelcomeMail("[email protected]"); 

The output of this code is as follows:

ServiceLocator resolving : IIMailServiceDi
ServiceLocator resolving : IISystemSettings
Message Sent 250
MailSender.sendMail returned : Message Sent : 250  

Here, we can see that the DI framework is calling the ServiceLocator class to resolve IIMailServiceDi. This is during the constructor of the MailSender class. As the MailServiceDi class is dependent on the ISystemSettings interface, a second call is made to resolve IISystemSettings.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.221.85.33