我有很多方法,我需要将其中一些放入缓存中。但是我不希望它编辑每种方法。
如何将返回值作为参数传递给动态方法?请在我的代码中将评论作为我的一些问题进行检查。
感谢您提前。
private string GetUserName(string userId)
{
// how can I pass the method as parameter?
// Method is dynamic and can be any method with parameter(s) and return value
return CacheIt<string>(item => GetUserNameFromDb(userId));
}
private T CacheIt<T>(Action<T> action) // Im not sure if this an Action
{
var key = "UserInfo." + userId; // how can I get the value of the parameter?
var cache = MemoryCache.Default;
var value = (T) cache[key];
if (value != null)
return value;
value = action(); // how can I call the action or the method
var policy = new CacheItemPolicy { SlidingExpiration = new TimeSpan(1, 0, 0) };
cache.Add(key, value, policy);
return value;
}
private string GetUserNameFromDb(string userId)
{
return "FirstName LastName";
}
答案 0 :(得分:1)
像这样修改CacheIt
方法;输入参数作为对象类型传递给方法,对于创建缓存键,输入对象被序列化为Json,json结果计算为MD5。 MD5结果作为键存储在缓存中。此外,操作不会返回值,我使用 Func 而不是操作。我们期望为缓存返回值。
private T2 CacheIt<T2>(Func<T2> func, object input)
{
var key = CreateMD5(JsonConvert.SerializeObject(input));
var cache = MemoryCache.Default;
var value = cache.Get(key);
if (value != null)
{
return (T2)value;
}
value = func();
var policy = new CacheItemPolicy { SlidingExpiration = new TimeSpan(1, 0, 0) };
cache.Add(key, value, policy);
return (T2)value;
}
private string CreateMD5(string input)
{
using (System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create())
{
byte[] inputBytes = System.Text.Encoding.ASCII.GetBytes(input);
byte[] hashBytes = md5.ComputeHash(inputBytes);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < hashBytes.Length; i++)
{
sb.Append(hashBytes[i].ToString("X2"));
}
return sb.ToString();
}
}
最后,GetUserName
和GetUserNameFromDb方法看起来像这样;
private string GetUserName(string userId,string anotherParameter)
{
return CacheIt<string>(() => GetUserNameFromDb(userId, anotherParameter), new { userId,anotherParameter });
}
private string GetUserNameFromDb(string userId, string anotherParameter)
{
return "FirstName LastName";
}
<强>用法; 强>
GetUserName("1","AnotherParameter");
注意:也许可能有更好的方法来获取输入参数 直接来自
func
方法中的CacheIt
。
答案 1 :(得分:0)
我们可以通过
动态传递方法而不管方法定义 public T CacheIt<T>(object container,string methodName,params object[] parameterlist)
{
MethodInfo func = container.GetType().GetMethod(methodName);
var cache = MemoryCache.Default;
T value = (T)cache.Get(func.Name);
if(value!=null)
{
return value;
}
value = (T)func.Invoke(container,parameterlist);
cache.Add(func.Name, value,new CacheItemPolicy());
return value;
}
public void PrintUserName()
{
CacheIt<string>(this,nameof(this.GetUserName),"1");
CacheIt<string>(this, nameof(this.GetFullName), "Raghu","Ram");
Console.Read();
}
public string GetUserName(string userId)
{
// how can I pass the method as parameter?
// Method is dynamic and can be any method with parameter(s) and return value
//return CacheIt<string>(item => GetUserNameFromDb(userId));
return $"UserId : {userId} & UserName:Vaishali";
}
public string GetFullName(string FirstName,string LastName)
{
return $"FullName : {string.Concat(FirstName," ",LastName)}";
}
使用'out'和'ref'变量可以正常工作,但是获取out和ref变量的值并不容易,为此我们必须对ParameterInfo的东西做更多的工作。