Ppdac.Cache.Maui 1.0.2

dotnet add package Ppdac.Cache.Maui --version 1.0.2                
NuGet\Install-Package Ppdac.Cache.Maui -Version 1.0.2                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Ppdac.Cache.Maui" Version="1.0.2" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Ppdac.Cache.Maui --version 1.0.2                
#r "nuget: Ppdac.Cache.Maui, 1.0.2"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install Ppdac.Cache.Maui as a Cake Addin
#addin nuget:?package=Ppdac.Cache.Maui&version=1.0.2

// Install Ppdac.Cache.Maui as a Cake Tool
#tool nuget:?package=Ppdac.Cache.Maui&version=1.0.2                


This library allows one to save bandwidth or API calls by caching images locally in a cache folder.

Video Demonstration

Demonstration GIF showing load times.

Notice the instant load times for this CollectionView of web images.

For .NET MAUI apps, the location of this folder is decided by FileSystem.CacheDirectory, and for .NET 6.0 Windows apps, it is decided by Environment.SpecialFolder.ApplicationData.

This version for .NET MAUI apps adds a new method to the ImageCache class, GetAsImageSourceAsync(Uri uri), which returns an ImageSource instead of a Stream, byte[] or Func<Stream>. This is useful for binding to an Image control's Source property, which are often given a URI to a web resource.

In place of the URI, use GetAsImageSourceAsync(Uri uri) instead, which will remember if this URI has been cached before, and if so, return the cached image source instead of downloading it again.

Because it is derived from the general-purpose ImageCache class, it can also be used for other classes not specific to .NET MAUI, such as bitmaps, or other image types that can accept byte arrays or a Stream.


  • Files will go stale after 12 seconds by default. You can change this with the CacheExpiryInSeconds property.

  • You can always set the cache folder by its public property. For .NET MAUI apps, the default is the FileSystem.CacheDirectory folder, and for .NET 6.0 Windows apps, it is the Environment.SpecialFolder.ApplicationData folder.

  • Use the Purg() method to clear the cache, the GetAs...(Uri) methods to retrieve images, and GetByteCount(Uri) if you need to check a remote images' filesize.

  • Some methods will let you pass in a string URL for convenience, but using Uris is preferred.

  • The Save() method does not need to be called. It will make sure the list of tracked Uris are saved to the cache. You may want to call if if you use Clear() on the list.

  • The Restore() method is obsolete, and does not need to be called.


Dependency Injection

Use this class to cache images from the Internet. Its functions receive a URI and turn the resource into an ImageSource, byte array, Stream, or Func‹Stream›. Where ever you would give a control a URL, a stream, or byte[], do so as normal, but have ImageCache sit in the middle. For example, in .NET MAUI:

// MauiProgram.cs:

Then use Dependency Injection to gain access to the class of a view, viewmodel, page or control. Assume a viewmodel has Collection‹Image› Images that will be used in a template:

Using Ppdac.ImageCache.Maui;
ImageCache _imageCache;
Page(ViewModel viewModel, ImageCache imageCache)
	_imageCache = imageCache;
	foreach (Image image in viewModel.Images)
		Image.Source = _imageCache.GetImageAsImageSource(image.Url);
	Stream imageStream = await _imageCache.GetImageAsStreamAsync(image.Url);
	Bitmap bitmap = new(imageStream);
	byte[] imageBytes = await _imageCache.GetImageAsBytesAsync(image.Url);

Helper Helping Out However Examples

With the flexible IImage:

		Microsoft.Maui.Graphics.IImage? image = new W2DImageLoadingService().FromStream(await _imageCache.GetAsStreamAsync(new Uri("https://example.com/e.jpg")));
		// Microsoft.Maui.Graphics.IImage? image = new W2DImageLoadingService().FromStream(_imageCache.GetAsStreamAsync(new Uri("https://example.com/e.jpg")).Result);
		Microsoft.Maui.Graphics.IImage image = PlatformImage.FromStream(_imageCache.GetAsStreamAsync(new Uri("https://example.com/e.jpg")).Result);

You have an Microsoft.Maui.Controls.Image that you currently pass a URL string into the Source property, instead of passing the string do something like:

Source = await ImageCache.GetAsImageSourceAsync("https://www.example.com/image.png");
// or ideally:
Source = await ImageCache.GetAsImageSourceAsync(new Uri("https://www.example.com/image.png"));

Or use the ImageSource type directly:

ImageSource imageSource = await ImageCache.GetAsImageSourceAsync(imageUri);
Microsoft.Maui.Controls.Image mmcImage = new Microsoft.Maui.Controls.Image
	Source = imageSource

It also works with controls that expect a byte array or stream, System.Drawing.Image, or the Bitmap class:

System.Drawing.Bitmap sdBitmap = new Bitmap(await _imageStore.GetAsStreamAsync(uri));

// If you prefer synchronous methods:
System.Drawing.Image sdImage = System.Drawing.Image.FromStream(_imageStore.GetAsStreamAsync(uri).Result);

// Or just set up your byte array, and you can use these anywhere!
byte[] imageBytes = await _imageStore.GetAsByteArrayAsync(uri);

As you can see, you are simply establishing a source for the image, but having a helper function sit right in the middle.

Other Usage

You may only want to use it on certain pages. There are several ways to do this, including with dependcy injection, as well as changing the default cache folder to whatever you like:

// Page A
_imageCache.ImageCachePath = nameof(MyPage);

// Page B
_imageCacheB.ImageCachePath = nameof(MyOtherPage);

Though, DI is probably the best way to do this, injecting the class into the desired page.


You are actively encouraged to report bugs and contribute to this repository

Contributions Are Appreciated and Welcome

Bugs and Issues

Product Compatible and additional computed target framework versions.
.NET net7.0 is compatible.  net7.0-android was computed.  net7.0-android33.0 is compatible.  net7.0-ios was computed.  net7.0-ios16.1 is compatible.  net7.0-maccatalyst was computed.  net7.0-maccatalyst16.1 is compatible.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net7.0-windows10.0.17763 is compatible.  net7.0-windows10.0.19041 is compatible.  net7.0-windows10.0.22000 is compatible.  net7.0-windows10.0.22621 is compatible.  net8.0 is compatible.  net8.0-android was computed.  net8.0-android34.0 is compatible.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-ios17.0 is compatible.  net8.0-maccatalyst was computed.  net8.0-maccatalyst17.0 is compatible.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net8.0-windows10.0.17763 is compatible.  net8.0-windows10.0.19041 is compatible.  net8.0-windows10.0.22000 is compatible.  net8.0-windows10.0.22621 is compatible. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
1.0.2 208 11/30/2023
1.0.0 103 11/30/2023

This version adds the CacheExpiryInSeconds property (12 seconds default) so you can control when files automatically go stale.