-
Notifications
You must be signed in to change notification settings - Fork 713
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
One phase initialization for providers #418
Comments
I started working on this and I realized that the proposed solution has a problem: It assumes that we want the provider to return a singleton. For this reason, I decided not to go ahead with this change. However, I noticed that the Provider was much less flexible than the Factory. I have upgraded the Provider signature to allow advanced use cases like:
I have created a PR #431 that documents all these features. The PR also documents a "recipe" that helps to reduce boilerplate: function valueOrDefault<T>(provider: () => Promise<T>, defaultValue: T) {
return new Promise<T>((resolve, reject) => {
provider().then((value) => {
resolve(value);
}).catch(() => {
resolve(defaultValue);
});
});
} @injectable()
class Ninja {
public level: number;
public rank: string;
public constructor() {
this.level = 0;
this.rank = "Ninja";
}
public train(): Promise<number> {
return new Promise<number>((resolve) => {
setTimeout(() => {
this.level += 10;
resolve(this.level);
}, 100);
});
}
}
@injectable()
class NinjaMaster {
public rank: string;
public constructor() {
this.rank = "NinjaMaster";
}
}
type NinjaMasterProvider = () => Promise<NinjaMaster>;
let container = new Container();
container.bind<Ninja>("Ninja").to(Ninja).inSingletonScope();
container.bind<NinjaMasterProvider>("NinjaMasterProvider").toProvider((context) => {
return () => {
return new Promise<NinjaMaster>((resolve, reject) => {
let ninja = context.container.get<Ninja>("Ninja");
ninja.train().then((level) => {
if (level >= 20) {
resolve(new NinjaMaster());
} else {
reject("Not enough training");
}
});
});
};
});
let ninjaMasterProvider = container.get<NinjaMasterProvider>("NinjaMasterProvider");
valueOrDefault(ninjaMasterProvider, { rank: "DefaultNinjaMaster" }).then((ninjaMaster) => {
// Using default here because the provider was rejected (the ninja has a level below 20)
expect(ninjaMaster.rank).to.eql("DefaultNinjaMaster");
});
valueOrDefault(ninjaMasterProvider, { rank: "DefaultNinjaMaster" }).then((ninjaMaster) => {
// A NinjaMaster was provided because the the ninja has a level above 20
expect(ninjaMaster.rank).to.eql("NinjaMaster");
done();
}); |
* Remove default exports * Upgraded tslint * Implemented #408 * Implementes #419 * fixes #405 * release 3.0.0-beta.2 * Implements #421 & refactor enum -> literal types * Added #421 docs * Working on #193 * Working on #193 * Working on #193 * Working on #193 * Working on #193 * Working on #193 * Working on #193 * Working on #193 * [WIP] #418 * [WIP] #418
Any updates on this feature? |
Expected Behavior
Reduce the number of steps required by the users when using synchronous factories (AKA Providers).
Current Behavior
Asynchronous factories require two steps for initialization:
Possible Solution
As suggested by @buehler:
Context
#404
The text was updated successfully, but these errors were encountered: