diff --git a/doc/reference/src/aop-aspect-library.xml b/doc/reference/src/aop-aspect-library.xml
index 313e6755..2b198ac1 100644
--- a/doc/reference/src/aop-aspect-library.xml
+++ b/doc/reference/src/aop-aspect-library.xml
@@ -196,14 +196,14 @@ public Airport GetAirport(long id)
The first parameter is the cache name. The second string parameter
is the cache key and is a string expression that incorporates the argument
- passed into the method, the id. The method parameter names are exposed as
- variables to the key expression. If you do not specify a key, then all the
- parameter values will be used to cache the returned value. The expression
- may also call out to other objects in the Spring container allowing for a
- more complex key algorithm to be encapsulated. The end result is that the
- Airport object is cached by id for 60 seconds in a cache named
- AspNetCache. The TimetoLive property could also have been specified on the
- configuration of the AspNetCache object.
+ passed into the method, the id. The cache key value cannot be null or an
+ empty string (""). The method parameter names are exposed as variables to
+ the key expression. The expression may also call out to other objects in
+ the Spring container allowing for a more complex key algorithm to be
+ encapsulated. The end result is that the Airport object is cached by id
+ for 60 seconds in a cache named AspNetCache. The TimetoLive property could
+ also have been specified on the configuration of the AspNetCache
+ object.
The configuration to enable the caching aspect is shown below
diff --git a/src/Spring/Spring.Core/Caching/BaseCacheAttribute.cs b/src/Spring/Spring.Core/Caching/BaseCacheAttribute.cs
index 62a25e00..130a7bc0 100644
--- a/src/Spring/Spring.Core/Caching/BaseCacheAttribute.cs
+++ b/src/Spring/Spring.Core/Caching/BaseCacheAttribute.cs
@@ -1,174 +1,186 @@
-using System;
-using Spring.Core.TypeConversion;
-using Spring.Expressions;
-
-namespace Spring.Caching
-{
- ///
- /// Abstract base class containing shared properties for all cache attributes.
- ///
- /// Aleksandar Seovic
- [Serializable]
- public abstract class BaseCacheAttribute : Attribute
- {
- #region Fields
-
- ///
- /// The instance used to parse values.
- ///
- ///
- ///
- protected static readonly TimeSpanConverter TimeSpanConverter = new TimeSpanConverter();
-
- private string cacheName;
- private string key;
- private IExpression keyExpression;
- private string condition;
- private IExpression conditionExpression;
- private string timeToLive = null;
- private TimeSpan timeToLiveTimeSpan = TimeSpan.MinValue;
-
- #endregion
-
- #region Constructors
-
- ///
- /// Creates an attribute instance.
- ///
- public BaseCacheAttribute()
- {
- }
-
- ///
- /// Creates an attribute instance.
- ///
- ///
- /// The name of the cache to use.
- ///
- ///
- /// An expression string that should be evaluated in order to determine
- /// the cache key for the item.
- ///
- public BaseCacheAttribute(string cacheName, string key)
- {
- this.CacheName = cacheName;
- this.Key = key;
- }
-
- #endregion
-
- #region Properties
-
- ///
- /// Gets or sets the name of the cache to use.
- ///
- ///
- /// The name of the cache to use.
- ///
- public string CacheName
- {
- get { return cacheName; }
- set { cacheName = value; }
- }
-
- ///
- /// Gets or sets a SpEL expression that should be evaluated in order
- /// to determine the cache key for the item.
- ///
- ///
- /// An expression string that should be evaluated in order to determine
- /// the cache key for the item.
- ///
- public string Key
- {
- get { return key; }
- set
- {
- key = value;
- keyExpression = Expression.Parse(value);
- }
- }
-
- ///
- /// Gets an expression instance that should be evaluated in order
- /// to determine the cache key for the item.
- ///
- ///
- /// An expression instance that should be evaluated in order to determine
- /// the cache key for the item.
- ///
- public IExpression KeyExpression
- {
- get { return keyExpression; }
- }
-
- ///
- /// Gets or sets a SpEL expression that should be evaluated in order
- /// to determine whether the item should be cached.
- ///
- ///
- /// An expression string that should be evaluated in order to determine
- /// whether the item should be cached.
- ///
- public string Condition
- {
- get { return condition; }
- set
- {
- condition = value;
- conditionExpression = Expression.Parse(value);
- }
- }
-
- ///
- /// Gets an expression instance that should be evaluated in order
- /// to determine whether the item should be cached.
- ///
- ///
- /// An expression instance that should be evaluated in order to determine
- /// whether the item should be cached.
- ///
- public IExpression ConditionExpression
- {
- get { return conditionExpression; }
- }
-
- ///
- /// The amount of time an object should remain in the cache.
- ///
- ///
- /// If no TTL is specified, the default TTL defined by the
- /// cache's policy will be applied.
- ///
- ///
- /// The amount of time object should remain in the cache
- /// formatted to be recognizable by .
- ///
- public string TimeToLive
- {
- get { return timeToLive; }
- set
- {
- timeToLive = value;
- timeToLiveTimeSpan = (timeToLive == null) ? TimeSpan.MinValue : (TimeSpan)TimeSpanConverter.ConvertFrom(timeToLive);
- }
- }
-
-
- ///
- /// The amount of time an object should remain in the cache (in seconds).
- ///
- ///
- /// If no TTL is specified, the default TTL defined by the
- /// cache's policy will be applied.
- ///
- ///
- /// The amount of time object should remain in the cache (in seconds).
- ///
- public TimeSpan TimeToLiveTimeSpan
- {
- get { return timeToLiveTimeSpan; }
- }
-
- #endregion
}
+using System;
+using Spring.Core.TypeConversion;
+using Spring.Expressions;
+
+namespace Spring.Caching
+{
+ ///
+ /// Abstract base class containing shared properties for all cache attributes.
+ ///
+ /// Aleksandar Seovic
+ [Serializable]
+ public abstract class BaseCacheAttribute : Attribute
+ {
+ #region Fields
+
+ ///
+ /// The instance used to parse values.
+ ///
+ ///
+ ///
+ protected static readonly TimeSpanConverter TimeSpanConverter = new TimeSpanConverter();
+
+ private string cacheName;
+ private string key;
+ private IExpression keyExpression;
+ private string condition;
+ private IExpression conditionExpression;
+ private string timeToLive = null;
+ private TimeSpan timeToLiveTimeSpan = TimeSpan.MinValue;
+
+ #endregion
+
+ #region Constructors
+
+ ///
+ /// Creates an attribute instance.
+ ///
+ public BaseCacheAttribute()
+ {
+ }
+
+ ///
+ /// Creates an attribute instance.
+ ///
+ ///
+ /// The name of the cache to use.
+ ///
+ ///
+ /// An expression string that should be evaluated in order to determine
+ /// the cache key for the item.
+ ///
+ /// The cache key cannot evaluate be null or an empty string.
+ public BaseCacheAttribute(string cacheName, string key)
+ {
+ if (null == key)
+ {
+ throw new ArgumentNullException("key", "The expression for the Cache Key cannot be null.");
+ }
+
+ if (key.Trim() == string.Empty)
+ {
+ throw new ArgumentOutOfRangeException("key", "The expression for the Cache Key cannot be an empty string.");
+ }
+
+ this.CacheName = cacheName;
+ this.Key = key;
+ }
+
+ #endregion
+
+ #region Properties
+
+ ///
+ /// Gets or sets the name of the cache to use.
+ ///
+ ///
+ /// The name of the cache to use.
+ ///
+ public string CacheName
+ {
+ get { return cacheName; }
+ set { cacheName = value; }
+ }
+
+ ///
+ /// Gets or sets a SpEL expression that should be evaluated in order
+ /// to determine the cache key for the item.
+ ///
+ ///
+ /// An expression string that should be evaluated in order to determine
+ /// the cache key for the item.
+ ///
+ public string Key
+ {
+ get { return key; }
+ set
+ {
+ key = value;
+ keyExpression = Expression.Parse(value);
+ }
+ }
+
+ ///
+ /// Gets an expression instance that should be evaluated in order
+ /// to determine the cache key for the item.
+ ///
+ ///
+ /// An expression instance that should be evaluated in order to determine
+ /// the cache key for the item.
+ ///
+ public IExpression KeyExpression
+ {
+ get { return keyExpression; }
+ }
+
+ ///
+ /// Gets or sets a SpEL expression that should be evaluated in order
+ /// to determine whether the item should be cached.
+ ///
+ ///
+ /// An expression string that should be evaluated in order to determine
+ /// whether the item should be cached.
+ ///
+ public string Condition
+ {
+ get { return condition; }
+ set
+ {
+ condition = value;
+ conditionExpression = Expression.Parse(value);
+ }
+ }
+
+ ///
+ /// Gets an expression instance that should be evaluated in order
+ /// to determine whether the item should be cached.
+ ///
+ ///
+ /// An expression instance that should be evaluated in order to determine
+ /// whether the item should be cached.
+ ///
+ public IExpression ConditionExpression
+ {
+ get { return conditionExpression; }
+ }
+
+ ///
+ /// The amount of time an object should remain in the cache.
+ ///
+ ///
+ /// If no TTL is specified, the default TTL defined by the
+ /// cache's policy will be applied.
+ ///
+ ///
+ /// The amount of time object should remain in the cache
+ /// formatted to be recognizable by .
+ ///
+ public string TimeToLive
+ {
+ get { return timeToLive; }
+ set
+ {
+ timeToLive = value;
+ timeToLiveTimeSpan = (timeToLive == null) ? TimeSpan.MinValue : (TimeSpan)TimeSpanConverter.ConvertFrom(timeToLive);
+ }
+ }
+
+
+ ///
+ /// The amount of time an object should remain in the cache (in seconds).
+ ///
+ ///
+ /// If no TTL is specified, the default TTL defined by the
+ /// cache's policy will be applied.
+ ///
+ ///
+ /// The amount of time object should remain in the cache (in seconds).
+ ///
+ public TimeSpan TimeToLiveTimeSpan
+ {
+ get { return timeToLiveTimeSpan; }
+ }
+
+ #endregion
+ }
}
\ No newline at end of file
diff --git a/test/Spring/Spring.Core.Tests/Caching/BaseCacheAttributeTests.cs b/test/Spring/Spring.Core.Tests/Caching/BaseCacheAttributeTests.cs
index 98302232..20611634 100644
--- a/test/Spring/Spring.Core.Tests/Caching/BaseCacheAttributeTests.cs
+++ b/test/Spring/Spring.Core.Tests/Caching/BaseCacheAttributeTests.cs
@@ -38,6 +38,16 @@ namespace Spring.Caching
private class DerivedCacheAttribute : BaseCacheAttribute
{
+ public DerivedCacheAttribute()
+ {
+
+ }
+
+ public DerivedCacheAttribute(string cacheName, string key)
+ : base(cacheName, key)
+ {
+
+ }
}
public string TestProperty
@@ -78,7 +88,21 @@ namespace Spring.Caching
public void AllowsForExtendedTimeSpanConverterSyntax()
{
att.TimeToLive = "5ms";
- Assert.AreEqual( new TimeSpan(0,0,0,0,5), att.TimeToLiveTimeSpan );
+ Assert.AreEqual(new TimeSpan(0, 0, 0, 0, 5), att.TimeToLiveTimeSpan);
+ }
+
+ [Test]
+ [ExpectedException(typeof(ArgumentOutOfRangeException))]
+ public void KeyCannotBeEmptyString()
+ {
+ att = new DerivedCacheAttribute("someName", string.Empty);
+ }
+
+ [Test]
+ [ExpectedException(typeof(ArgumentNullException))]
+ public void KeyCannotBeNull()
+ {
+ att = new DerivedCacheAttribute("someName", null);
}
}
}
\ No newline at end of file