DbContext not Disposed using dependencyinjection - c#

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.

Related

how Dispose() works inside my Controller and Repository classes

I am working on asp.net mvc-4 web application and entity framework 5.0. now i am confused on how Dispose is working inside my application. currently i have the following settings:-
-I have a APIRepository class which contain multiple methods that use WebClient() to do external API calls. and i do not define any Dispose method inside this class.
public class APIRepository
{
public string AddTicket(string title, string technichian,string account,string site,string description,string mode,string requestor)
{
//code goes here
using (var client = new WebClient())
{
}
return result;
}
//code goes here
}
-I have a Repository class which contain my data access logic, and it initiate my DbContext, and i define a Dispose method inside this class.
public class Repository
{
private MyEntities my = new MyEntities();
//code goes here...
public void Dispose()
{
my.Dispose();
}
-I have a Controller class, which initiate the two repository classes:-
[RequireHttps]
public class ServerController : Controller
{
Repository repository = new Repository();
APIRepository APIrepository = new APIRepository();
//code goes here
protected override void Dispose(bool disposing)
{
if (disposing)
{
repository.Dispose();
}
base.Dispose(disposing);
}
now i have the following questions about my current project:-
Based on my understanding on how Dispose works, is that when an action method calls a View, then asp.net mvc will automatically calls the Dispose method inside my current Controller class. which in turn calls the Dispose method inside my repository , which will make sure that the database connection is closed. so is my understanding valid ?
in my case do i need to have a Dispose method inside my APIRepository() , which as i mentioned this repository only have WebClient() calls to integrate with 3rd party application, and it will return object or simple string to the action method.??
what are the operations that need to be Disposed? as i know calling a my.Dispose(); inside my repository class will make sure that the database connection is closed.. but are there other operations that need to be disposed? such as initiating a WebClient() or returning a JSON by my action method?
what are the actions other than returning a View will call the Dispose method inside my Controller class ?
If you use dependency injection then none of the classes would be responsible for creating or disposing the dependencies injected into it.
Instead of this:
public class ServerController : Controller
{
Repository repository = new Repository();
APIRepository APIrepository = new APIRepository();
where ServerController creates its dependencies and is responsible for disposing of them, this:
public class ServerController : Controller
{
private readonly Repository _repository;
private readonly APIRepository _apiRepository;
public ServerController(Repository repository, APIRepository apiRepository)
{
_repository = repository;
_apiRepository = apiRepository;
}
Now whatever creates an instance of ServerController is responsible for instantiating those objects and disposing of them. That "whatever" is typically your dependency injection container, like Windsor or Unity. Or even better, in ASP.NET Core it's built in and you don't need to add a separate container.
The short version: The container creates your repository, and if it needs to be disposed, it disposes it. You can even specify details about the lifetime of certain dependencies. If it's not disposable and can be reused then it's a singleton. You can create and dispose a new instance every time you need one. Or you can create a new instance that's tied to a given web request. That request uses it and then it's disposed.
which will make sure that the database connection is closed. so is my understanding valid ?
Your database connection is closed way before the dispose method is called. It would be a very rare circumstance that it is not.
in my case do i need to have a Dispose method inside my APIRepository()
Only if you are managing the disposable of objects at field level instead of a method level.
// The method is disposing of the object
public class NotDisposable
{
public string GetString()
{
string result;
// This is disposed by the time the method exists.
using(var disposable new Disposable)
{
result = disposable.GetString()
}
return result;
}
}
// This class has a field that it needs to dispose
// so it inherites from IDisposable
public class Disposable : IDisposable
{
private bool _isDisposed;
private readonly IDisposable _somethingToManuallyDispose;
public Disposable()
{
somethingToManuallyDispose = new SomethingImplementsIDisposable();
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposing && !_isDisposed)
{
_isDisposed = true;
// Dispose Managed Resources
if (_somethingToManuallyDispose != null)
{
_somethingToManuallyDispose.Dispose();
}
}
}
}
but are there other operations that need to be disposed?
Example above, where you do not Dispose of an object in the method.
what are the actions other than returning a View will call the Dispose method inside my Controller class
That sentence doesn't even make sense. Returning a View does not call Dispose. The MVC/API Pipeline Disposes of the controller after the response is sent to the client, and only if it implements IDisposable.
Please consider reading MSDN - Dispose Pattern and MSDN - Implementing a Dispose Method and MSDN - Using Objects That Implement IDisposable.

Disposable Request-scoped object

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?

Auto Dispose Sql Connections properly

My application is using 3 layers: DAL / Service / UL.
My typical DAL class looks like this:
public class OrdersRepository : IOrdersRepository, IDisposable
{
private IDbConnection _db;
public OrdersRepository(IDbConnection db) // constructor
{
_db = db;
}
public void Dispose()
{
_db.Dispose();
}
}
My service calls the DAL class like this (injecting a database connection):
public class ordersService : IDisposable
{
IOrdersRepository _orders;
public ordersService() : this(new OrdersRepository(new Ajx.Dal.DapperConnection().getConnection()))
{
}
public ordersService(OrdersRepository ordersRepo)
{
_orders = ordersRepo;
}
public void Dispose()
{
_orders.Dispose();
}
}
And then finally within my UI layer, this is how I access my service layer:
public class OrdersController : Controller, IDisposable
{
//
// GET: /Orders/
private ordersService _orderService;
public OrdersController():this(new ordersService())
{
}
public OrdersController(ordersService o)
{
_orderService = o;
}
void IDisposable.Dispose()
{
_orderService.Dispose();
}
}
This all works good. But as you can see, I am relying on IDisposable within every layer. UI disposes service object and then service object disposes DAL object and then DAL object disposes the database connection object.
I am sure there has to be a better way of doing it. I am afraid users can forget to dispose my service object (within UI) and I will end up with many open database connections or worse. Please advise the best practice. I need a way to auto-dispose my database connections OR any other unmanaged resources (files etc).
Your question comes back to the principle of ownership:
he who has ownership of the resource, should dispose it.
Although ownership can be transferred, you should usually not do this. In your case the ownership of the IDbConnection is transferred from the ordersService to the OrdersRepository (since OrdersRepository disposes the connection). But in many cases the OrdersRepository can't know whether the connection can be disposed. It can be reused throughout the object graph. So in general, you should not dispose objects that are passed on to you through the constructor.
Another thing is that the consumer of a dependency often can't know if a dependency needs disposal, since whether or not a dependency needs to be disposed is an implementation detail. This information might not be available in the interface.
So instead, refactor your OrdersRepository to the following:
public class OrdersRepository : IOrdersRepository {
private IDbConnection _db;
public OrdersRepository(IDbConnection db) {
_db = db;
}
}
Since OrdersRepository doesn't take ownership, IDbConnection doesn't need to dispose IDbConnection and you don't need to implement IDisposable. This explicitly moves the responsibility of disposing the connection to the OrdersService. However, ordersService by itself doesn't need IDbConnection as a dependency; it just depends on IOrdersRepository. So why not move the responsibility of building up the object graph out of the OrdersService as well:
public class OrdersService : IDisposable {
private readonly IOrdersRepository _orders;
public ordersService(IOrdersRepository ordersRepo) {
_orders = ordersRepo;
}
}
Since ordersService has nothing to dispose itself, there's no need to implement IDisposable. And since it now has just a single constructor that takes the dependencies it requires, the class has become much easier to maintain.
So this moves the responsibility of creating the object graph to the OrdersController. But we should apply the same pattern to the OrdersController as well:
public class OrdersController : Controller {
private ordersService _orderService;
public OrdersController(ordersService o) {
_orderService = o;
}
}
Again, this class has become much easier to grasp and it doesn't needs to dispose anything, since it doesn't has or took ownership of any resource.
Of course we just moved and postponed our problems, since obviously we still need to create our OrdersController. But the difference is that we now moved the responsiblity of building up object graphs to a single place in the application. We call this place the Composition Root.
Dependency Injection frameworks can help you making your Composition Root maintainable, but even without a DI framework, you build your object graph quite easy in MVC by implementing a custom ControllerFactory:
public class CompositionRoot : DefaultControllerFactory {
protected override IController GetControllerInstance(
RequestContext requestContext, Type controllerType) {
if (controllerType == typeof(OrdersController)) {
var connection = new Ajx.Dal.DapperConnection().getConnection();
return new OrdersController(
new OrdersService(
new OrdersRepository(
Disposable(connection))));
}
else if (...) {
// other controller here.
}
else {
return base.GetControllerInstance(requestContext, controllerType);
}
}
public static void CleanUpRequest() }
var items = (List<IDisposable>)HttpContext.Current.Items["resources"];
if (items != null) items.ForEach(item => item.Dispose());
}
private static T Disposable<T>(T instance)
where T : IDisposable {
var items = (List<IDisposable>)HttpContext.Current.Items["resources"];
if (items == null) {
HttpContext.Current.Items["resources"] =
items = new List<IDisposable>();
}
items.Add(instance);
return instance;
}
}
You can hook your custom controller factory in the Global asax of your MVC application like this:
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
ControllerBuilder.Current.SetControllerFactory(
new CompositionRoot());
}
protected void Application_EndRequest(object sender, EventArgs e)
{
CompositionRoot.CleanUpRequest();
}
}
Of course, this all becomes much easier when you use a Dependency Injection framework. For instance, when you use Simple Injector (I'm the lead dev for Simple Injector), you can replace all of this with the following few lines of code:
using SimpleInjector;
using SimpleInjector.Integration.Web;
using SimpleInjector.Integration.Web.Mvc;
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
var container = new Container();
container.RegisterPerWebRequest<IDbConnection>(() =>
new Ajx.Dal.DapperConnection().getConnection());
container.Register<IOrdersRepository, OrdersRepository>();
container.Register<IOrdersService, OrdersService>();
container.RegisterMvcControllers(Assembly.GetExecutingAssembly());
container.Verify();
DependencyResolver.SetResolver(
new SimpleInjectorDependencyResolver(container));
}
}
There are a few interesting things going on in the code above. First of all, the calls to Register tell Simple Injector that they need to return a certain implementation should be created when the given abstraction is requested. Next, Simple Injector allows registering types with the Web Request Lifestyle, which makes sure that the given instance is disposed when the web request ends (just as we did in the Application_EndRequest). By calling RegisterMvcControllers, Simple Injector will batch-register all Controllers for you. By supplying MVC with the SimpleInjectorDependencyResolver we allow MVC to route the creation of controllers to Simple Injector (just as we did with the controller factory).
Although this code might be a bit harder to understand at first, the use of a Dependency Injection container becomes really valuable when your application starts to grow. A DI container will help you keeping your Composition Root maintainable.
Well, if you're really paranoid about that you can use the finalizer (destructor) to automatically execute the Dispose when the object is being garbage collected. Check this link which explains basically all you need to know about IDisposable, skip to the Examples section if just want a quick sample how to do that. The finalizer(destructor) is the ~MyResource() method.
But any way, you should always encourage the consumers of your libraries to use correctly the Dispose. The automatic cleaning up, by means of garbage collector still presents flaws. You don't know when the garbage collector will do its job, so if you get lots of these classes instantiated and used, then forgotten, in a short time, you may still be in trouble.

