Skip to content

Commit 6c09c69

Browse files
committed
allow overwriting a registered component
1 parent 13fb2fd commit 6c09c69

File tree

3 files changed

+73
-9
lines changed

3 files changed

+73
-9
lines changed

packages/app/src/firebaseApp.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,9 +144,16 @@ export class FirebaseAppImpl implements FirebaseApp {
144144
this.container.getProvider(name).clearInstance(instanceIdentifier);
145145
}
146146

147-
_addComponent(component: Component): void {
147+
/**
148+
*
149+
* @param component the component being added to this app's container
150+
* @param overwrite When a component with the same name has already been registered,
151+
* if overwrite is true: overwrite the existing component
152+
* if overwrite is false: throw an expection
153+
*/
154+
_addComponent(component: Component, overwrite = false): void {
148155
try {
149-
this.container.addComponent(component);
156+
this.container.addComponent(component, overwrite);
150157
} catch (e) {
151158
logger.debug(
152159
`Component ${component.name} failed to register with FirebaseApp ${this.name}`,

packages/component/src/component_container.test.ts

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ describe('Component Container', () => {
5555
expect(setComponentStub).has.been.calledWith(component);
5656
});
5757

58-
it('throws when registering multiple components with the same name', () => {
58+
it('throws when registering multiple components with the same name, when overwrite is false', () => {
5959
const component1 = getFakeComponent(
6060
'fireball',
6161
() => ({}),
@@ -74,4 +74,47 @@ describe('Component Container', () => {
7474
/Component fireball has already been registered with/
7575
);
7676
});
77+
78+
it('does not throw when registering multiple components with the same name, when overwrite is true', () => {
79+
const component1 = getFakeComponent(
80+
'fireball',
81+
() => ({}),
82+
true,
83+
InstantiationMode.EAGER
84+
);
85+
const component2 = getFakeComponent(
86+
'fireball',
87+
() => ({ test: true }),
88+
false,
89+
InstantiationMode.LAZY
90+
);
91+
92+
expect(() => container.addComponent(component1)).to.not.throw();
93+
expect(() => container.addComponent(component2, true)).to.not.throw();
94+
});
95+
96+
it('registers a component with a name that is already registered and return the provider for the new component', () => {
97+
const component1 = getFakeComponent(
98+
'fireball',
99+
() => ({ test: false }),
100+
true,
101+
InstantiationMode.EAGER
102+
);
103+
const component2 = getFakeComponent(
104+
'fireball',
105+
() => ({ test: true }),
106+
false,
107+
InstantiationMode.LAZY
108+
);
109+
110+
container.addComponent(component1);
111+
const oldProvider = container.getProvider('fireball');
112+
expect(oldProvider.getImmediate()).to.deep.eq({ test: false });
113+
114+
container.addComponent(component2, true);
115+
const newProvider = container.getProvider('fireball');
116+
expect(oldProvider).to.not.eq(newProvider);
117+
expect(newProvider.getImmediate()).to.deep.eq({ test: true });
118+
119+
});
77120
});

packages/component/src/component_container.ts

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,28 @@ import { Component } from './component';
2121
export class ComponentContainer {
2222
private providers = new Map<string, Provider>();
2323

24-
constructor(private name: string) {}
24+
constructor(private name: string) { }
2525

26-
addComponent(component: Component): void {
27-
const provider = this.getProvider(component.name);
26+
/**
27+
*
28+
* @param component Component being added
29+
* @param overwrite When a component with the same name has already been registered,
30+
* if overwrite is true: overwrite the existing component with the new component and create a new provider with the new component
31+
* if overwrite is false: throw an expection
32+
*/
33+
addComponent(component: Component, overwrite = false): void {
34+
let provider = this.getProvider(component.name);
2835
if (provider.isComponentSet()) {
29-
throw new Error(
30-
`Component ${component.name} has already been registered with ${this.name}`
31-
);
36+
if (!overwrite) {
37+
throw new Error(
38+
`Component ${component.name} has already been registered with ${this.name}`
39+
);
40+
} else { // use the new component to replace the existing component
41+
// delete the existing provider from the container
42+
this.providers.delete(component.name);
43+
// create a new provider
44+
provider = this.getProvider(component.name);
45+
}
3246
}
3347

3448
provider.setComponent(component);

0 commit comments

Comments
 (0)