Disposable Request-scoped object - c#

I need to properly Dispose of an object instantiated at request-level scope in my MVC 5 application.
I have declared the object as follows:
<object id="dataContext" singleton="false" scope="request" type="MyDisposableObject, MyAssembly" factory-object="dataContextFactory" factory-method="Build" destroy-method="Dispose" ></object>
<object id="dataContextFactory" scope="application" type="MyFactoryClass, MyAssembly"/>
Code for the DataContextFactory is the following (there is little masking in names)
public class DataContextFactory: DbConfiguration
{
public IDisposable Build()
{
return new Wrapper();
}
private class Wrapper : MyDisposableObject //: DbContext
{
protected override void Dispose(bool disposing)
{
base.Dispose(disposing); //BREAKPOINT HERE
}
public new void Dispose()
{
base.Dispose(); //BREAKPOINT HERE
}
}
}
This experiment shows me, by placing a breakpoint on the Dispose method, that when I end page request the object (which is ultimately an EF6 DbContext) is not disposed of.
I have read SPRNET-318 but it's kinda ambiguous to me. The bug title is "IDisposable singletons with request or session scopr are not disposed of", which matches my case; however the correlated forum topic says about calling WebApplicationContext.Dispose, which is not my case because I never dispose of the context when the request ends.
Am I missing something on disposing of object at request/session level?

Related

DbContext not Disposed using dependencyinjection

In its most simple form, i created a new mvc core project, and created a class:
public class Test : IDisposable
{
public void Dispose()
{
}
}
registered it
services.AddScoped<Test>();
and used it in the constructor of a controller
public HomeController(ILogger<HomeController> logger, Test t)
{
_logger = logger;
}
When i set a breakpoint at Test.Dispose(), it is hit as expected after loading the home page.
Now i change the Test class as follows:
public class Test : DbContext
{
public override void Dispose()
{
}
}
Now Disposed is not called anymore... Why is this???
I also tried
services.AddDbContext<Test>();
instead of AddScoped, but that makes no difference.
What do i need to change to make the container call dispose as it did in the first situation?
(related Question without answer)
You need to override the Dispose(bool) method rather than the (usually) non-virtual Dispose() method. Try this:
protected override void Dispose(bool disposing)
{
// implementation
}
And set a breakpoint to see if it hits. There's more info abotu the difference here:
https://learn.microsoft.com/en-us/dotnet/standard/garbage-collection/implementing-dispose
In case a class implements both IDisposable and IAsyncDisposable, MS.DI prefers to call IAsyncDisposable whenever possible. This means that it will rather call DisposeAsync and skip Dispose altogether. This happens when you call IServiceScope.DisposeAsync.
In the context of ASP.NET Core, the request's IServiceScope will be disposed asynchronously, hense the absense of the call to Dispose.

Why do I need I need to implement IDisposable() on a child class

I wrote a class that inherits DbConnection and I'm not understanding fully why it works as it does.
At first I had this :
public class DatabaseConnection : DbConnection
{
...
public override void Close()
{
// Some stuff
}
// No Dispose method
}
using(var db = new DatabaseConnection())
{
// Some processing
}
The Close() method was not called, and we could see the connections staying on the MySQL server.
Now I have this, and it works (it really closes the connections, and the server is OK) :
public class DatabaseConnection : DbConnection, IDisposable
{
...
public override void Close()
{
// Some stuff
}
public new void Dispose()
{
Close();
base.Dispose();
GC.SuppressFinalize(this);
}
}
using(var db = new DatabaseConnection())
{
// Some processing
}
Why inheriting the DbConnection class and overriding the Close() method doesn't work ?
You can see in the reference source that DbConnection does not override Dispose, so Dispose will not call Close.
DbConnection inherits from Component, which is where the implementation of IDisposable is. You can see from the reference source that its Dispose(bool disposing) method is virtual, so you should override that:
protected override void Dispose(bool disposing)
{
base.Dispose(disposing)
Close();
}
The using statement calls the Dispose method at the end of the block.
Since the DbConnection also implements the IDisposable interface, the using block in the first snippet calls the inherited Dispose method.
The connection stays alive perhaps because you override the Close function, but I'm not sure in this, please correct me if I'm wrong.

