C#共享逻辑和重用代码的最佳方式

时间:2015-07-10 13:10:17

标签: c# code-reuse

给定函数返回KPI值,首先检查其缓存,然后执行其逻辑,缓存结果并返回值,处理失败条件。

我如何最好地重用缓存,错误处理逻辑。我本质上想要创建的是一个函数,只需执行必要的逻辑,抽象出锅炉板代码,并在多个类似函数中重复使用。

public static int CurrentEmployees()
 {
     if (HttpRuntime.Cache["CurrentEmployees"] == null)
     {
         try
         {
             int CurrentEmployees = Employee.Load().Count(x => x.DateFinished == null && !x.Contractor && x.DateStarted < DateTime.Now);
             HttpRuntime.Cache.Insert("CurrentEmployees", CurrentEmployees, null, DateTime.Now.AddMinutes(20), new TimeSpan(0, 10, 0));

             return CurrentEmployees;
         }
         catch(Exception e)
         {
             //TODO: Report this
             return -1;
         }
     }
     else
         return (int)HttpRuntime.Cache["CurrentEmployees"];
 }

由于样板代码包含在逻辑中,因此我很难将这些代码简单地推送到其他函数调用中。

2 个答案:

答案 0 :(得分:3)

以下是如何创建一个通用方法来缓存任何你想要的东西并重用这个逻辑。

public static T Cache<T>(string key, Func<T> loadFunction, Func<T> errorHandler)
{
     if (HttpRuntime.Cache[key] == null)
     {
         try
         {
             T value = loadFunction();
         HttpRuntime.Cache.Insert(key, value , null, DateTime.Now.AddMinutes(20), new TimeSpan(0, 10, 0));
             return value;
         }
         catch(Exception e)
         {
             //TODO: Report this
             return errorHandler();
         }
     }
     else
         return (T)HttpRuntime.Cache[key];
}

用法:

public static int CurrentEmployees()
{
    return Cache<int>("CurrentEmployees", 
        () => Employee.Load().Count(x => x.DateFinished == null && !x.Contractor && x.DateStarted < DateTime.Now),
        () => -1);
}

答案 1 :(得分:0)

同意answer from @DLeh,但我会这样写:

public static class HelperFunctions
{
    public static Func<T> Cache<T>(this Func<T> inner, string cacheName)
    {
        return () =>
        {
            if (HttpRuntime.Cache[cacheName] == null)
            {
                var result = inner();
                HttpRuntime.Cache.Insert(cacheName, inner(), null, DateTime.Now.AddMinutes(20), new TimeSpan(0, 10, 0));

                return result;
            }

            return (T)HttpRuntime.Cache[cacheName];
        };
    }

    public static Func<T> OnError<T>(this Func<T> inner, Func<Exception, T> onError)
    {
        return () =>
        {
            try
            {
                return inner();
            }
            catch (Exception e)
            {
                return onError(e);
            }
        };
    }
}

用法:

public static class Employees
{
    public static int CurrentEmployees()
    {
        return (new Func<int>(() => Employee.Load().Count(x => x.DateFinished == null && !x.Contractor && x.DateStarted < DateTime.Now)))
            .Cache("CurrentEmployees")
            .OnError(e => -1) 
            ();//TODO: log?
    }
}

这样我们将缓存逻辑与错误处理(遵循单一责任原则)分开,并且能够分别重用/组合每个。所以当你添加这样的另一个函数时,你不必更改缓存函数。