4

我正在尝试创建一个通用的 CacheManager ,我可以在我的整个应用程序中使用它,这将确保缓存项的所有管理都以一致的方式完成并遵守一些缓存访问模式。这将用于根据需要缓存所有类型的对象。

我知道我可以使用委托将函数传递给方法,您可以在下面看到。

public static T GetGlobalCacheitem( Func<int ,int , T> populateCacheCall )
        {
            string cacheKey = "test";
            var cachedObject = CacheFactory<T>.GlobalCache.GetGlobalCacheItem(cacheKey);

            if (cachedObject == null)
            {
                cachedObject =  populateCacheCall();
                CacheFactory<T>.GlobalCache.AddGlobalCacheItem(cachedObject, cacheKey);
            }
            return cachedObject;
        }

但是我有两个问题。

  1. 我想传入以填充缓存的大多数函数本身都具有他们需要的参数。在上面的例子中,这是一个需要两个 int 参数的方法。第一个问题是我怎样才能传入我希望调用函数的参数,因为它们在这个缓存处理程序中是不知道的,在这个缓存处理程序之外是知道的。也这与下一个问题二有关,无论函数需要多少参数(如果有的话),我如何才能在一种方法中做到这一点?

  2. 第二个问题是我需要传入的很多用于填充缓存项的函数会有所不同,有些没有参数,有些只有一个,有些可能不止一个,而且每个函数的类型都不同。这些参数中的一些会有所不同。那么我如何能够使其工作而不必定义一个具有所有可能签名的函数,该函数将涵盖支付给我使用的所有可能的函数组合。

4

4 回答 4

3

如果函数的参数将填充 GetGlobalCacheitem 方法之外,您可以使用另一个委托来欺骗调用函数,如下所示:

public static T GetGlobalCacheitem<T>(Func<T> populateCacheCall)

并称之为:

Func<int ,int , object> tempPopulateCacheCall=(a,b)=>new object();

GetGlobalCacheitem(()=>tempPopulateCacheCall(1,2))

或任何其他具有可变参数的函数签名

Func<int , object> tempPopulateCacheCall=(a)=>new object();

GetGlobalCacheitem(()=>tempPopulateCacheCall(1))
于 2013-02-18T12:36:21.803 回答
0

我认为 Reza Arab 提出的结构很好,因为它符合您的想法。但是,在我看来,拥有全局缓存是不可取的,特别是因为它使有效的垃圾收集变得困难(除非您对缓存对象使用弱引用。但是重复创建和删除的对象呢?在这种情况下,弱引用将禁止有效缓存)。

于 2013-02-18T14:18:13.907 回答
0

您可以将List<P>参数作为第一个参数传递,或Tuple<P>用作您的参数。

还尝试从函数和参数的哈希码中制作全局缓存键。

如果我理解正确,您可能会在 Dapper Identity 函数中找到一些代码SqlMapper

于 2013-02-18T12:30:17.967 回答
0

您可以创建一个类,该类将封装函数参数,以便您可以从此类实例调用此函数而无需任何参数。这些参数的参数将被放入构造函数中:

interface ICachedFunction<out T>
{
    T Invoke();
}

class CustomFunctionWithVariousParameters<T> : ICachedFunction<T>
{
    private readonly Func<int, string, T> _function;
    private readonly int _parameter1;
    private readonly string _parameter2;

    public CustomFunctionWithVariousParameters(int parameter1, string parameter2, Func<int, string, T> function)
    {
        _function = function;
        _parameter1 = parameter1;
        _parameter2 = parameter2;
    }

    public T Invoke()
    {
        return _function(_parameter1, _parameter2);
    }
}

现在您可以在您的方法中使用此解决方案:

public static T GetGlobalCacheitem( ICachedFunction<T> populateCacheCall )

希望这种方法会有所帮助。

于 2013-02-18T12:33:38.517 回答