How to implement IDisposable in Entity Framework?

I am having my entity framework context in a separate EL Layer, which stands for Entity Layer and then I move to DAL, then BL and my user inteface aspx.cs code page.
I am confused as such how to use IDisposable in the same.
What I am doing till now, supopose in my DAL I have context of my entities.
namespace abc
{
public class Action: IDisposable
{
Entities context = new Entities();
// all the methods
public void Dispose()
{
context.Dispose();
}
}
}
Is it the correct way of doing so?
I am just a naive programmer so help me in learning the same logic.
Personally I would change it a little bit, such as:
Although I have very little experience with implementing the IDisposable within the Entity Framework.
namespace abc
{
public class Action: IDisposable
{
private bool _disposed;
Entities context= new Entities();
// all the methods
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
context.Dispose();
// Dispose other managed resources.
}
//release unmanaged resources.
}
_disposed = true;
}
}
}
Well in general, yes, your Dispose method should dispose of all resources that implement IDisposable as well as unmanaged resources (files, etc.)
However, it it usually not a good design to hold on to an EF context as a resource. You will likely have better success if you create a Context within your Action methods and dispose of it when you're done with it. Then, if that's your only resource, you don't need to implement IDisposable at all.

Do not call Dispose of parts in dispose MEF

I ran into a problem when the application ends the container does not call the Dispose method of the parts.
Application based on MEF.
When I explicitly call Dispose the container, then matod Dispose is called on the parts, but if you just close the program, the Dispose of the parts will not be called, why?
How to make sure that when you close the program were caused by the Dispose method of all parts of the container MEF?
[Export(typeof(IMyClass))]
[PartCreationPolicy(CreationPolicy.Shared)]
public class MyClass: IDisposable, IMyClass
{
private bool disposed = false;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if(!this.disposed)
{
if(disposing)
{
// Dispose managed resources.
}
disposed = true;
}
}
~MyClass()
{
Dispose(false);
}
}
When I explicitly call Dispose the container, then matod Dispose is called on the parts, but if you just close the program, the Dispose of the parts will not be called, why?
Because disposing the container when you are done with it is mandatory. If your program does not call CompositionContainer.Dispose() before exiting, then that is a bug in your program.
Wim Coenen, thanks, I thought that the destruction of MEF must call Destruct on parts.
I made ​​sure to work the way I need to:
public partial class MyBootstrapper : MefBootstrapper
{
public MyBootstrapper()
{
App.Current.Exit += new ExitEventHandler(Current_Exit);
}
void Current_Exit(object sender, ExitEventArgs e)
{
if (this.Container != null)
this.Container.Dispose();
}
...

Calling base.Dispose() automatically from derived classes

Edit - New Question
Ok lets rephrase the question more generically.
Using reflection, is there a way to dynamically call at runtime a base class method that you may be overriding. You cannot use the 'base' keyword at compile time because you cannot be sure it exists. At runtime I want to list my ancestors methods and call the ancestor methods.
I tried using GetMethods() and such but all they return are "pointers" to the most derived implementation of the method. Not an implementation on a base class.
Background
We are developing a system in C# 3.0 with a relatively big class hierarchy. Some of these classes, anywhere in the hierarchy, have resources that need to be
disposed of, those implement the IDisposable interface.
The Problem
Now, to facilitate maintenance and refactoring of the code I would like to find a way, for classes implementing IDisposable,
to "automatically" call base.Dispose(bDisposing) if any ancestors also implements IDisposable. This way, if some class higher up in the hierarchy starts implementing
or stops implementing IDisposable that will be taken care of automatically.
The issue is two folds.
First, finding if any ancestors implements IDisposable.
Second, calling base.Dispose(bDisposing) conditionally.
The first part, finding about ancestors implementing IDisposable, I have been able to deal with.
The second part is the tricky one. Despite all my
efforts, I haven't been able to call base.Dispose(bDisposing) from a derived class. All my attempts failed. They either caused
compilation errors or called the wrong Dispose() method, that is the most derived one, thus looping forever.
The main issue is that you cannot actually refer to base.Dispose() directly in your code if there is no such thing as an
ancestor implementing it (be reminded that there might have no ancestors yet implementing IDisposable, but I want the derived code to be ready when and if such
a thing happens in the future). That leave us with the Reflection mechanisms, but I did not find a proper way of doing it. Our code is quite filled with
advanced reflection techniques and I think I did not miss anything obvious there.
My Solution
My best shot yet was to have some conditional code using in commented code. Changing the IDisposable hierarchy would either break the build
(if no IDisposable ancestor exists) or throw an exception (if there are IDisposable ancestors but base.Dispose is not called).
Here is some code I am posting to show you what my Dispose(bDisposing) method looks like. I am putting this code at the end of all the Dispose()
methods throughout the hierarchy. Any new classes are created from templates that also includes this code.
public class MyOtherClassBase
{
// ...
}
public class MyDerivedClass : MyOtherClassBase, ICalibrable
{
private bool m_bDisposed = false;
~MyDerivedClass()
{
Dispose(false);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool bDisposing)
{
if (!m_bDisposed) {
if (bDisposing) {
// Dispose managed resources
}
// Dispose unmanaged resources
}
m_bDisposed = true;
Type baseType = typeof(MyDerivedClass).BaseType;
if (baseType != null) {
if (baseType.GetInterface("IDisposable") != null) {
// If you have no ancestors implementing base.Dispose(...), comment
// the following line AND uncomment the throw.
//
// This way, if any of your ancestors decide one day to implement
// IDisposable you will know about it right away and proceed to
// uncomment the base.Dispose(...) in addition to commenting the throw.
//base.Dispose(bDisposing);
throw new ApplicationException("Ancestor base.Dispose(...) not called - "
+ baseType.ToString());
}
}
}
}
So, I am asking is there a way to call base.Dispose() automatically/conditionally instead?
More Background
There is another mechanism in the application where all objects are registered with a main class. The class checks if they implement IDisposable.
If so, they are disposed of properly by the application. This avoids having the code using the classes to deal with
calling Dispose() all around by themselves. Thus, adding IDisposable to a class that has no ancestor history of IDisposable still works perfectly.
The standard pattern is for your base class to implement IDisposable and the non-virtual Dispose() method, and to implement a virtual Dispose(bool) method, which those classes which hold disposable resources must override. They should always call their base Dispose(bool) method, which will chain up to the top class in the hierarchy eventually. Only those classes which override it will be called, so the chain is usually quite short.
Finalizers, spelled ~Class in C#: Don't. Very few classes will need one, and it's very easy to accidentally keep large object graphs around, because the finalizers require at least two collections before the memory is released. On the first collection after the object is no longer referenced, it's put on a queue of finalizers to be run. These are run on a separate, dedicated thread which only runs finalizers (if it gets blocked, no more finalizers run and your memory usage explodes). Once the finalizer has run, the next collection that collects the appropriate generation will free the object and anything else it was referencing that isn't otherwise referenced. Unfortunately, because it survives the first collection, it will be placed into the older generation which is collected less frequently. For this reason, you should Dispose early and often.
Generally, you should implement a small resource wrapper class that only manages the resource lifetime and implement a finalizer on that class, plus IDisposable. The user of the class should then call Dispose on this when it is disposed. There shouldn't be a back-link to the user. That way, only the thing that actually needs finalization ends up on the finalization queue.
If you are going to need them anywhere in the hierarchy, the base class that implements IDisposable should implement the finalizer and call Dispose(bool), passing false as the parameter.
WARNING for Windows Mobile developers (VS2005 and 2008, .NET Compact Framework 2.0 and 3.5): many non-controls that you drop onto your designer surface, e.g. menu bars, timers, HardwareButtons, derive from System.ComponentModel.Component, which implements a finalizer. For desktop projects, Visual Studio adds the components to a System.ComponentModel.Container named components, which it generates code to Dispose when the form is Disposed - it in turn Disposes all the components that have been added. For the mobile projects, the code to Dispose components is generated, but dropping a component onto the surface does not generate the code to add it to components. You have to do this yourself in your constructor after calling InitializeComponent.
Personally, I think you might be better off handling this with something like FxCop. You should be able to write a rule that check so see if when an object is created that implements IDisposable that you use a using statement.
It seems a little dirty (to me) to automatically dispose an object.
There is not an "accepted" way of doing this. You really want to make your clean up logic (whether it runs inside of a Dispose or a finalizer) as simple as possible so it won't fail. Using reflection inside of a dispose (and especially a finalizer) is generally a bad idea.
As far as implementing finalizers, in general you don't need to. Finalizers add a cost to your object and are hard to write correctly as most of the assumptions you can normally make about the state of the object and the runtime are not valid.
See this article for more information on the Dispose pattern.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace TestDisposeInheritance
{
class Program
{
static void Main(string[] args)
{
classC c = new classC();
c.Dispose();
}
}
class classA: IDisposable
{
private bool m_bDisposed;
protected virtual void Dispose(bool bDisposing)
{
if (!m_bDisposed)
{
if (bDisposing)
{
// Dispose managed resources
Console.WriteLine("Dispose A");
}
// Dispose unmanaged resources
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
Console.WriteLine("Disposing A");
}
}
class classB : classA, IDisposable
{
private bool m_bDisposed;
public void Dispose()
{
Dispose(true);
base.Dispose();
GC.SuppressFinalize(this);
Console.WriteLine("Disposing B");
}
protected override void Dispose(bool bDisposing)
{
if (!m_bDisposed)
{
if (bDisposing)
{
// Dispose managed resources
Console.WriteLine("Dispose B");
}
// Dispose unmanaged resources
}
}
}
class classC : classB, IDisposable
{
private bool m_bDisposed;
public void Dispose()
{
Dispose(true);
base.Dispose();
GC.SuppressFinalize(this);
Console.WriteLine("Disposing C");
}
protected override void Dispose(bool bDisposing)
{
if (!m_bDisposed)
{
if (bDisposing)
{
// Dispose managed resources
Console.WriteLine("Dispose C");
}
// Dispose unmanaged resources
}
}
}
}
If you wanted to use [basetype].Invoke("Dispose"...) then you could implement the function call without the debugger complaining. Then later when the base type actually implements the IDisposable interface it will execute the proper call.
If you wanted to use [basetype].Invoke("Dispose"...) then you could implement the function call without the debugger complaining. Then later when the base type actually implements the IDisposable interface it will execute the proper call.
Try this. It's a one-line addition to the Dispose() method, and calls the ancestor's dispose, if it exists. (Note that Dispose(bool) is not a member of IDisposable)
// Disposal Helper Functions
public static class Disposing
{
// Executes IDisposable.Dispose() if it exists.
public static void DisposeSuperclass(object o)
{
Type baseType = o.GetType().BaseType;
bool superclassIsDisposable = typeof(IDisposable).IsAssignableFrom(baseType);
if (superclassIsDisposable)
{
System.Reflection.MethodInfo baseDispose = baseType.GetMethod("Dispose", new Type[] { });
baseDispose.Invoke(o, null);
}
}
}
class classA: IDisposable
{
public void Dispose()
{
Console.WriteLine("Disposing A");
}
}
class classB : classA, IDisposable
{
}
class classC : classB, IDisposable
{
public void Dispose()
{
Console.WriteLine("Disposing C");
Disposing.DisposeSuperclass(this);
}
}
public class MyVeryBaseClass {
protected void RealDispose(bool isDisposing) {
IDisposable tryme = this as IDisposable;
if (tryme != null) { // we implement IDisposable
this.Dispose();
base.RealDispose(isDisposing);
}
}
}
public class FirstChild : MyVeryBaseClasee {
//non-disposable
}
public class SecondChild : FirstChild, IDisposable {
~SecondChild() {
Dispose(false);
}
public void Dispose() {
Dispose(true);
GC.SuppressFinalize(this);
base.RealDispose(true);
}
protected virtual void Dispose(bool bDisposing) {
if (!m_bDisposed) {
if (bDisposing) {
}// Dispose managed resources
} // Dispose unmanaged resources
}
}
That way, you are responsible to implement right only the first class which is IDisposable.

Categories

Resources