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
ExtendedContext
functions. So every function I add, I have to implement it in the smaller context class, and then add it as a pass through in theExtendedContext
class and to theExtendedContext
interface. I'm lazy, I don't want to have to do that for every function. - This one is more minor, but the
ExtendedContext
that is passed to theDisplayContext
is not fully initialized, which could lead to null ref errors. For example, ifDisplayContext
were to call a function on theXrmExt.ExtendedContext
interface in it's constructor that it itself implements, the class level "display" field of theExtendedContext
class will not be populated, and a null ref exception would be thrown. An "unspoken" rule of never access theExendedContext
from 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?