Какой самый удобный способ добавить памятку в библиотеку пакетов - PullRequest
1 голос
/ 23 мая 2019

Предположим (полностью гипотетически;)), что у меня есть пакет 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 метода, я мог бы просто добавить частный статический словарь в класс расширения и в методе запросить у словаря ответ.

Но я бы очень хотел не дублировать столько кода, и есть действительно хорошая функция памятки:

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 голосов
/ 23 мая 2019

Вы можете использовать Fody / MethodCache

Run

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();
    }
}
...