Subclass Registration

Class registration is a pivotal concept in MemberJunction’s software architecture, particularly when it comes to overriding functionality through subclassing. Subclassing allows the derivation of new objects from a base object, separating concerns and enabling customized functionality for different entities.

Understanding Subclassing

  • Base Class Functionality: Subclassing is used to create specialized versions of a base class, such as the BaseEntity. This allows for the separation of general functionalities in the base class from specific business logic in subclasses.
  • Mandatory and Optional Subclasses: Depending on the design, subclasses can be either mandatory, as in the case of an abstract base class, or optional when the base class is fully implemented and non-abstract./

Integrating Subclasses with MemberJunction Architecture

The key question is how to integrate these subclasses so that they are utilized effectively within the MemberJunction architecture. This applies to BaseEntity subclasses and extends to other areas, such as selecting the appropriate UI component in the MemberJunction Explorer.

The Role of Registry in Class Integration

  • Global Library: MemberJunction employs a registry maintained by a library called Global, accessible at @memberjunction/global. This library is central to most MemberJunction libraries and plays a crucial role in class registration.
  • Registration Mechanism: The Global library provides a centralized location for classes to register themselves. This ensures that when a particular class is needed, it can be requested from this central registry.

Code Examples: The @RegisterClass Decorator

  • Usage of Decorator: The @RegisterClass decorator is a powerful tool in TypeScript class definition. It allows for specifying the base class being extended and a key for identification, such as ‘persons’ for a Person entity subclass.
  • Priority Specification: The decorator also enables the specification of a priority, determining which class takes precedence when multiple options are available.

Context-Dependent Execution and Library Management

  • Execution Context Independence: Typically, code in MemberJunction is written to be execution context-independent, meaning it should function across the architecture, whether on a server, browser, or other locations.
  • Conditional Logic and Library Customization: For business logic meant to execute only in specific locations, such as API-exclusive logic, conditional checks or separate class libraries can be used. For instance, a ‘server-side subclasses’ library might contain functionality intended only for server-side execution and use the Metadata.ProviderType property to determine if the server-side code should be executed or not.

Advanced Class Hierarchy and Registration

  • Hierarchy Example: Consider a class hierarchy starting with a base class Person, leading to a generated subclass PersonEntity, followed by a custom UniversalPersonEntity for universal logic, and a ServerPersonEntity for server-specific logic. This approach would be more elegant than the idea of using the Metadata.ProviderType property to conditionally include the execution of server-only code and also simplify the dependencies included in the library so that server-side libraries aren’t bundled into a codebase that will execute client-side.
  • Library Utilization: These specialized classes can be packaged into different libraries, like server-side-subclasses, and included only in the relevant execution environment.

The Power of RegisterClass and Metadata Object

  • Automated Handling: The @RegisterClass decorator simplifies the process, automatically managing the priority and integration of classes within the MemberJunction architecture.
  • Utilization in BaseEntity Objects: For creating instances derived from BaseEntity, the Metadata object’s GetEntityObject function leverages the class registration details in @memberjunction/global, ensuring a seamless and abstracted creation process.

Conclusion: Benefits of This Approach

Class Registration provides a high degree of abstraction, separation of concerns, and encapsulation. By effectively managing class registration and subclass integration, MemberJunction ensures that its software architecture remains flexible, robust, and adaptable to various needs.