-
Notifications
You must be signed in to change notification settings - Fork 135
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
Add support for Asynchronous Factories #12
Comments
You want to inject a database connection which you optain with an async call, correct? 😊 |
@osher I use this pattern with great success:
At one point there was support for "async" registrations but it made the simpler usage way more complicated. To summarize: create your container when you have everything you need. 😄 |
Closing due to inactivity and an alternative pattern has been provided. |
but how would you inject configuration parameters into |
@amitport depends on where you store them. I usually just do this:
|
Well, it will be nice to store those get those parameter through awilix as well, but I understand that it is not possible (currently). |
Personally wouldn't do it that way since it's just config that you use only for that particular service. |
Sir, with all the respect - that's a very weak answer.
Please try to see it from my perspective for a minute:
I contributed of my time to let you know of a feature request.
If you don't intend to support it - don't tell me stories how to work
around your limit - I had things done before awilix, you know?
I advise you to just kindly say:
"sorry, we do not intend to support this feature - this is out of scope for
awilix"
And if you allow me to be blunt for a minute - this translates to:
"we mean to give you a partial solution
Go initiate your modules on your own and then we'll cover whatever work is
left"
Which kinda defeats the purpose, but if that's the situation - I'll respect
your choice.
…On Thu, Mar 16, 2017 at 6:55 PM, Jeff Hansen ***@***.***> wrote:
Closing due to inactivity and an alternative pattern has been provided.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#12 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AAxBHVn5tPEWM6nb2r9gaCraB9cUVVnqks5rmWl0gaJpZM4MFZrl>
.
|
@osher that was not respectful at all.
I contributed my time to build this library and open source it for others to use free of charge, even MIT licensed.
I told you "stories to work around the limit" in an attempt to help you out. My answer is how async dependencies should be handled in Awilix. I don't intend to support it not because it's impossible to implement, but because I feel it does not fit in a proper DI pipeline and would complicate usage for others using DI the intended way. It would make it impossible to use The primary design goal of Awilix is that, if you chose to, you could throw it away and wire up your modules manually: // no mention of awilix anywhere - good ol' constructor injection
const service1 = new Service1()
const service2 = new Service2()
const service3 = new Service3({
service1: service1,
service2: service2
})
It is not a partial solution.
Do you mean that you would have to manually set up the dependencies that the async async function configureContainer () {
const container = createContainer()
container.registerValue('someDepThatDbNeeds', 42)
// returns a promise
const connection = await connectToDb(container.cradle)
return container
.registerValue({ connection })
}
// in some main file
configureContainer().then(container => {
// You're ready!
}) |
@amitport if you really want to store the config values in the container, you can use the approach in the comment above 😄 |
Hi All, I am faced with the same conundrum as @osher .. I need to resolve values after the container has been initialized. I don't have much knowledge of the internals of this project, but I'd love to see a native solution implemented and look forward to your thoughts on this. Here's an example of what I have: container.register({
sources: asValue<Source[]>([
new PrimarySource(),
new SecondarySource(),
]),
loader: asFunction<Source[]>(async (someValue: string, sources: Source[]) => {
for (let source of sources){
const supported = await source.supports(someValue);
if (supported) {
return new Loader(source);
}
}
throw new Error(`'${someValue}' is not supported`);
}).scope()
}) At invocation time, I am given const someValue = // get it from arguments/env/request/db/etc
const scope = container.createScope();
scope.register({
someValue: asValue<string>(someValue)
});
const loader = scope.resolve<Loader>('loader');
// this loader is not the Loader instance, but instead, a promise that resolves a Loader instance, ie Promise<Loader> Is there any reason not to implement a function which could resolve the promise before returning the value registered with the container? Example: loader: asFunction<Source[]>(async (someValue: string, sources: Source[]) => {
...
...
}).await().scope() Notice the Thanks for this great library and I look forward to hearing your thoughts. |
My guess is the library was built synchronously, and this would introduce asynchronicity which would be impossible to overcome without an entire rework of the base logic, and therefore, it would introduce breaking changes? |
You are correct that it would require the core to be async, which would incur a significant performance overhead for 99% of use cases that just use synchronous dependencies. I suggest you use the pattern outlined above, or a factory instead. |
From your README.md example:
This does not pass for me... 😢.
Dependency innitiations are often an asynchronous operation, especially when working with fail-fast policy. If a Peer cannot be found - I want the service to fail as soon as possible - preferably before it joins the load balancer.
For this I need my dependencies to be more eager-loaded and less lazy loaded.
Would you please consider support for
?
Thanks
The text was updated successfully, but these errors were encountered: