Aspects can depend on other Aspect and obtain access the declared Aspect API. To use Aspects as dependencies, compose the Aspect reference to the static dependencies property and annotate the type on the provider first argument.
import { SymphonyPlatformAspect, type SymphonyPlatformBrowser } from '@bitdev/symphony.symphony-platform'; export class PeopleBrowser { // declare the requested aspect dependencies. static dependencies = [SymphonyPlatformAspect]; // accept an array of all requested dependencies in your runtime. static async provider([symphonyPlatform]: [SymphonyPlatformBrowser]) { console.log(symphonyPlatform); // echos the wayne platform runtime API return new PeopleBrowser(); } }
An Aspect can only depend on the same runtime on the requested Aspect. If there is implementation for the Aspect in the same runtime, the dependency would be undefined
.
Registering to Aspect slots is best upon construction of the platform. Use the provider execution to plugin to slots of your dependencies:
import { SymphonyPlatformAspect, type SymphonyPlatformBrowser } from '@bitdev/symphony.symphony-platform'; export class PeopleBrowser { static dependencies = [SymphonyPlatformAspect]; static async provider([symphonyPlatform]: [SymphonyPlatformBrowser]) { symphonyPlatform.registerRoute([ { path: 'user-profile', component: () => { return <div>hello there!</div>; } } ]); return new PeopleBrowser(); } }
Registering into slots in different phases of the platform runtime is possible but consider the slot value might before the register occurs.
Pass the Aspect to your constructor to use it your Aspect APIs:
import { PeopleAspect, type PeopleNode } from '@pied/people.people'; export class OrganizationNode { constructor( private people: PeopleNode ) {} async listOrgMembers(orgName: string) { const org = await this.getOrg(orgName); const members = org.listMembers(); const people = await this.people.listUsers(members); // use the people aspect to compose new APIs. return people; } static dependencies = [PeopleAspect]; // declare the required dependencies. static async provider([people]: [PeopleNode]) { return new OrganizationNode(people); // pass the aspect to the constructor to use it from your APIs. } }
Avoid passing Aspect runtimes as props to inner dependencies and rather keep Aspects using components and not vice versa.
If Aspects are not composed in the Harmony platform they might be missing even if declaring them. Annotate you are allowing for an optional dependency using |undefined
an keep your aspect implementation aware to the case.
import { SymphonyPlatformAspect, type SymphonyPlatformBrowser } from '@bitdev/symphony.symphony-platform'; export class PeopleBrowser { // declare the requested aspect dependencies. static dependencies = [SymphonyPlatformAspect]; // accept an array of all requested dependencies in your runtime. static async provider([waynePlatform]: [SymphonyPlatformBrowser|undefined]) { console.log(waynePlatform); // echos the wayne platform runtime API return new PeopleBrowser(); } }
Cyclic dependencies are not allowed to use between Aspects. We recommend to avoid cyclic dependencies of all components, learn more on avoiding cyclic dependencies.