-
Notifications
You must be signed in to change notification settings - Fork 450
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
Issue with IServiceProvider, Scope, Sub scope #5312
Comments
(1) I have read in other tickets here that others are using "side containers", I think @APIWT mentioned he was using this approach to counter DI issues (can't find link). In relation to your question (2), I have witnessed that the DryIOC container can handle and does handle disposables. The Functions runtime does however appear to execute the dispose in a different logical execution context. As a practical example, any I too have noticed, as have you, that the Theoretically this seems sound, so it being a singleton doesn't seem too offensive (but perhaps I've just rationalised this perspective too much?). In practice at present, there is a bug in there somewhere (my #4914 and @heikkilamarko #5098), or its not quite implemented right - the timing of the capture of the |
Thanks for reporting this. I'll be blocking some time to look at this area soon, and have identified an issue impacting the scenario reported by @t-l-k, just pending some validation before I can get that in. |
Hello, any progress so far? |
Any progress on this? |
Possibly flogging a dead horse here, but I am still seeing this issue, was there ever any solution to this? It really does seem like Scoped dependencies are not always honoured through our request lifecycle. @jeffhollan, this was marked as a P1 in Feb, it would be great if this was acknowledged or even closed with a description regarding best practice to work around. Cheers |
Hello, I am author of DryIoc. I have read the issue but still not sure that I get the problem. There is a lot of references and split info. I am willing to help if someone explains what DryIoc version and the rules are used.. What is expected behavior and what is the problem. |
Hey @dadhi Thanks for taking the time to respond here. From what I have seen I don’t think this is necessarily an issue with DryIoC, but instead how the container and it’s child scopes are being managed within the function runtime. As the example repo above shows, a static container, both DryIoC and a new IServiceCollection, both resolve dependencies as expected. The issue appears when you try and resolve a service from the primary Functions IOC container which is using DryIoC under the hood. In these instances the lifetimes of the IServiceProvider injected to our services are not as expected. In the repo above in all occasions it resolves a scoped service from what appears to be the wrong scope. I am not sure if this has something to do with the AsyncLocal where the scope is stored, or from how the Azure function starts up (I was seeing this on a cold start using Mediatr behaviours), warm start was fine. It I am sure is a difficult problem to diagnose, I had a quick scan but ended in deep without the time. We worked around it be simply removing our scoped dependencies, but this is obviously not ideal. Any help would be appreciated. Thanks again. |
DryIoc scoping behavior depends on the rules. By default it does not use the shared scope context - the scopes tree is bound to the container instance. But you opt-in it with the shared scope context where the the scopes are tracked. One of the predefined contexts is the |
The example created by @MihaiStrejer above reproduces this 100% of the time from what I could see. As I say, the complexities of the function runtime and also DryIoC make this problem, for me anyway, non trivial to resolve and in honesty feel it requires buy-in by the MS team to resolve it. I am not sure it something mere mortal like myself would be best place to resolve in any sort of timely manner, plus we do pay for Azure functions so don't think it unfair we ask the question. Again, I am really appreciatove of the work happening here, but from the MS side I feel this should be a higher priority than it currently is. I'm not really sure this should be your resposibility @dadhi, but I do appreciate you looking. |
Kuds on those docs too @dadhi, some great reading here and food for thought for my problem we worked around. I'll be sure to give it a go 👍 |
Indeed, and as @micklaw stated this is not a problem with DryIoc, but a problem with the azure function host.
I think this is how the container is setup: azure-functions-host/src/WebJobs.Script.WebHost/DependencyInjection/WebHostServiceProvider.cs Line 19 in 9fb8b40
|
@MihaiStrejer FYI It is possible that the fix is in for this issue via ticket #5098 |
I've been waiting for #3399 to be resolve but when I ran my test I've got a strange result. It has to do with creating a sub scope using the function scoped IServiceProvider. In other IOC frameworks an instance that got created by the scope and tries to resolve IServiceProvider would get the creator scope reference. This is not the case in azure functions IOC.
More so between subsequent runs the HashCode of the function scope does not change however some cleanup appears to be done since the scoped services are not the same.
Possibly related to #4914
I have a created sample repository here: Repo
The code is fairly simple I'm going to list some details below:
Objects lifetime:
TestService, MedRequestHandler - transient
MediatR - scoped (as well as the ServiceFactory)
MyStateService - scoped
Azure Function Scope > (DryIoc and the .Net container create new scopes in the FunctionEntry)
FunctionEntry (Function1) >
CreateSubScope and load a state >
Resolve TestService that checks IServiceProvider >
MediatR create and run request >
MedRequestHandler that checks IServiceProvider
Normally you would expect to see the scope and state created in CreateSubScope to propagate down the line.
And some final questions:
Up until now I've ran with a custom side container that behaves as expected (similar to the example DryIocSideContainer). Are there any potential issues with running a side container in functions, at least until the scope issue is fixed?
Does the scope created by azure functions handle IDisposables? Does it "behave" similarly to the default DryIoc container?
The text was updated successfully, but these errors were encountered: