Skip to content
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

ASP.Net Core 3.1 - DbContext (Transient Disposable) store in Scope Container #261

Closed
Ager1912 opened this issue Apr 12, 2020 · 6 comments
Closed

Comments

@Ager1912
Copy link

Ager1912 commented Apr 12, 2020

Hi,
I am using DryIoc (last release version) for Dependency Injection.
In my application (Asp.net Core 3.1), I am using Entity Framework.
My AppDbContext hinerits DbContext and implements IDisposable
I also use UnitOfWork pattern and the class is disposable.

These two objects are declared as Transient.
I follow the documentation that explains the context with Transient Disposable objects:
https://github.com/dadhi/DryIoc/blob/master/docs/DryIoc.Docs/ReuseAndScopes.md

For my AppDbContext, I resolve this service manually. Same thing for my UnitOfWork. At the end I call Dispose method.
But these two instances are not destroyed and are stored in the Singleton Scope of the DryIoc Container.

I did some tests and use JetBrain dotMemory.
My test is to call around 300 times a method

  • Call controler
  • open UnitOfWork
  • create AppDbContext
  • call database to get my data
  • close / dispose objects.
    At the end, I have around 300 times my AppDbContext and my UnitOfWork in the scope of the container:

image

I try a lot of combinaison of creation of container but each time, it is the same thing:

var container = new Container(rules => rules.With(propertiesAndFields: request => request.ServiceType.Name.EndsWith("Controller") ? PropertiesAndFields.Auto(request) : null) // .WithoutThrowOnRegisteringDisposableTransient() // .WithTrackingDisposableTransients() .WithoutThrowIfDependencyHasShorterReuseLifespan()) .WithDependencyInjectionAdapter(services); Result: memory is growing up fast because of these two kind of objects stored in the scope.

If I comment .WithoutThrowOnRegisteringDisposableTransient(), my code is still working (I thought an exception would be thrown)

I tried also to declare these services as Scoped (for each http request) but it does not work because I don't create scope for each query. (Exception thrown and a scope is automatically opened per each web request by Asp .Net Core framework).

Maybe I need to dispose scope at the end of each request?

Thanks for your help.

@dadhi
Copy link
Owner

dadhi commented Apr 13, 2020

Maybe I need to dispose scope at the end of each request?

Likely yes. and the creation of the scope for each query / request seems like a natural choice for Unit-of-work pattern. Otherwise, transient disposables are accumulating at the top level (Singleton) because we need to track them somewhere for disposal, and we have no Scope to put them in.

@Ager1912
Copy link
Author

Hello,
Thanks for your quick answer.
I change the resolution by calling New method instead of Resolve.
I hadn't paid attention to this method. It is sloved my issue.

Last question: is there a way/a method to release an instance in the scope?

@dadhi
Copy link
Owner

dadhi commented Apr 13, 2020

The method is Disposing the scope.

@Ager1912
Copy link
Author

Hello,
Ok
Sorry for my questions but I don't understand something.
Actually, I used the New method instead of Resolve but I still have some instances of my UnitOfWork and my DbContext. Do you have any idea why?

On StackOverFlow, I asked how to have one scope per http request.
You told me a scope is automatically open per each web request by Asp .Net Core framework, you don't need to bother.

So I don't open any Scope.
In my container, ScopeContext, CurrentScope are null. Only SingletonScope is not null.
So I can't dispose this scope.
Is there another way?

Now if I want to open a scope per HTTP Request, I don't know where I can do it.
I follow the sample:
https://bitbucket.org/dadhi/dryioc/src/8e609b011beafd71236f9cfe3bb2d3e0589e76ae/NetCore/src/DryIoc.AspNetCore.Sample/
But because I don't have any scope opened, I can't call the method Resolve or New on a service declared as Scoped. So in my application, all services are transient or singleton.
Maybe it is a wrong way?

I am a little bit wonfused. But the memory of my application is growing up and between two snapshots, the Scope size is growing up.

Thanks for your help.

dadhi pushed a commit that referenced this issue Apr 14, 2020
@dadhi
Copy link
Owner

dadhi commented Apr 14, 2020

@Ager1912

I have released the new DryIoc.Microsoft.DependencyInjection v4
and created the fresh sample for ASP .NET Core https://github.com/dadhi/DryIoc/tree/master/samples/DryIoc.AspNetCore31.WebApi.Sample

Please check it out.

@Ager1912
Copy link
Author

Hi,
Thanks.
I upgraded the version.
And for my issue of memory, I open a Scope and Dispose it when my unit of work is disposed.

Thanks for your time.
Adrien

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants