将备忘录添加到包库的最巧妙的方法是什么

时间:2019-05-23 06:59:01

标签: c# nuget-package memoization

假设(完全假设为;))我有nuget包,该包实际上公开了一组静态扩展方法:

public static class MyNugetLibrary
{
    public static int DoSomethingExpensiveAndUseful(this string input)
    {
        return input.Length;
    }

    public static int DoSomethingElseExpensiveAndUseful(this string input)
    {
        return (int)input.ToCharArray().First();
    }
}

并且,出于理智的原因,我得出结论,该程序包真正需要的是缓存。给定输入,输出是恒定的,而输入则是原始的。

就我而言,没有任何可能的方式来更改输出,因此我永远不必担心缓存无效等。

如果只有1个或2个方法,我可以在扩展类中添加一个私有静态Dictionary,然后在方法中向字典询问答案。

但是我很想不重复太多代码,并且有一个非常好的备忘录功能:

public static Func<T, TResult> Memoize<T, TResult>(this Func<T, TResult> f)
{
    var cache = new ConcurrentDictionary<T, TResult>();
    return a => cache.GetOrAdd(a, f);
}

(从这里被盗:https://www.aleksandar.io/post/memoization/

但是我不能完全弄清楚如何使用该方法来使这些功能记忆化,而无需更改程序包的外部接口。

我该怎么做?


如果我们可以进一步做到这一点,则可以使用大量奖励积分,以便最终用户(MyNugetLibrary.DisableCaching())可以在他们担心的情况下禁用缓存,例如内存占用。

1 个答案:

答案 0 :(得分:0)

您可以使用Fody / MethodCache

运行

Install-Package Fody
Install-Package MethodCache.Fody

然后,您可以将方法更改为:

public interface ICache
{
    bool Contains(string key);
    T Retrieve<T>(string key);
    void Store(string key, object data);
    void Remove(string key);
}

public static class MyNugetLibrary
{
    public static ICache Cache { get; set; } = DefaultCache;

    public readonly static ICache DefaultCache = new MemoryCache();
    public readonly static ICache NoCache = new UnCache();
    [Cache]
    public static int DoSomethingExpensiveAndUseful(this string input)
    {
        return input.Length;
    }
    [Cache]
    public static int DoSomethingElseExpensiveAndUseful(this string input)
    {
        return (int)input.ToCharArray().First();
    }
}