Let's say I've extended the CRM FormContext by creating a new TS class that wraps it, and adds helper functions. This new ExtendedContext has functions like getDisplayValue(attName) which gets the attribute, handles it not being on the form, determines the attribute type, and appropriately returns what the "displayed value" is. As I add more helper functions, the class get's bigger and bigger, which means I need to start splitting the class into more classes, but I don't want the API to change. The consuming code should not have to know that it needs to create a DisplayExtendedContext class to call getDisplayValue, all functions should exist on the main extended context. What's the recommended approach?
My current approach feels wrong and looks like this:
// extendedContex.ts
import { DisplayContext } from "../context/display";
export class ExtendedContext implements XrmExt.ExtendedContext {
public context: Xrm.FormContext // Actual Xrm.Client form context
private display: DisplayContext;
constructor(context: Xrm.FormContext){
this.context = context;
this.display = new DisplayContext(this);
}
public getDisplayValue(att: string): string {
return display.getDisplayValue(att);
}
}
// xrmExt.d.ts
declare namespace XrmExt {
interface ExtendedContext {
getDisplayValue(att: string): string;
}
}
// ../context/display.ts
export class DisplayContext {
private context: XrmExt.ExtendedContext;
constructor(context: XrmExt.ExtendedContext){
this.context = context;
}
public getDisplayValue(att: string): string {
// Do logic here, with full access to the ExtendedContext
}
}
Here are the issues it has:
- I have to duplicate the pass throughs for
ExtendedContextfunctions. So every function I add, I have to implement it in the smaller context class, and then add it as a pass through in theExtendedContextclass and to theExtendedContextinterface. I'm lazy, I don't want to have to do that for every function. - This one is more minor, but the
ExtendedContextthat is passed to theDisplayContextis not fully initialized, which could lead to null ref errors. For example, ifDisplayContextwere to call a function on theXrmExt.ExtendedContextinterface in it's constructor that it itself implements, the class level "display" field of theExtendedContextclass will not be populated, and a null ref exception would be thrown. An "unspoken" rule of never access theExendedContextfrom the constructor of one of the smaller classes would prevent this from ever being an issue. I'm guessing Mixings might be the way forward here, but I'm just not sure. Thoughts / Suggestions?