Should Dispose methods be unit tested?

I am using C#. Is it advised to unit test dispose methods? If so why, and how should one test these methods?
Yes, but it might be hard. There are two things that can generally happen in Dispose implementation:
Unmanaged resources are released.
In this case it's pretty hard to verify that the code called, for example, Marshal.Release. A possible solution is to inject an object that can do the disposing and pass a mock to it during testing. Something to this effect:
interface ComObjectReleaser {
public virtual Release (IntPtr obj) {
Marshal.Release(obj);
}
}
class ClassWithComObject : IDisposable {
public ClassWithComObject (ComObjectReleaser releaser) {
m_releaser = releaser;
}
// Create an int object
ComObjectReleaser m_releaser;
int obj = 1;
IntPtr m_pointer = Marshal.GetIUnknownForObject(obj);
public void Dispose() {
m_releaser.Release(m_pointer);
}
}
//Using MOQ - the best mocking framework :)))
class ClassWithComObjectTest {
public DisposeShouldReleaseComObject() {
var releaserMock = new Mock<ComObjectReleaser>();
var target = new ClassWithComObject(releaserMock);
target.Dispose();
releaserMock.Verify(r=>r.Dispose());
}
}
Other classes' Dispose method is called
The solution to this might not be as simple as above. In most cases, implementation of Dispose is not virtual, so mocking it is hard.
One way is to wrap up those other objects in a mockable wrapper, similar to what System.Web.Abstractions namespace does for HttpContext class - i.e. defines HttpContextBase class with all virtual methods that simply delegates method calls to the real HttpContext class.
For more ideas on how to do something like that have a look at System.IO.Abstractions project.
Certainly can't hurt. Client code may try to use an object of your class after it has disposed of it. If your class is composed of other IDisposable objects, you should always be throwing the ObjectDisposedException exception if it is in a state which it is no longer usable.
Of course, you should only be testing the external state of your object. In the example below, I've made the property Disposed external to give me the state.
Consider:
internal class CanBeDisposed : IDisposable
{
private bool disposed;
public bool Disposed
{
get
{
if (!this.disposed)
return this.disposed;
throw new ObjectDisposedException("CanBeDisposed");
}
}
public void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing)
{
//// Dispose of managed resources.
}
//// Dispose of unmanaged resources.
this.disposed = true;
}
}
}
So how I would test this is thus:
CanBeDisposed cbd;
using (cbd = new CanBeDisposed())
{
Debug.Assert(!cbd.Disposed); // Best not be disposed yet.
}
try
{
Debug.Assert(cbd.Disposed); // Expecting an exception.
}
catch (Exception ex)
{
Debug.Assert(ex is ObjectDisposedException); // Better be the right one.
}
If your class creates and works with unmanaged resources, then you should definitely ensure that Dispose works as you expect it to - although it could be argued it is more of an integration test due to the type of hoops you're going to have to jump through.
If your class only creates / uses managed resources ( i.e. they implement IDisposable ) then all you really need to ensure is that the Dispose method on these resources is invoked at the correct time - if you are using some form of DI then you can inject a mock and assert that Dispose was called.
Look at the complexity of your dispose methods - if they are only a couple of lines long with maybe 1 condition, ask yourself if there really is a benefit in unit testing them.
Big yes - if your situation requires you to implement a Dispose function - you better make sure it does what you think!
For example, we have classes that coordinate database tasks (think SSIS packages, but with SqlConnection and SqlCommand and SqlBulkCopy etc.).
If I don't properly implement my Dispose, I could have an uncommitted SqlTransaction, or dangling SqlConnection. This would be VERY bad if I were running multiple instances of these database tasks in series.
As a practical tip (because yes, you should test Dispose()) my experience has been that there are two ways to do so without too much hassle.
IDisposer
The first follows Igor's accepted answer - inject something like an IDisposer, so that you can call
public void Dispose()
{
_disposer.Release(_disposable);
}
where
public interface IDisposer
{
void Release(IDisposable disposable);
}
Then all you need to do is mock the IDisposer and assert that it's called once and you're golden.
Factory
The second, and my personal favourite, is to have a factory that creates the thing you need to test disposal of. This only works when the factory produces a mockable type (interface, abstract class), but hey, that's almost always the case, especially for something that's to be disposed. For testing purposes, mock the factory but have it produce a mock implementation of the thing you want to test disposal of. Then you can assert calls to Dispose directly on your mock. Something along the lines of
public interface IFooFactory
{
IFoo Create(); // where IFoo : IDisposable
}
public class MockFoo : IFoo
{
// ugly, use something like Moq instead of this class
public int DisposalCount { get; privat set; }
public void Dispose()
{
DisposalCount++;
}
}
public class MockFooFactory
{
public MockFoo LatestFoo { get; private set; }
public IFoo Create()
{
LatestFoo = new MockFoo();
return LatestFoo;
}
}
Now you can always ask the factory (which will be available in your test) to give you the latest MockFoo, then you dispose of the outer thing and check that DisposalCount == 1 (although you should use a test framwork instead, e.g. Moq).

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