diff --git a/.gitignore b/.gitignore
index 6178c90d3..a39e0d3a0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -65,7 +65,7 @@ local.properties
**/*.dotCover
## TODO: If you have NuGet Package Restore enabled, uncomment this
-**/packages/
+src/packages/
# Visual C++ cache files
ipch/
diff --git a/src/ImageProcessor.Web/NET4/ImageProcessor.Web.csproj b/src/ImageProcessor.Web/NET4/ImageProcessor.Web.csproj
index c5ff34b28..29e5f62f8 100644
--- a/src/ImageProcessor.Web/NET4/ImageProcessor.Web.csproj
+++ b/src/ImageProcessor.Web/NET4/ImageProcessor.Web.csproj
@@ -65,6 +65,7 @@
..\..\packages\Microsoft.Bcl.1.0.19\lib\net40\System.Runtime.dll
+ ..\..\packages\Microsoft.Bcl.1.0.19\lib\net40\System.Threading.Tasks.dll
@@ -73,14 +74,21 @@
+
+ CacheManager.cs
+
+
+ CleanupImage.cs
+
-
+
+ MemoryCache.cs
+
-
diff --git a/src/ImageProcessor.Web/NET45/Caching/CacheManager.cs b/src/ImageProcessor.Web/NET45/Caching/CacheManager.cs
new file mode 100644
index 000000000..0e1e517b5
--- /dev/null
+++ b/src/ImageProcessor.Web/NET45/Caching/CacheManager.cs
@@ -0,0 +1,231 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// Copyright (c) James South.
+// Licensed under the Apache License, Version 2.0.
+//
+//
+// Encapsulates methods that allow the caching and retrieval of objects.
+//
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace ImageProcessor.Web.Caching
+{
+ #region Using
+ using System;
+ using System.Collections.Generic;
+ using System.Runtime.Caching;
+ #endregion
+
+ ///
+ /// Encapsulates methods that allow the caching and retrieval of objects.
+ ///
+ public static class CacheManager
+ {
+ #region Fields
+ ///
+ /// The cache
+ ///
+ private static readonly ObjectCache Cache = System.Runtime.Caching.MemoryCache.Default;
+
+ ///
+ /// An internal list of cache keys to allow bulk removal.
+ ///
+ private static readonly Dictionary CacheItems = new Dictionary();
+ #endregion
+
+ #region Methods
+ ///
+ /// Adds an item to the cache.
+ ///
+ ///
+ /// A unique identifier for the cache entry.
+ ///
+ ///
+ /// The object to insert.
+ ///
+ ///
+ /// Optional. An object that contains eviction details for the cache entry. This object
+ /// provides more options for eviction than a simple absolute expiration. The default value for the optional parameter
+ /// is null.
+ ///
+ ///
+ /// Optional. A named region in the cache to which the cache entry can be added,
+ /// if regions are implemented. The default value for the optional parameter
+ /// is null.
+ ///
+ ///
+ /// True if the insertion try succeeds, or false if there is an already an entry
+ /// in the cache with the same key as key.
+ ///
+ public static bool AddItem(string key, object value, CacheItemPolicy policy = null, string regionName = null)
+ {
+ bool isAdded;
+
+ lock (Cache)
+ {
+ if (policy == null)
+ {
+ // Create a new cache policy with the default values
+ policy = new CacheItemPolicy();
+ }
+
+ isAdded = Cache.Add(key, value, policy, regionName);
+
+ if (isAdded)
+ {
+ CacheItems.Add(key, regionName);
+ }
+ }
+
+ return isAdded;
+ }
+
+ ///
+ /// Fetches an item matching the given key from the cache.
+ ///
+ ///
+ /// A unique identifier for the cache entry.
+ ///
+ ///
+ /// Optional. A named region in the cache to which the cache entry can be added,
+ /// if regions are implemented. The default value for the optional parameter
+ /// is null.
+ ///
+ ///
+ /// The cache entry that is identified by key.
+ ///
+ public static object GetItem(string key, string regionName = null)
+ {
+ return Cache.Get(key, regionName);
+ }
+
+ //public static bool
+
+ ///
+ /// Updates an item to the cache.
+ ///
+ ///
+ /// A unique identifier for the cache entry.
+ ///
+ ///
+ /// The object to insert.
+ ///
+ ///
+ /// Optional. An object that contains eviction details for the cache entry. This object
+ /// provides more options for eviction than a simple absolute expiration. The default value for the optional parameter
+ /// is null.
+ ///
+ ///
+ /// Optional. A named region in the cache to which the cache entry can be added,
+ /// if regions are implemented. The default value for the optional parameter
+ /// is null.
+ ///
+ ///
+ /// True if the update try succeeds, or false if there is an already an entry
+ /// in the cache with the same key as key.
+ ///
+ public static bool UpdateItem(string key, object value, CacheItemPolicy policy = null, string regionName = null)
+ {
+ bool isUpDated = true;
+
+ // Remove the item from the cache if it already exists. MemoryCache will
+ // not add an item with an existing name.
+ if (GetItem(key, regionName) != null)
+ {
+ isUpDated = RemoveItem(key, regionName);
+ }
+
+ if (policy == null)
+ {
+ // Create a new cache policy with the default values
+ policy = new CacheItemPolicy();
+ }
+
+ if (isUpDated)
+ {
+ isUpDated = AddItem(key, value, policy, regionName);
+ }
+
+ return isUpDated;
+ }
+
+ ///
+ /// Removes an item matching the given key from the cache.
+ ///
+ ///
+ /// A unique identifier for the cache entry.
+ ///
+ ///
+ /// Optional. A named region in the cache to which the cache entry can be added,
+ /// if regions are implemented. The default value for the optional parameter
+ /// is null.
+ ///
+ ///
+ /// True if the removal try succeeds, or false if there is an already an entry
+ /// in the cache with the same key as key.
+ ///
+ public static bool RemoveItem(string key, string regionName = null)
+ {
+ bool isRemoved;
+
+ lock (Cache)
+ {
+ isRemoved = Cache.Remove(key, regionName) != null;
+
+ if (isRemoved)
+ {
+ CacheItems.Remove(key);
+ }
+ }
+
+ return isRemoved;
+ }
+
+ ///
+ /// Clears the cache.
+ ///
+ ///
+ /// The region name.
+ ///
+ ///
+ /// The .
+ ///
+ public static bool Clear(string regionName = null)
+ {
+ bool isCleared = false;
+
+ lock (CacheItems)
+ {
+ // You can't remove items from a collection whilst you are iterating over it so you need to
+ // create a collection to store the items to remove.
+ Dictionary tempDictionary = new Dictionary();
+
+ foreach (KeyValuePair cacheItem in CacheItems)
+ {
+ // Does the cached key come with a region.
+ if ((cacheItem.Value == null) || (cacheItem.Value != null && cacheItem.Value.Equals(regionName, StringComparison.OrdinalIgnoreCase)))
+ {
+ isCleared = RemoveItem(cacheItem.Key, cacheItem.Value);
+
+ if (isCleared)
+ {
+ tempDictionary.Add(cacheItem.Key, cacheItem.Value);
+ }
+ }
+ }
+
+ if (isCleared)
+ {
+ // Loop through and clear out the dictionary of cache keys.
+ foreach (KeyValuePair cacheItem in tempDictionary)
+ {
+ CacheItems.Remove(cacheItem.Key);
+ }
+ }
+ }
+
+ return isCleared;
+ }
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/src/ImageProcessor.Web/NET45/Caching/CleanupImage.cs b/src/ImageProcessor.Web/NET45/Caching/CleanupImage.cs
new file mode 100644
index 000000000..aa813bae3
--- /dev/null
+++ b/src/ImageProcessor.Web/NET45/Caching/CleanupImage.cs
@@ -0,0 +1,32 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// Copyright (c) James South.
+// Licensed under the Apache License, Version 2.0.
+//
+//
+// Describes a cached image for cleanup.
+//
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace ImageProcessor.Web.Caching
+{
+ #region Using
+ using System;
+ #endregion
+
+ ///
+ /// Describes a cached image for cleanup
+ ///
+ public sealed class CleanupImage
+ {
+ ///
+ /// Gets or sets the value of the cached image.
+ ///
+ public string Path { get; set; }
+
+ ///
+ /// Gets or sets when the cached image should expire from the cache.
+ ///
+ public DateTime ExpiresUtc { get; set; }
+ }
+}
diff --git a/src/ImageProcessor.Web/NET45/Caching/DiskCache.cs b/src/ImageProcessor.Web/NET45/Caching/DiskCache.cs
index 67445ee3a..3bbc0a42b 100644
--- a/src/ImageProcessor.Web/NET45/Caching/DiskCache.cs
+++ b/src/ImageProcessor.Web/NET45/Caching/DiskCache.cs
@@ -1,17 +1,18 @@
-// -----------------------------------------------------------------------
+// --------------------------------------------------------------------------------------------------------------------
//
-// Copyright (c) James South.
-// Licensed under the Apache License, Version 2.0.
+// Copyright (c) James South.
+// Licensed under the Apache License, Version 2.0.
//
-// -----------------------------------------------------------------------
+//
+// The disk cache.
+//
+// --------------------------------------------------------------------------------------------------------------------
namespace ImageProcessor.Web.Caching
{
#region Using
using System;
- using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
- using System.Drawing;
using System.Globalization;
using System.IO;
using System.Linq;
@@ -238,7 +239,7 @@ namespace ImageProcessor.Web.Caching
ExpiresUtc = expires
};
- await PersistantDictionary.Instance.AddAsync(key, cachedImage);
+ await MemoryCache.Instance.AddAsync(key, cachedImage);
}
///
@@ -255,14 +256,16 @@ namespace ImageProcessor.Web.Caching
if (this.isRemote)
{
- if (PersistantDictionary.Instance.TryGetValue(key, out cachedImage))
+ cachedImage = await MemoryCache.Instance.GetValueAsync(key);
+
+ if (cachedImage != null)
{
// Can't check the last write time so check to see if the cached image is set to expire
// or if the max age is different.
if (cachedImage.ExpiresUtc < DateTime.UtcNow.AddDays(-MaxFileCachedDuration)
|| cachedImage.MaxAge != MaxFileCachedDuration)
{
- if (await PersistantDictionary.Instance.TryRemoveAsync(key))
+ if (await MemoryCache.Instance.RemoveAsync(key))
{
isUpdated = true;
}
@@ -277,7 +280,9 @@ namespace ImageProcessor.Web.Caching
else
{
// Test now for locally requested files.
- if (PersistantDictionary.Instance.TryGetValue(key, out cachedImage))
+ cachedImage = await MemoryCache.Instance.GetValueAsync(key);
+
+ if (cachedImage != null)
{
FileInfo imageFileInfo = new FileInfo(this.requestPath);
@@ -289,7 +294,7 @@ namespace ImageProcessor.Web.Caching
|| cachedImage.ExpiresUtc < DateTime.UtcNow.AddDays(-MaxFileCachedDuration)
|| cachedImage.MaxAge != MaxFileCachedDuration)
{
- if (await PersistantDictionary.Instance.TryRemoveAsync(key))
+ if (await MemoryCache.Instance.RemoveAsync(key))
{
isUpdated = true;
}
@@ -314,8 +319,17 @@ namespace ImageProcessor.Web.Caching
///
internal async Task GetLastWriteTimeAsync()
{
- // Create Action delegate for TrimCachedFolders.
- return await TaskHelpers.Run(this.GetLastWriteTime);
+ string key = Path.GetFileNameWithoutExtension(this.CachedPath);
+ DateTime dateTime = DateTime.UtcNow;
+
+ CachedImage cachedImage = await MemoryCache.Instance.GetValueAsync(key);
+
+ if (cachedImage != null)
+ {
+ dateTime = cachedImage.LastWriteTimeUtc;
+ }
+
+ return dateTime;
}
///
@@ -383,17 +397,17 @@ namespace ImageProcessor.Web.Caching
///
private async void TrimCachedFolders()
{
- // Group each cache folder and clear any expired items or any that exeed
+ // Group each cache folder and clear any expired items or any that exceed
// the maximum allowable count.
- var groups = PersistantDictionary.Instance.ToList()
- .GroupBy(x => SubFolderRegex.Match(x.Value.Path).Value)
+ var groups = SQLContext.GetImagesForCleanup()
+ .GroupBy(x => SubFolderRegex.Match(x.Path).Value)
.Where(g => g.Count() > MaxFilesCount);
foreach (var group in groups)
{
int groupCount = group.Count();
- foreach (KeyValuePair pair in group.OrderBy(x => x.Value.ExpiresUtc))
+ foreach (CleanupImage pair in group.OrderBy(x => x.ExpiresUtc))
{
// If the group count is equal to the max count minus 1 then we know we
// are counting down from a full directory not simply clearing out
@@ -406,10 +420,10 @@ namespace ImageProcessor.Web.Caching
try
{
// Remove from the cache and delete each CachedImage.
- FileInfo fileInfo = new FileInfo(pair.Value.Path);
+ FileInfo fileInfo = new FileInfo(pair.Path);
string key = Path.GetFileNameWithoutExtension(fileInfo.Name);
- if (await PersistantDictionary.Instance.TryRemoveAsync(key))
+ if (await MemoryCache.Instance.RemoveAsync(key))
{
fileInfo.Delete();
groupCount -= 1;
@@ -460,26 +474,6 @@ namespace ImageProcessor.Web.Caching
return cachedPath;
}
- ///
- /// Gets last modified time of the image.
- ///
- ///
- /// The representing the last modified time of the image.
- ///
- private DateTime GetLastWriteTime()
- {
- string key = Path.GetFileNameWithoutExtension(this.CachedPath);
- CachedImage cachedImage;
- DateTime dateTime = DateTime.UtcNow;
-
- if (PersistantDictionary.Instance.TryGetValue(key, out cachedImage))
- {
- dateTime = cachedImage.LastWriteTimeUtc;
- }
-
- return dateTime;
- }
-
///
/// The rough date time compare.
///
diff --git a/src/ImageProcessor.Web/NET45/Caching/PersistantDictionary.cs b/src/ImageProcessor.Web/NET45/Caching/MemoryCache.cs
similarity index 62%
rename from src/ImageProcessor.Web/NET45/Caching/PersistantDictionary.cs
rename to src/ImageProcessor.Web/NET45/Caching/MemoryCache.cs
index aaa8f7c0b..dedaf5d56 100644
--- a/src/ImageProcessor.Web/NET45/Caching/PersistantDictionary.cs
+++ b/src/ImageProcessor.Web/NET45/Caching/MemoryCache.cs
@@ -1,31 +1,32 @@
-// -----------------------------------------------------------------------
-//
-// Copyright (c) James South.
-// Licensed under the Apache License, Version 2.0.
+// --------------------------------------------------------------------------------------------------------------------
+//
+// Copyright (c) James South.
+// Licensed under the Apache License, Version 2.0.
//
-// -----------------------------------------------------------------------
+//
+//
+//
+// --------------------------------------------------------------------------------------------------------------------
namespace ImageProcessor.Web.Caching
{
#region Using
using System;
- using System.Collections.Generic;
using System.Threading.Tasks;
- using ImageProcessor.Web.Helpers;
#endregion
///
- /// Represents a collection of keys and values whose operations are concurrent.
+ /// Represents an in memory collection of keys and values whose operations are concurrent.
///
- internal sealed class PersistantDictionary : LockedDictionary
+ internal sealed class MemoryCache
{
#region Fields
///
- /// A new instance Initializes a new instance of the class.
+ /// A new instance Initializes a new instance of the class.
/// initialized lazily.
///
- private static readonly Lazy Lazy =
- new Lazy(() => new PersistantDictionary());
+ private static readonly Lazy Lazy =
+ new Lazy(() => new MemoryCache());
///
/// The object to lock against.
@@ -35,19 +36,19 @@ namespace ImageProcessor.Web.Caching
#region Constructors
///
- /// Prevents a default instance of the class
+ /// Prevents a default instance of the class
/// from being created.
///
- private PersistantDictionary()
+ private MemoryCache()
{
this.LoadCache();
}
#endregion
///
- /// Gets the current instance of the class.
+ /// Gets the current instance of the class.
///
- public static PersistantDictionary Instance
+ public static MemoryCache Instance
{
get
{
@@ -57,29 +58,47 @@ namespace ImageProcessor.Web.Caching
#region Public
///
- /// Tries to remove the value associated with the specified key.
+ /// Gets the associated with the specified key.
///
///
- /// The key of the item to remove.
+ /// The key of the value to get.
///
///
- /// true if the removes an element with
- /// the specified key; otherwise, false.
+ /// The matching the given key if the contains an element with
+ /// the specified key; otherwise, null.
///
- public async Task TryRemoveAsync(string key)
+ public async Task GetValueAsync(string key)
{
- // No CachedImage to remove.
- if (!this.ContainsKey(key))
+ CachedImage cachedImage = (CachedImage)CacheManager.GetItem(key);
+
+ if (cachedImage == null)
{
- return false;
+ cachedImage = await SQLContext.GetImageAsync(key);
+
+ if (cachedImage != null)
+ {
+ CacheManager.AddItem(key, cachedImage);
+ }
}
- // Remove the CachedImage.
- CachedImage value = this[key];
+ return cachedImage;
+ }
- if (await this.SaveCacheAsync(key, value, true) > 0)
+ ///
+ /// Removes the value associated with the specified key.
+ ///
+ ///
+ /// The key of the item to remove.
+ ///
+ ///
+ /// true if the removes an element with
+ /// the specified key; otherwise, false.
+ ///
+ public async Task RemoveAsync(string key)
+ {
+ if (await this.SaveCacheAsync(key, null, true) > 0)
{
- this.Remove(key);
+ CacheManager.RemoveItem(key);
return true;
}
@@ -103,7 +122,7 @@ namespace ImageProcessor.Web.Caching
// Add the CachedImage.
if (await this.SaveCacheAsync(key, cachedImage, false) > 0)
{
- this.Add(key, cachedImage);
+ CacheManager.AddItem(key, cachedImage);
}
return cachedImage;
@@ -131,7 +150,7 @@ namespace ImageProcessor.Web.Caching
{
if (remove)
{
- return await SQLContext.RemoveImageAsync(cachedImage);
+ return await SQLContext.RemoveImageAsync(key);
}
return await SQLContext.AddImageAsync(cachedImage);
@@ -150,13 +169,6 @@ namespace ImageProcessor.Web.Caching
lock (SyncRoot)
{
SQLContext.CreateDatabase();
-
- Dictionary dictionary = SQLContext.GetImages();
-
- foreach (KeyValuePair pair in dictionary)
- {
- this.Add(pair);
- }
}
}
}
diff --git a/src/ImageProcessor.Web/NET45/Caching/SQLContext.cs b/src/ImageProcessor.Web/NET45/Caching/SQLContext.cs
index fe1da938d..deeb30658 100644
--- a/src/ImageProcessor.Web/NET45/Caching/SQLContext.cs
+++ b/src/ImageProcessor.Web/NET45/Caching/SQLContext.cs
@@ -83,29 +83,47 @@ namespace ImageProcessor.Web.Caching
/// Gets all the images from the database.
///
///
- /// The .
+ /// The .
///
- internal static Dictionary GetImages()
+ internal static List GetImagesForCleanup()
{
- Dictionary dictionary = new Dictionary();
-
try
{
+ List images;
using (SQLiteConnection connection = new SQLiteConnection(ConnectionString))
{
- List images = connection.Query("SELECT * FROM CachedImage");
-
- foreach (CachedImage cachedImage in images)
- {
- dictionary.Add(cachedImage.Key, cachedImage);
- }
+ images = connection.Query("SELECT Path,ExpiresUtc FROM CachedImage");
}
- return dictionary;
+ return images;
+
+ }
+ catch
+ {
+ return new List();
+ }
+ }
+
+ ///
+ /// Gets a cached image from the database.
+ ///
+ ///
+ /// The key for the cached image to get.
+ ///
+ ///
+ /// The from the database.
+ ///
+ internal static async Task GetImageAsync(string key)
+ {
+ try
+ {
+ SQLiteAsyncConnection connection = new SQLiteAsyncConnection(ConnectionString);
+
+ return await connection.GetAsync(c => c.Key == key);
}
catch
{
- return new Dictionary();
+ return null;
}
}
@@ -123,7 +141,6 @@ namespace ImageProcessor.Web.Caching
try
{
SQLiteAsyncConnection connection = new SQLiteAsyncConnection(ConnectionString);
-
return await connection.InsertAsync(image);
}
catch
@@ -135,17 +152,18 @@ namespace ImageProcessor.Web.Caching
///
/// Removes a cached image from the database.
///
- ///
+ ///
/// The key for the cached image.
///
///
/// The true if the addition of the cached image is removed; otherwise, false.
///
- internal static async Task RemoveImageAsync(CachedImage cachedImage)
+ internal static async Task RemoveImageAsync(string key)
{
try
{
SQLiteAsyncConnection connection = new SQLiteAsyncConnection(ConnectionString);
+ CachedImage cachedImage = await connection.GetAsync(c => c.Key == key);
return await connection.DeleteAsync(cachedImage);
}
diff --git a/src/ImageProcessor.Web/NET45/Config/ImageCacheSection.cs b/src/ImageProcessor.Web/NET45/Config/ImageCacheSection.cs
index 6a28d3229..92015a83d 100644
--- a/src/ImageProcessor.Web/NET45/Config/ImageCacheSection.cs
+++ b/src/ImageProcessor.Web/NET45/Config/ImageCacheSection.cs
@@ -21,7 +21,7 @@ namespace ImageProcessor.Web.Config
/// Gets or sets the virtual path of the cache folder.
///
/// The name of the cache folder.
- [ConfigurationProperty("virtualPath", DefaultValue = "~/cache", IsRequired = true)]
+ [ConfigurationProperty("virtualPath", DefaultValue = "~/app_data/cache", IsRequired = true)]
[StringValidator(MinLength = 3, MaxLength = 200)]
public string VirtualPath
{
@@ -29,7 +29,7 @@ namespace ImageProcessor.Web.Config
{
string virtualPath = (string)this["virtualPath"];
- return virtualPath.IsValidVirtualPathName() ? virtualPath : "~/cache";
+ return virtualPath.IsValidVirtualPathName() ? virtualPath : "~/app_data/cache";
}
set
diff --git a/src/ImageProcessor.Web/NET45/Helpers/LockedDictionary.cs b/src/ImageProcessor.Web/NET45/Helpers/LockedDictionary.cs
deleted file mode 100644
index 8cc26c06b..000000000
--- a/src/ImageProcessor.Web/NET45/Helpers/LockedDictionary.cs
+++ /dev/null
@@ -1,321 +0,0 @@
-// -----------------------------------------------------------------------
-//
-// Copyright (c) James South.
-// Licensed under the Apache License, Version 2.0.
-//
-// -----------------------------------------------------------------------
-
-namespace ImageProcessor.Web.Helpers
-{
- #region Using
- using System.Collections.Generic;
- using System.Linq;
- #endregion
-
- ///
- /// Represents a collection of keys and values that are thread safe.
- ///
- ///
- /// The type of the keys in the dictionary.
- ///
- ///
- /// The type of the values in the dictionary.
- ///
- internal class LockedDictionary : IDictionary
- {
- ///
- /// The _inner.
- ///
- private readonly Dictionary innerDictionary = new Dictionary();
-
- #region Constructors
- ///
- /// Initializes a new instance of the class.
- ///
- ///
- /// The value to initialize the LockedDictionary with.
- ///
- public LockedDictionary(IEnumerable> val = null)
- {
- if (val != null)
- {
- this.innerDictionary = val.ToDictionary(x => x.Key, x => x.Value);
- }
- }
- #endregion
-
- #region Properties
- ///
- /// Gets a collection containing the keys in the .
- ///
- public ICollection Keys
- {
- get
- {
- lock (this.innerDictionary)
- {
- return this.innerDictionary.Keys.ToArray();
- }
- }
- }
-
- ///
- /// Gets a collection containing the values in the .
- ///
- public ICollection Values
- {
- get
- {
- lock (this.innerDictionary)
- {
- return this.innerDictionary.Values.ToArray();
- }
- }
- }
-
- ///
- /// Gets the number of key/value pairs contained in the .
- ///
- public int Count
- {
- get
- {
- lock (this.innerDictionary)
- {
- return this.innerDictionary.Count;
- }
- }
- }
-
- ///
- /// Gets a value indicating whether the is read only.
- ///
- public bool IsReadOnly
- {
- get { return false; }
- }
-
- ///
- /// Gets or sets the value associated with the specified key.
- ///
- ///
- /// The key of the value to get or set.
- ///
- ///
- /// TThe value associated with the specified key. If the specified key is not found,
- /// a get operation throws a ,
- /// and a set operation creates a new element with the specified key.
- ///
- public TVal this[TKey key]
- {
- get
- {
- lock (this.innerDictionary)
- {
- return this.innerDictionary[key];
- }
- }
-
- set
- {
- lock (this.innerDictionary)
- {
- this.innerDictionary[key] = value;
- }
- }
- }
- #endregion
-
- #region Methods
- ///
- /// Adds the specified key and value to the dictionary.
- ///
- ///
- /// The key of the element to add.
- ///
- ///
- /// The value of the element to add. The value can be null for reference types.
- ///
- public void Add(TKey key, TVal value)
- {
- lock (this.innerDictionary)
- {
- this.innerDictionary.Add(key, value);
- }
- }
-
- ///
- /// Determines whether the LockedDictionary contains the specified key.
- ///
- ///
- /// The key to locate in the LockedDictionary.
- ///
- ///
- /// true if the LockedDictionary contains the key; otherwise, false.
- ///
- public bool ContainsKey(TKey key)
- {
- lock (this.innerDictionary)
- {
- return this.innerDictionary.ContainsKey(key);
- }
- }
-
- ///
- /// Removes the value with the specified key from the .
- ///
- ///
- /// The key of the element to remove.
- ///
- ///
- /// true if the element is successfully found and removed; otherwise, false.
- /// This method returns false if key is not found in the .
- ///
- public bool Remove(TKey key)
- {
- lock (this.innerDictionary)
- {
- return this.innerDictionary.Remove(key);
- }
- }
-
- ///
- /// Gets the value associated with the specified key.
- ///
- ///
- /// The key of the value to get.
- ///
- ///
- /// When this method returns, contains the value associated with the specified key, if the key is found;
- /// otherwise, the default value for the type of the value parameter. This parameter is passed uninitialized.
- ///
- ///
- /// true if the contains an element with
- /// the specified key; otherwise, false.
- ///
- public bool TryGetValue(TKey key, out TVal value)
- {
- lock (this.innerDictionary)
- {
- return this.innerDictionary.TryGetValue(key, out value);
- }
- }
-
- ///
- /// Adds the specified key and value to the dictionary.
- ///
- ///
- /// The representing
- /// the item to add.
- ///
- public void Add(KeyValuePair item)
- {
- lock (this.innerDictionary)
- {
- this.innerDictionary.Add(item.Key, item.Value);
- }
- }
-
- ///
- /// Removes all keys and values from the .
- ///
- public void Clear()
- {
- lock (this.innerDictionary)
- {
- this.innerDictionary.Clear();
- }
- }
-
- ///
- /// Determines whether the contains the specified key.
- ///
- ///
- /// The representing
- /// the item to locate.
- ///
- ///
- /// true if the contains an element
- /// with the specified key; otherwise, false.
- ///
- public bool Contains(KeyValuePair item)
- {
- lock (this.innerDictionary)
- {
- var inner = this.innerDictionary as IDictionary;
- return inner.Contains(item);
- }
- }
-
- ///
- /// Copies the elements of an to a one-dimensional
- /// starting at a particular index.
- ///
- ///
- /// The one-dimensional that is the destination of the elements copied
- /// from .KeyCollection.
- /// The must have zero-based indexing.
- ///
- ///
- /// The zero-based index in array at which copying begins.
- ///
- public void CopyTo(KeyValuePair[] array, int arrayIndex)
- {
- lock (this.innerDictionary)
- {
- var inner = this.innerDictionary as IDictionary;
- inner.CopyTo(array, arrayIndex);
- }
- }
-
- ///
- /// Removes the item with the specified
- /// from the
- ///
- ///
- /// The representing the item to remove.
- ///
- ///
- /// This method returns false if item is not found in the .
- ///
- public bool Remove(KeyValuePair item)
- {
- lock (this.innerDictionary)
- {
- var inner = this.innerDictionary as IDictionary;
- return inner.Remove(item);
- }
- }
-
- ///
- /// Returns an enumerator that iterates through the .KeyCollection.
- ///
- ///
- /// A
- /// for the .
- ///
- public IEnumerator> GetEnumerator()
- {
- lock (this.innerDictionary)
- {
- return this.innerDictionary.ToList().GetEnumerator();
- }
- }
-
- ///
- /// Returns an enumerator that iterates through the .KeyCollection.
- ///
- ///
- /// A
- /// for the .
- ///
- System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
- {
- lock (this.innerDictionary)
- {
- return this.innerDictionary.ToArray().GetEnumerator();
- }
- }
- #endregion
- }
-}
\ No newline at end of file
diff --git a/src/ImageProcessor.Web/NET45/HttpModules/ImageProcessingModule.cs b/src/ImageProcessor.Web/NET45/HttpModules/ImageProcessingModule.cs
index df1363b92..7097047a5 100644
--- a/src/ImageProcessor.Web/NET45/HttpModules/ImageProcessingModule.cs
+++ b/src/ImageProcessor.Web/NET45/HttpModules/ImageProcessingModule.cs
@@ -1,9 +1,12 @@
-// -----------------------------------------------------------------------
+// --------------------------------------------------------------------------------------------------------------------
//
-// Copyright (c) James South.
-// Licensed under the Apache License, Version 2.0.
+// Copyright (c) James South.
+// Licensed under the Apache License, Version 2.0.
//
-// -----------------------------------------------------------------------
+//
+// Processes any image requests within the web application.
+//
+// --------------------------------------------------------------------------------------------------------------------
namespace ImageProcessor.Web.HttpModules
{
diff --git a/src/ImageProcessor.Web/NET45/ImageProcessor.Web_NET45.csproj b/src/ImageProcessor.Web/NET45/ImageProcessor.Web_NET45.csproj
index 7274ce547..d9a2832fd 100644
--- a/src/ImageProcessor.Web/NET45/ImageProcessor.Web_NET45.csproj
+++ b/src/ImageProcessor.Web/NET45/ImageProcessor.Web_NET45.csproj
@@ -40,6 +40,7 @@
+
@@ -49,14 +50,15 @@
+
+
-
+
-
diff --git a/src/ImageProcessor.Web/NET45/Settings.StyleCop b/src/ImageProcessor.Web/NET45/Settings.StyleCop
new file mode 100644
index 000000000..253825567
--- /dev/null
+++ b/src/ImageProcessor.Web/NET45/Settings.StyleCop
@@ -0,0 +1,11 @@
+
+
+
+
+ James South
+ Copyright (c) James South.
+Licensed under the Apache License, Version 2.0.
+
+
+
+
\ No newline at end of file
diff --git a/src/ImageProcessor/Imaging/ImageUtils.cs b/src/ImageProcessor/Imaging/ImageUtils.cs
index 58a9568ab..f7e6de6b4 100644
--- a/src/ImageProcessor/Imaging/ImageUtils.cs
+++ b/src/ImageProcessor/Imaging/ImageUtils.cs
@@ -210,7 +210,6 @@ namespace ImageProcessor.Imaging
/// True the value contains a valid image extension, otherwise false.
public static bool IsValidImageExtension(string fileName)
{
-
return FormatRegex.IsMatch(fileName);
}
diff --git a/src/ImageProcessor/Processors/Crop.cs b/src/ImageProcessor/Processors/Crop.cs
index 9023916b6..53ee2041a 100644
--- a/src/ImageProcessor/Processors/Crop.cs
+++ b/src/ImageProcessor/Processors/Crop.cs
@@ -1,9 +1,12 @@
-// -----------------------------------------------------------------------
+// --------------------------------------------------------------------------------------------------------------------
//
-// Copyright (c) James South.
-// Licensed under the Apache License, Version 2.0.
+// Copyright (c) James South.
+// Licensed under the Apache License, Version 2.0.
//
-// -----------------------------------------------------------------------
+//
+// Crops an image to the given directions.
+//
+// --------------------------------------------------------------------------------------------------------------------
namespace ImageProcessor.Processors
{