The Guard Pattern meets IDisposable
September 13, 2007The Guard is a very handy design pattern, which is traditionally used in languages with deterministic destruction like C++.
The concept is pretty simple:
The guard class encapsulates some resource which is initialized in its constructor and is released in its destructor.
The guard object lives in a dedicated scope and has a short lifetime during which it guards some other piece of code. This concept of guarding is a very abstract pattern and can be used in a broad range of scenarios where some kind of temporary resources (mutexes, file handles, database connections, registry values,) are allocated.
// The guard's scope
{
// The guard allocates some resource in its constructor.
SomeGuard guard;
//
// The "guarded" code follows ..,
//
}
// The guard goes out of scope and its resource is released.
As this sample demonstrates, the guard pattern heavily relies on deterministic destruction. So how can we leverage this pattern in C#? The answers to this question are the IDisposable interface and the using keyword. With these constructs the same functionality can easily be implemented:
// The guard allocates some resource in its constructor.
using (SomeGuard guard = new SomeGuard()) {
//
// The "guarded" code.
//
}
// The guard's dispose method is called
// and its resource is released.
As can be seen the guard pattern is nothing magical in a “silver-bullet” kind of way. Though the nice thing about it is how it takes complexity out of your code. The dedicated scope of the guard visualizes the control flow and lifetime of your resources nicely and makes your code far more readable. The allocation and finalization of the resources are implemented inside the guard class and do not interfere with the actual business logic.
The following sample demonstrates the TempFileGuard class which can be used in combination with temporary files and provides automatic allocation and cleanup of these temporary files.
Bitmap bmp = null;
// A temporary file is allocated here.
using (TempFileGuard guard = new TempFileGuard()) {
// Download a bitmap into this temporary file.
WebClient webclient = new WebClient();
webclient.DownloadFile(uri, guard.FullName);
bmp = new Bitmap(guard.FullName);
}
// The TempFileGuard object gets disposed and the temporary
// file is removed automatically.