refactor(ivy): generate ngFactoryDef for injectables (#32433)
With #31953 we moved the factories for components, directives and pipes into a new field called `ngFactoryDef`, however I decided not to do it for injectables, because they needed some extra logic. These changes set up the `ngFactoryDef` for injectables as well. For reference, the extra logic mentioned above is that for injectables we have two code paths: 1. For injectables that don't configure how they should be instantiated, we create a `factory` that proxies to `ngFactoryDef`: ``` // Source @Injectable() class Service {} // Output class Service { static ngInjectableDef = defineInjectable({ factory: () => Service.ngFactoryFn(), }); static ngFactoryFn: (t) => new (t || Service)(); } ``` 2. For injectables that do configure how they're created, we keep the `ngFactoryDef` and generate the factory based on the metadata: ``` // Source @Injectable({ useValue: DEFAULT_IMPL, }) class Service {} // Output export class Service { static ngInjectableDef = defineInjectable({ factory: () => DEFAULT_IMPL, }); static ngFactoryFn: (t) => new (t || Service)(); } ``` PR Close #32433
This commit is contained in:
@ -86,7 +86,8 @@ export interface R3FactoryDefMetadata {
|
||||
name: string;
|
||||
type: o.Expression;
|
||||
typeArgumentCount: number;
|
||||
deps: R3DependencyMetadata[]|null;
|
||||
deps: R3DependencyMetadata[]|'invalid'|null;
|
||||
injectFn: o.ExternalReference;
|
||||
isPipe?: boolean;
|
||||
}
|
||||
|
||||
@ -267,8 +268,7 @@ export function compileFactoryFromMetadata(meta: R3FactoryDefMetadata): R3Factor
|
||||
type: meta.type,
|
||||
deps: meta.deps,
|
||||
typeArgumentCount: meta.typeArgumentCount,
|
||||
// TODO(crisbeto): this should be refactored once we start using it for injectables.
|
||||
injectFn: R3.directiveInject,
|
||||
injectFn: meta.injectFn,
|
||||
},
|
||||
meta.isPipe);
|
||||
}
|
||||
|
@ -89,7 +89,8 @@ export function compilePipeFromRender2(
|
||||
pure: pipe.pure,
|
||||
};
|
||||
const res = compilePipeFromMetadata(metadata);
|
||||
const factoryRes = compileFactoryFromMetadata({...metadata, isPipe: true});
|
||||
const factoryRes =
|
||||
compileFactoryFromMetadata({...metadata, injectFn: R3.directiveInject, isPipe: true});
|
||||
const definitionField = outputCtx.constantPool.propertyNameOf(DefinitionKind.Pipe);
|
||||
const ngFactoryDefStatement = new o.ClassStmt(
|
||||
/* name */ name,
|
||||
|
@ -325,7 +325,7 @@ export function compileDirectiveFromRender2(
|
||||
|
||||
const meta = directiveMetadataFromGlobalMetadata(directive, outputCtx, reflector);
|
||||
const res = compileDirectiveFromMetadata(meta, outputCtx.constantPool, bindingParser);
|
||||
const factoryRes = compileFactoryFromMetadata(meta);
|
||||
const factoryRes = compileFactoryFromMetadata({...meta, injectFn: R3.directiveInject});
|
||||
const ngFactoryDefStatement = new o.ClassStmt(
|
||||
name, null,
|
||||
[new o.ClassField(
|
||||
@ -378,7 +378,7 @@ export function compileComponentFromRender2(
|
||||
i18nUseExternalIds: true,
|
||||
};
|
||||
const res = compileComponentFromMetadata(meta, outputCtx.constantPool, bindingParser);
|
||||
const factoryRes = compileFactoryFromMetadata(meta);
|
||||
const factoryRes = compileFactoryFromMetadata({...meta, injectFn: R3.directiveInject});
|
||||
const ngFactoryDefStatement = new o.ClassStmt(
|
||||
name, null,
|
||||
[new o.ClassField(
|
||||
|
Reference in New Issue
Block a user