Recently I had opportunities to present to the Nashville Salesforce Developers Group and Richmond Salesforce Developers Group on how to adopt the dependency injection design pattern with the force-di library, an open source project that I’m developing in collaboration with Andy Fawcett and John Daniel.
In this webinar, I explain what the dependency injection design pattern is and the kinds of problems it solves. I walk through refactoring a set of tightly coupled Apex classes and also explore how to address declarative dependencies, such as object action overrides and custom buttons. I show how you can use the force-di library to dynamically swap out their behavior too with Lightning or Visualforce components, or even Flows.
Applying the dependency injection design pattern with force-di library has profound implications for how the programmatic and declarative customizations in an org can be developed and released as separate, modular unlocked packages.
I hope you find my presentation informative and thought provoking on how you can begin architecting your applications for reuse and changing requirements.
Bravo Doug! I LOVED The Jenga reference
LikeLiked by 1 person
Awesome, thanks Sara! =)
LikeLike
So if custom metadata type doesn’t exist for an apex binding, all modules are instantiated and then searched for any bindings of that class? For example, if there is no custom metadata type binding for WelcomeMessage:
public class ChatApp {
}
public class ChatAppConfiguration extends di_Module {
}
If the DI framework searches for the ChatAppConfiguration module to see if WelcomeMessage.class is used, what if WelcomeMessage.class is used by other modules?
LikeLiked by 1 person
Hi John,
There are two ways to express the bindings (bind X to Y). One is explicitly in the CMDT record itself, that’s a very straight forward to do it. The other is programmatically by creating an Apex class that extends
di_Module
then create a CMDT record of Type “Module” that points to that Apex class.At runtime, when
di_Injector.Org.getInstance( bindingName )
is called, then all bindings from the CMDT and any Modules are added to one big pool of bindings and the bindings that match the binding name is returned.As of this comment, the
di_Injector.Org.getInstance( bindingName )
is returning the first result, so the behavior is undefined if you have multiple bindings by the same name (e.g. multiplebind(name).to(something)
. This will be changing such that all attempts to get a binding instance will return a list of matches, which is the behavior of the TriggerInjector for injecting and ordering the sequence in which trigger handlers are executed.LikeLike