views:

180

answers:

3

In webmethods, it is very simple to implement caching by annotating [WebMethod(CacheDuration...] attribute. Can we create something similar for non-webmethods, such as Static methods?

Any help/tip is appreciated. Thanks in advance.

+4  A: 

There is no built in feature for achieving exactly what you want. You should use Httpruntime.Cache.

It's not a built in feature but you may achieve something like that using aspect oriented programming (AOP). Caching information using aspects.

In case you're interested Spring.NET provides AOP

Claudio Redi
Thanks for replying, Claudio. AoP can help, but it is not possible for the project at this time. So the next best thing is Attribute. Can't we still use HttpRuntime.Cache with attributes? If so, any pointers on how to achieve it?
SP
@SP: I'm afraid you have to do it programatically, you can't use attributes.
Claudio Redi
@SP attributes are nothing more than metadata embedded in the assembly. You'd need something to read that metadata and intercept the method call. This is exactly what AOP does. So an attribute-only solution is impossible.
Josh Einstein
Thanks, it looks like I have to look into AoP framework. But it will be worth it. Thank you!
SP
A: 

If you can't use AOP to get the job done you could try using this little class I put together.

public MyClass CachedInstance
{
    get { return _cachedInstance.Value; }
}
private static readonly Cached<MyClass> _cachedInstance = new Cached<MyClass>(() => new MyClass(), TimeSpan.FromMinutes(15));

public sealed class Cached<T>
{
    private readonly Func<T> _createValue;
    private readonly TimeSpan _cacheFor;
    private DateTime _createdAt;
    private T _value;


    public T Value
    {
        get
        {
            if (_createdAt == DateTime.MinValue || DateTime.Now - _createdAt > _cacheFor)
            {
                lock (this)
                {
                    if (_createdAt == DateTime.MinValue || DateTime.Now - _createdAt > _cacheFor)
                    {
                        _value = _createValue();
                        _createdAt = DateTime.Now;
                    }
                }
            }
            return _value;
        }
    }


    public Cached(Func<T> createValue, TimeSpan cacheFor)
    {
        if (createValue == null)
        {
            throw new ArgumentNullException("createValue");
        }
        _createValue = createValue;
        _cacheFor = cacheFor;
    }
}
ChaosPandion
I am looking more declarative way to cache, so AoP solutions fit much better. If everything fails, I have to do it the hard way, by leaving cache entrails everywhere. Messy!
SP
+1  A: 

Check this simple implementation of an attribute for caching using Post Sharp.

Fernando
PostSharp is great and does exactly what I want. Great commercial alternative. Thank you, Fernando.
SP
It has a communty edition too. Check the download page.
Fernando