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