The proxy facade is an eager-injectable abstraction used to bridge the gap between eager code and lazy-loaded feature modules. It allows components to inject(ActiveCartFacade) immediately, even though the actual implementation resides in a separate lazy chunk.
How it works
- The Abstract Facade: An abstract class (e.g.,
ActiveCartFacade) is declared in an eager @spartacus/<feature>/root module. This provides the stable contract for consumers. - The Proxy Provider: A
useFactory provider is registered in the root module using facadeFactory. This factory returns a stub object that:- Triggers the lazy chunk for the specified
feature if not yet loaded. - Once loaded, retrieves the real implementation from the lazy injector.
- Forwards method calls to the real instance.
Critical Constraint: Async Only
Because the proxy must wait for lazy chunks to load, proxy facades must only expose methods that return Observables. They must never expose synchronous methods or plain value properties, as a synchronous getter cannot wait for the chunk to load.
// Example of the two pieces
// 1. The abstract Facade class (Eager)
export abstract class ActiveCartFacade {
abstract getActive(): Observable<Cart>;
abstract getEntries(): Observable<OrderEntry[]>;
abstract addEntry(productCode: string, quantity: number): void;
abstract removeEntry(entry: OrderEntry): void;
}
// 2. The proxy useFactory provider (Eager)
@Injectable({
providedIn: 'root',
useFactory: () =>
facadeFactory({
facade: ActiveCartFacade,
feature: CART_BASE_CORE_FEATURE,
methods: ['getActive', 'getEntries', 'addEntry', 'removeEntry'],
}),
})
export abstract class ActiveCartFacade { /* ... */ }