public Func <TCommand, string> Compile <TCommand>(ICacheKeyHash cacheKeyHash) { Func <TCommand, string> compiledFunc = null; var commandParameter = Expression.Parameter(typeof(TCommand)); MethodInfo toStringMethodInfo = typeof(object).GetTypeInfo().GetDeclaredMethod("ToString"); MethodInfo gethashcodeMethodInfo = typeof(ICacheKeyHash).GetTypeInfo().GetDeclaredMethod("GetHash"); PropertyInfo[] properties = typeof(TCommand).GetTypeInfo().DeclaredProperties.OrderBy(x => x.Name).ToArray(); Expression[] concatParameters = new Expression[properties.Length * 3 + 1]; concatParameters[0] = Expression.Constant(typeof(TCommand).Name); for (int propertyIndex = 0; propertyIndex < properties.Length; propertyIndex++) { concatParameters[propertyIndex * 3 + 1] = Expression.Constant("|"); concatParameters[propertyIndex * 3 + 2] = Expression.Constant(properties[propertyIndex].Name + ":"); concatParameters[propertyIndex * 3 + 3] = Expression.Call(Expression.Property(commandParameter, properties[propertyIndex]), toStringMethodInfo); } MethodInfo concatMethodInfo = typeof(string).GetTypeInfo().GetDeclaredMethods("Concat").Single(x => x.GetParameters().Length == 1 && x.GetParameters()[0].ParameterType == typeof(IEnumerable <string>)); Expression concatCall = Expression.Call(null, concatMethodInfo, Expression.NewArrayInit(typeof(string), concatParameters)); Expression gethashcodeCall = Expression.Call(Expression.Constant(cacheKeyHash), gethashcodeMethodInfo, concatCall); var lambda = Expression.Lambda <Func <TCommand, string> >(gethashcodeCall, commandParameter); compiledFunc = lambda.Compile(); return(compiledFunc); }
public PropertyCacheKeyProvider(IPropertyCacheKeyProviderCompiler compiler, ICacheKeyHash cacheKeyHash) { _compiler = compiler; _cacheKeyHash = cacheKeyHash; }