diff --git a/src/ImageProcessor.Web.AzureBlobCache/AzureBlobCache.cs b/src/ImageProcessor.Web.AzureBlobCache/AzureBlobCache.cs
index dc6e1a74c..6bda004f3 100644
--- a/src/ImageProcessor.Web.AzureBlobCache/AzureBlobCache.cs
+++ b/src/ImageProcessor.Web.AzureBlobCache/AzureBlobCache.cs
@@ -1,4 +1,15 @@
-namespace ImageProcessor.Web.Caching
+// --------------------------------------------------------------------------------------------------------------------
+//
+// Copyright (c) James South.
+// Licensed under the Apache License, Version 2.0.
+//
+//
+// Provides an implementation that uses Azure blob storage.
+// The cache is self healing and cleaning.
+//
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace ImageProcessor.Web.Caching
{
using System;
using System.Collections.Generic;
@@ -15,54 +26,72 @@
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Blob;
+ ///
+ /// Provides an implementation that uses Azure blob storage.
+ /// The cache is self healing and cleaning.
+ ///
public class AzureBlobCache : ImageCacheBase
{
///
- /// The max age.
+ /// The maximum number of days to store the image.
///
private readonly int maxDays;
- private CloudStorageAccount cloudCachedStorageAccount;
-
- private CloudStorageAccount cloudSourceStorageAccount;
-
- private CloudBlobClient cloudCachedBlobClient;
-
- private CloudBlobClient cloudSourceBlobClient;
-
- private CloudBlobContainer cloudCachedBlobContainer;
+ ///
+ /// The cloud cached blob container.
+ ///
+ private readonly CloudBlobContainer cloudCachedBlobContainer;
- private CloudBlobContainer cloudSourceBlobContainer;
+ ///
+ /// The cloud source blob container.
+ ///
+ private readonly CloudBlobContainer cloudSourceBlobContainer;
- private string cachedCDNRoot;
+ ///
+ /// The cached root url for a content delivery network.
+ ///
+ private readonly string cachedCdnRoot;
+ ///
+ /// The cached rewrite path.
+ ///
private string cachedRewritePath;
///
- /// The physical cached path.
+ /// Initializes a new instance of the class.
///
- private string physicalCachedPath;
-
+ ///
+ /// The request path for the image.
+ ///
+ ///
+ /// The full path for the image.
+ ///
+ ///
+ /// The querystring containing instructions.
+ ///
public AzureBlobCache(string requestPath, string fullPath, string querystring)
: base(requestPath, fullPath, querystring)
{
this.maxDays = Convert.ToInt32(this.Settings["MaxDays"]);
// Retrieve storage accounts from connection string.
- this.cloudCachedStorageAccount = CloudStorageAccount.Parse(this.Settings["CachedStorageAccount"]);
- this.cloudSourceStorageAccount = CloudStorageAccount.Parse(this.Settings["SourceStorageAccount"]);
+ CloudStorageAccount cloudCachedStorageAccount = CloudStorageAccount.Parse(this.Settings["CachedStorageAccount"]);
+ CloudStorageAccount cloudSourceStorageAccount = CloudStorageAccount.Parse(this.Settings["SourceStorageAccount"]);
// Create the blob clients.
- this.cloudCachedBlobClient = this.cloudCachedStorageAccount.CreateCloudBlobClient();
- this.cloudSourceBlobClient = this.cloudSourceStorageAccount.CreateCloudBlobClient();
+ CloudBlobClient cloudCachedBlobClient = cloudCachedStorageAccount.CreateCloudBlobClient();
+ CloudBlobClient cloudSourceBlobClient = cloudSourceStorageAccount.CreateCloudBlobClient();
// Retrieve references to a previously created containers.
- this.cloudCachedBlobContainer = this.cloudCachedBlobClient.GetContainerReference(this.Settings["CachedBlobContainer"]);
- this.cloudSourceBlobContainer = this.cloudSourceBlobClient.GetContainerReference(this.Settings["SourceBlobContainer"]);
+ this.cloudCachedBlobContainer = cloudCachedBlobClient.GetContainerReference(this.Settings["CachedBlobContainer"]);
+ this.cloudSourceBlobContainer = cloudSourceBlobClient.GetContainerReference(this.Settings["SourceBlobContainer"]);
- this.cachedCDNRoot = this.Settings["CachedCDNRoot"];
+ this.cachedCdnRoot = this.Settings["CachedCDNRoot"];
}
+ ///
+ /// Gets the maximum number of days to store the image.
+ ///
public override int MaxDays
{
get
@@ -71,6 +100,12 @@
}
}
+ ///
+ /// Gets a value indicating whether the image is new or updated in an asynchronous manner.
+ ///
+ ///
+ /// The asynchronous returning the value.
+ ///
public override async Task IsNewOrUpdatedAsync()
{
string cachedFileName = await this.CreateCachedFileName();
@@ -79,7 +114,7 @@
// That gives us massive scope to store millions of files.
string pathFromKey = string.Join("\\", cachedFileName.ToCharArray().Take(6));
this.CachedPath = Path.Combine(this.cloudCachedBlobContainer.Uri.ToString(), pathFromKey, cachedFileName).Replace(@"\", "/");
- this.cachedRewritePath = Path.Combine(this.cachedCDNRoot, this.cloudCachedBlobContainer.Name, pathFromKey, cachedFileName).Replace(@"\", "/");
+ this.cachedRewritePath = Path.Combine(this.cachedCdnRoot, this.cloudCachedBlobContainer.Name, pathFromKey, cachedFileName).Replace(@"\", "/");
bool isUpdated = false;
CachedImage cachedImage = CacheIndexer.GetValue(this.CachedPath);
@@ -147,18 +182,36 @@
return isUpdated;
}
+ ///
+ /// Adds the image to the cache in an asynchronous manner.
+ ///
+ ///
+ /// The stream containing the image data.
+ ///
+ ///
+ /// The content type of the image.
+ ///
+ ///
+ /// The representing an asynchronous operation.
+ ///
public override async Task AddImageToCacheAsync(Stream stream, string contentType)
{
string blobPath = this.CachedPath.Substring(this.cloudCachedBlobContainer.Uri.ToString().Length + 1);
CloudBlockBlob blockBlob = this.cloudCachedBlobContainer.GetBlockBlobReference(blobPath);
await blockBlob.UploadFromStreamAsync(stream);
-
+
blockBlob.Properties.ContentType = contentType;
blockBlob.Properties.CacheControl = string.Format("public, max-age={0}", this.MaxDays * 86400);
await blockBlob.SetPropertiesAsync();
}
+ ///
+ /// Trims the cache of any expired items in an asynchronous manner.
+ ///
+ ///
+ /// The asynchronous representing an asynchronous operation.
+ ///
public override async Task TrimCacheAsync()
{
Uri uri = new Uri(this.CachedPath);
@@ -197,6 +250,12 @@
}
}
+ ///
+ /// Gets a string identifying the cached file name.
+ ///
+ ///
+ /// The asynchronous returning the value.
+ ///
public override async Task CreateCachedFileName()
{
string streamHash = string.Empty;
@@ -260,6 +319,12 @@
return cachedFileName;
}
+ ///
+ /// Rewrites the path to point to the cached image.
+ ///
+ ///
+ /// The encapsulating all information about the request.
+ ///
public override void RewritePath(HttpContext context)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(this.cachedRewritePath);
diff --git a/src/ImageProcessor.Web/Caching/DiskCache.cs b/src/ImageProcessor.Web/Caching/DiskCache.cs
index 451183526..e02cd4e24 100644
--- a/src/ImageProcessor.Web/Caching/DiskCache.cs
+++ b/src/ImageProcessor.Web/Caching/DiskCache.cs
@@ -1,4 +1,15 @@
-namespace ImageProcessor.Web.Caching
+// --------------------------------------------------------------------------------------------------------------------
+//
+// Copyright (c) James South.
+// Licensed under the Apache License, Version 2.0.
+//
+//
+// Provides an implementation that is file system based.
+// The cache is self healing and cleaning.
+//
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace ImageProcessor.Web.Caching
{
using System;
using System.Collections.Generic;
@@ -9,9 +20,12 @@
using System.Web;
using System.Web.Hosting;
- using ImageProcessor.Web.Configuration;
using ImageProcessor.Web.Extensions;
+ ///
+ /// Provides an implementation that is file system based.
+ /// The cache is self healing and cleaning.
+ ///
public class DiskCache : ImageCacheBase
{
///
@@ -27,7 +41,7 @@
private const int MaxFilesCount = 100;
///
- /// The max age.
+ /// The maximum number of days to store the image.
///
private readonly int maxDays;
@@ -42,7 +56,7 @@
private readonly string absoluteCachePath;
///
- /// The virtual cached path to the cached file.
+ /// The virtual path to the cached file.
///
private string virtualCachedFilePath;
@@ -75,8 +89,7 @@
}
///
- /// The maximum number of days to cache files on the system for.
- /// TODO: Shift the getter source to proper config.
+ /// Gets the maximum number of days to store the image.
///
public override int MaxDays
{
@@ -86,6 +99,12 @@
}
}
+ ///
+ /// Gets a value indicating whether the image is new or updated in an asynchronous manner.
+ ///
+ ///
+ /// The .
+ ///
public override async Task IsNewOrUpdatedAsync()
{
string cachedFileName = await this.CreateCachedFileName();
@@ -138,6 +157,18 @@
return isUpdated;
}
+ ///
+ /// Adds the image to the cache in an asynchronous manner.
+ ///
+ ///
+ /// The stream containing the image data.
+ ///
+ ///
+ /// The content type of the image.
+ ///
+ ///
+ /// The representing an asynchronous operation.
+ ///
public override async Task AddImageToCacheAsync(Stream stream, string contentType)
{
// ReSharper disable once AssignNullToNotNullAttribute
@@ -153,6 +184,12 @@
}
}
+ ///
+ /// Trims the cache of any expired items in an asynchronous manner.
+ ///
+ ///
+ /// The asynchronous representing an asynchronous operation.
+ ///
public override async Task TrimCacheAsync()
{
string directory = Path.GetDirectoryName(this.CachedPath);
@@ -198,6 +235,12 @@
}
}
+ ///
+ /// Rewrites the path to point to the cached image.
+ ///
+ ///
+ /// The encapsulating all information about the request.
+ ///
public override void RewritePath(HttpContext context)
{
// The cached file is valid so just rewrite the path.
diff --git a/src/ImageProcessor.Web/Caching/IImageCache.cs b/src/ImageProcessor.Web/Caching/IImageCache.cs
index 976d47012..9c9214824 100644
--- a/src/ImageProcessor.Web/Caching/IImageCache.cs
+++ b/src/ImageProcessor.Web/Caching/IImageCache.cs
@@ -1,4 +1,13 @@
-
+// --------------------------------------------------------------------------------------------------------------------
+//
+// Copyright (c) James South.
+// Licensed under the Apache License, Version 2.0.
+//
+//
+// Defines properties and methods for allowing caching of images to different sources.
+//
+// --------------------------------------------------------------------------------------------------------------------
+
namespace ImageProcessor.Web.Caching
{
using System.Collections.Generic;
@@ -6,6 +15,9 @@ namespace ImageProcessor.Web.Caching
using System.Threading.Tasks;
using System.Web;
+ ///
+ /// Defines properties and methods for allowing caching of images to different sources.
+ ///
public interface IImageCache
{
///
@@ -13,20 +25,60 @@ namespace ImageProcessor.Web.Caching
///
Dictionary Settings { get; set; }
+ ///
+ /// Gets the path to the cached image.
+ ///
string CachedPath { get; }
+ ///
+ /// Gets the maximum number of days to store the image.
+ ///
int MaxDays { get; }
+ ///
+ /// Gets a value indicating whether the image is new or updated in an asynchronous manner.
+ ///
+ ///
+ /// The asynchronous returning the value.
+ ///
Task IsNewOrUpdatedAsync();
+ ///
+ /// Adds the image to the cache in an asynchronous manner.
+ ///
+ ///
+ /// The stream containing the image data.
+ ///
+ ///
+ /// The content type of the image.
+ ///
+ ///
+ /// The representing an asynchronous operation.
+ ///
Task AddImageToCacheAsync(Stream stream, string contentType);
+ ///
+ /// Trims the cache of any expired items in an asynchronous manner.
+ ///
+ ///
+ /// The asynchronous representing an asynchronous operation.
+ ///
Task TrimCacheAsync();
+ ///
+ /// Gets a string identifying the cached file name.
+ ///
+ ///
+ /// The asynchronous returning the value.
+ ///
Task CreateCachedFileName();
+ ///
+ /// Rewrites the path to point to the cached image.
+ ///
+ ///
+ /// The encapsulating all information about the request.
+ ///
void RewritePath(HttpContext context);
-
- //void SetHeaders(HttpContext context);
}
}
diff --git a/src/ImageProcessor.Web/Caching/ImageCacheBase.cs b/src/ImageProcessor.Web/Caching/ImageCacheBase.cs
index b49602501..4a036a2f6 100644
--- a/src/ImageProcessor.Web/Caching/ImageCacheBase.cs
+++ b/src/ImageProcessor.Web/Caching/ImageCacheBase.cs
@@ -1,10 +1,20 @@
-namespace ImageProcessor.Web.Caching
+// --------------------------------------------------------------------------------------------------------------------
+//
+// Copyright (c) James South.
+// Licensed under the Apache License, Version 2.0.
+//
+//
+// The image cache base provides methods for implementing the interface.
+// It is recommended that any implementations inherit from this class.
+//
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace ImageProcessor.Web.Caching
{
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
- using System.Reflection;
using System.Threading.Tasks;
using System.Web;
@@ -12,6 +22,10 @@
using ImageProcessor.Web.Extensions;
using ImageProcessor.Web.Helpers;
+ ///
+ /// The image cache base provides methods for implementing the interface.
+ /// It is recommended that any implementations inherit from this class.
+ ///
public abstract class ImageCacheBase : IImageCache
{
///
@@ -54,16 +68,52 @@
///
public Dictionary Settings { get; set; }
- public string CachedPath { get; protected set; }
+ ///
+ /// Gets or sets the path to the cached image.
+ ///
+ public string CachedPath { get; set; }
+ ///
+ /// Gets the maximum number of days to store the image.
+ ///
public abstract int MaxDays { get; }
+ ///
+ /// Gets a value indicating whether the image is new or updated in an asynchronous manner.
+ ///
+ ///
+ /// The .
+ ///
public abstract Task IsNewOrUpdatedAsync();
+ ///
+ /// Adds the image to the cache in an asynchronous manner.
+ ///
+ ///
+ /// The stream containing the image data.
+ ///
+ ///
+ /// The content type of the image.
+ ///
+ ///
+ /// The representing an asynchronous operation.
+ ///
public abstract Task AddImageToCacheAsync(Stream stream, string contentType);
+ ///
+ /// Trims the cache of any expired items in an asynchronous manner.
+ ///
+ ///
+ /// The asynchronous representing an asynchronous operation.
+ ///
public abstract Task TrimCacheAsync();
+ ///
+ /// Gets a string identifying the cached file name.
+ ///
+ ///
+ /// The asynchronous returning the value.
+ ///
public virtual Task CreateCachedFileName()
{
string streamHash = string.Empty;
@@ -106,6 +156,12 @@
return Task.FromResult(cachedFileName);
}
+ ///
+ /// Rewrites the path to point to the cached image.
+ ///
+ ///
+ /// The encapsulating all information about the request.
+ ///
public abstract void RewritePath(HttpContext context);
///
diff --git a/src/ImageProcessor.Web/Services/IImageService.cs b/src/ImageProcessor.Web/Services/IImageService.cs
index dfdcf0cdc..c6c39f80f 100644
--- a/src/ImageProcessor.Web/Services/IImageService.cs
+++ b/src/ImageProcessor.Web/Services/IImageService.cs
@@ -4,7 +4,7 @@
// Licensed under the Apache License, Version 2.0.
//
//
-// Defines properties and methods for allowing retrieval of image from different sources.
+// Defines properties and methods for allowing retrieval of images from different sources.
//
// --------------------------------------------------------------------------------------------------------------------
@@ -15,7 +15,7 @@ namespace ImageProcessor.Web.Services
using System.Threading.Tasks;
///
- /// Defines properties and methods for allowing retrieval of image from different sources.
+ /// Defines properties and methods for allowing retrieval of images from different sources.
///
public interface IImageService
{
diff --git a/src/ImageProcessor.Web/Settings.StyleCop b/src/ImageProcessor.Web/Settings.StyleCop
index 09dd1de03..311872ed4 100644
--- a/src/ImageProcessor.Web/Settings.StyleCop
+++ b/src/ImageProcessor.Web/Settings.StyleCop
@@ -1,6 +1,7 @@
+ cdn
dllimport