0

I have found code for Get/Set cache item, but I don't know how I can call this method, eg. how pass proper Func<T> getData to this method?

public class Cache<T> : MemoryCache where T : class
    {
        public void Set(string cacheKey, T cacheItem, CacheItemPolicy policy = null)
        {
            //...
        }

        public bool TryGet(string cacheKey, out T returnItem)
        {
             //...
        }
        public bool TryGetOrSet( string cacheKey, Func<T> getData, out T returnData, CacheItemPolicy policy = null )
        {
            if( TryGet( cacheKey, out returnData ) )
                return true;

            lock( WriteLock )
            {
                if( TryGet( cacheKey, out returnData ) )
                    return true;

                returnData = getData();
                Set( cacheKey, returnData, policy );
            }

            return false;
        }
    }

For example let's assume that cache type is string.

First question: By using method TryGetOrSet how I can add item (key : userName variable, value: lastName variable) to cache? Of course when this item doesn't exists in cache

var cache = new Cache<string>("UserInfo");
var userName = "test";
var lastName = "test2";
TryGetOrSet(userName, ???, out var _) // <- what should I pass to Func<T>?
mkul
  • 773
  • 1
  • 10
  • 28
  • Where is `T` defined? On the class containing `TryGetOrSet`? – Yacoub Massad Jun 27 '17 at 09:02
  • 6
    This is not the real code, is it? You did not declare `T` (as in `void TryGetOrSet(...)`, or is it in the type declaration?) and you have a `void` method returning a `bool`? – René Vogt Jun 27 '17 at 09:02
  • 3
    Try something like `() => "my string"` or `() => CallStringReturningMethod()` – Yacoub Massad Jun 27 '17 at 09:03
  • @YacoubMassad, yes, is defined in the class `public class Cache : MemoryCache where T : class` – mkul Jun 27 '17 at 09:04
  • @RenéVogt yep, I have found this on code review site – mkul Jun 27 '17 at 09:04
  • 3
    Which part are you having problems with? Do you not know how to create a `Func` at all? You don't know how to pass one to a method? You have found somebody doing it in a way you don't understand? It might be easiest to show us not just the code you are trying to call but more importantly the code where you are trying to call it so we can advise you. As it stands its going to be quite tricky to say exactly how to create the right `Func` without knowing what you expect that `Func` to do... – Chris Jun 27 '17 at 09:06

1 Answers1

6

Your example is missing the declaration of T - but you've commented its on the class

public class Cache<T>
{
    public void TryGetOrSet( string cacheKey, Func<T> getData, out T returnData, CacheItemPolicy policy = null )
    {
       ...
    }
}

In this case, you can pass to getData any method (anonymous or otherwise) which matches the signature expected. So say you have an instance

var myCache = new Cache<string>();

Then any method which takes no parameters and returns a string can be passed as that parameter.

string value = null;
myCache.TryGetOrSet("some_key", () => "foo", out value);

Also if you have a method which gets your data somewhere a reference to that can be passed

// somewhere eg "MyRepository"
public IEnumerable<MyObject> MyDataAccessMethod() { return Enumerable.Empty<MyObject>(); }

and

var myCache = new Cache<IEnumerable<MyObject>>();
var repo = new MyRepository();
IEnumerable<MyObject> data = null;
myCache.TryGetOrSet("some_key", repo.MyDataAccessMethod, out data);

As a side note, you've declared the method to return void but youre returning a boolean - this makes sense as a TryXXX method should return a boolean to indicate success.

public bool TryGetOrSet( string cacheKey, Func<T> getData, out T returnData, CacheItemPolicy policy = null )
{
   ...
}

In response to your update:

First question: By using method TryGetOrSet how I can add item (key : userName variable, value: lastName variable) to cache? Of course when this item doesn't exists in cache

var cache = new Cache<string>("UserInfo");
var userName = "test";
var lastName = "test2";
string result = null;
TryGetOrSet(userName, () => lastName, out result) ;
Jamiec
  • 133,658
  • 13
  • 134
  • 193
  • I think it could be useful to pass the `key` to the data access method, too: `myCache.TryGetOrSet("some_key", () => repo.MyDataAccessMethod("some_key"), out data);` But that depends on what OP is actually trying to do, which was not yet explained. – René Vogt Jun 27 '17 at 09:12
  • @RenéVogt its a pretty bog-standard caching wrapper. I don't know why you'd pass the cache key to the DAL - that makes no sense to me. – Jamiec Jun 27 '17 at 09:15
  • Because (as the code seems to me) it's trying to find a specific object for a specific key, and if it's not yet in the cache, it calls `getData` to get exactly that item from another source and add it to the cache. So I guessed it would be helpful for the `getData` method to know for which `key` it should return the specific item. But of course I maybe wrong as I don't know the rest of the code. – René Vogt Jun 27 '17 at 09:17