My Controllers inherit from a class that contains a field that implements IDisposable. So my first instinct was to write:
public abstract class EventRepositoryControllerBase : Controller
{
protected EventRepository eventRepos { get; private set; }
public EventRepositoryControllerBase(EventRepository eventRepos)
{
this.eventRepos = eventRepos;
}
public override void Dispose()
{
try
{
base.Dispose();
}
finally
{
eventRepos.Dispose();
}
}
}
but this won’t compile because Controller does not mark the Dispose method as virtual/override. So now I think I’m stuck. Even if I mark my method as new, won’t the framework hold references typed as Controller and as such my method will never be invoked? Suggestions on how to work around this?
UPDATE
So I looked at the MVC3 source and saw this:
public void Dispose() {
Dispose(true /* disposing */);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing) {
}
So I guess I’ll just put my code in the 2nd method. Not sure that this behavior is contractually specified though.
If
IDisposable.Disposewere implemented with an unsealed method, then the code for derived types would run before and after the base-type cleanup code; sinceGC.SuppressFinalizeshouldn’t be called until after a derived type has finished its cleanup (including any portions that should perhaps occur after the base type has finished its cleanup), theGC.SuppressFinalizeis made in a sealed implementation which in turn calls a virtual method whose signature isvoid Dispose(bool).Note that while conceptually it is a good idea to have a virtual method called within a sealed wrapper, there are some flaws in Microsoft’s implementation. Most notably:
Microsoft’s `Dispose` pattern provides no means of distinguishing among the latter two choices. While leaving an object registered for finalization-based cleanup might in many cases be harmless, it could cause confusion if the `Finalize` method is used to log failures to call `Dispose`.
Back before Microsoft had figured out the best ways to handle unmanaged resources, the
Disposepattern was a good first effort. Today, I would think it better to regard the virtual method’s parameter as being a dummy parameter used to change the signature, than as something meaningful (even though one should always passTruewhen chaining the virtual method from the wrapper).