James, All wrapper
can do is log it's own exceptions. You can't force the consumer of wrapper
to log their own exceptions. That's not what IDisposable is for. IDisposable is meant for semi-deterministic release of resources for an object. Writing correct IDisposable code is not trivial.
In fact, the consumer of the class isn't even required to call your classes dispose method, nor are they required to use a using block, so it all rather breaks down.
If you look at it from the point of view of the wrapper class, why should it care that it was present inside a using block and there was an exception? What knowledge does that bring? Is it a security risk to have 3rd party code privy to exception details and stack trace? What can wrapper
do if there is a divide-by-zero in a calculation?
The only way to log exceptions, irrespective of IDisposable, is try-catch and then to re-throw in the catch.
try
{
// code that may cause exceptions.
}
catch( Exception ex )
{
LogExceptionSomewhere(ex);
throw;
}
finally
{
// CLR always tries to execute finally blocks
}
You mention you're creating an external API. You would have to wrap every call at your API's public boundary with try-catch in order to log that the exception came from your code.
If you're writing a public API then you really ought to read Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries (Microsoft .NET Development Series) - 2nd Edition .. 1st Edition.
While I don't advocate them, I have seen IDisposable used for other interesting patterns:
- Auto-rollback transaction semantics. The transaction class would rollback the transaction on Dispose if not already committed.
- Timed code blocks for logging. During object creation a timestamp was recorded, and on Dispose the TimeSpan was calculated and a log event was written.
* These patterns can be achieved with another layer of indirection and anonymous delegates easily and without having to overload IDisposable semantics. The important note is that your IDisposable wrapper is useless if you or a team member forget to use it properly.