I would suggest two changes:
Most of the DirectoryCache
code is trivially cross-platform and usable in MonoTouch/desktop .NET/etc.; the Bitmap dependency isn't required. There are only two members that use Bitmap -- AddOrUpdate() and TryGet() -- and a Bitmap isn't required; they could instead take/provide a Stream.
Instead, I would suggest making it a strict cache management type for storing "blobs" (Stream
s) of data, and let higher-level logic deal with what the blobs are (Bitmaps
, databases, etc.):
partial class DirectoryCache {
// Replaces: AddOrUpdate(string,Bitmap,TimeSpan)
public void AddOrUpdate (string key, Stream stream, TimeSpan? duration = null);
// Replaces: TryGet(string, out Bitmap)
public void WithEntryPath (string key, Action<string> action)
{
key = SanitizeKey (key);
lock (entries) {
if (!entries.ContainsKey (key))
return;
action (Path.Combine (basePath, key));
}
}
}
When it comes to Bitmap
s and other large Java-side objects, you want to keep the Bitmap
C# instance lifetime as short as possible. There are two ways to do this:
-
Rely on the user to do it:
using (var bitmap = SomeMethodThatReturnsABitmap ()) DoSomethingWith(bitmap);
This works, but requires "overhead" on consuming code. Furthermore, this isn't possible with the original
DirectoryCache.TryGet()
method, which would require that the caller explicitly call.Dispose()
. -
Do it for them by requiring use of a closure.
This can be done with an extension method in terms of the above
DirectoryCache.WithEntryPath()
method:public static void WithBitmap(this DirectoryCache cache, string key, Action<Bitmap> action) { cache.WithEntryPath(key, path => { using (var bitmap = BitmapFactory.DecodeFile (path)) action (bitmap); }); } // ... cache.WithBitmap ("name", bitmap => widget.SetBackgroundBitmap(bitmap));
Personally, I'd suggest (2).