using System; using System.Linq; using System.Linq.Expressions; using System.Net.Http; using System.Reflection; using System.Web.Http; using iiie.CacheControl.Business.CacheKey; using iiie.CacheControl.Business.OutputCache; namespace iiie.CacheControl.Business.HttpExtensions { public class CacheOutputConfiguration { private readonly HttpConfiguration _configuration; private OutputCacheType _cacheType; public CacheOutputConfiguration(HttpConfiguration configuration, OutputCacheType type) { _configuration = configuration; _cacheType = type; } public void RegisterCacheOutputProvider(Func provider) { _configuration.Properties.GetOrAdd(typeof(IOutputCache), x => provider); } public void RegisterCacheKeyGeneratorProvider(Func provider) where T : ICacheKeyGenerator { _configuration.Properties.GetOrAdd(typeof(T), x => provider); } public void RegisterDefaultCacheKeyGeneratorProvider(Func provider) { RegisterCacheKeyGeneratorProvider(provider); } public string MakeBaseCachekey(string controller, string action) { return string.Format("{0}-{1}", controller.ToLower(), action.ToLower()); } public string MakeBaseCachekey(Expression> expression) { var method = expression.Body as MethodCallExpression; if (method == null) throw new ArgumentException("Expression is wrong"); var methodName = method.Method.Name; var nameAttribs = method.Method.GetCustomAttributes(typeof(ActionNameAttribute), false); if (nameAttribs.Any()) { var actionNameAttrib = (ActionNameAttribute)nameAttribs.FirstOrDefault(); if (actionNameAttrib != null) { methodName = actionNameAttrib.Name; } } return string.Format("{0}-{1}", typeof(T).Name.Replace("Controller", string.Empty).ToLower(), methodName.ToLower()); } private static ICacheKeyGenerator TryActivateCacheKeyGenerator(Type generatorType) { var hasEmptyOrDefaultConstructor = generatorType.GetConstructor(Type.EmptyTypes) != null || generatorType.GetConstructors(BindingFlags.Instance | BindingFlags.Public) .Any(x => x.GetParameters().All(p => p.IsOptional)); return hasEmptyOrDefaultConstructor ? Activator.CreateInstance(generatorType) as ICacheKeyGenerator : null; } public ICacheKeyGenerator GetCacheKeyGenerator(HttpRequestMessage request, Type generatorType) { generatorType = generatorType ?? typeof(ICacheKeyGenerator); object cache; _configuration.Properties.TryGetValue(generatorType, out cache); var cacheFunc = cache as Func; var generator = cacheFunc != null ? cacheFunc() : request.GetDependencyScope().GetService(generatorType) as ICacheKeyGenerator; return generator ?? TryActivateCacheKeyGenerator(generatorType) ?? new DefaultCacheKeyGenerator(); } public IOutputCache GetCacheOutputProvider(HttpRequestMessage request, object cacheOutputData) { object cache; _configuration.Properties.TryGetValue(typeof(IOutputCache), out cache); var cacheFunc = cache as Func; var cacheOutputProvider = cacheFunc != null ? cacheFunc() : request.GetDependencyScope().GetService(typeof(IOutputCache)) as IOutputCache; if (cacheOutputProvider == null) { if (_cacheType == OutputCacheType.File) cacheOutputProvider = new FileOuputCache(cacheOutputData as string); else cacheOutputProvider = new MemoryOutputCache(); } return cacheOutputProvider; } } }