PostSharp - динамические ключи кэша - PullRequest
1 голос
/ 11 июня 2011

Я пытаюсь использовать CacheAttribute для PostSharp .

Ниже приведен метод, который я использую для создания ключей кэша для каждой записи в кэше.

    private string BuildCacheKey(Arguments arguments)
    {
        var sb = new StringBuilder();
        sb.Append(_methodName);
        foreach (var argument in arguments.ToArray())
        {
            sb.Append(argument == null ? "_" : argument.ToString());
        }
        return sb.ToString();
    }

Ниже приведен пример класса, который я использую.

class State
{
    public string Code { get; set; }
    public string Name { get; set; }
}

И метод, который необходимо кэшировать:

    [Cache]
    private static IDictionary<string, string> GetStateRegions(IEnumerable<State> states)
    {
        //some db call here to retrieve values;
    }

И вот как я вызываю метод:

        IList<State> states = new List<State>();

        states.Add( new State {Code = "NM", Name = "New Mexico"});
        states.Add(new State {Code = "CA", Name = "California"});  

        GetStateRegions(states);

Метод BuildCacheKey создает следующий ключ кэша - "GetStateRegionsSystem.Collections.Generic.List`1 [ConsoleApplication1.State]"

Мне бы хотелосьчтобы в ключе кеша было что-то наподобие «GetStateRegions [ConsoleApplication1.State]» - например, для указанного выше вызова - «GetStateRegionsNMCA [ConsoleApplication1.State]» * для кодов состояний NM и CA.* Что было бы хорошим подходом для достижения этой цели?Также возможно ли использовать разную логику для построения ключей для разных методов (в зависимости от типа аргументов метода)?Буду очень признателен за любые указания / предложения.

1 Ответ

1 голос
/ 11 июня 2011

Проблема, с которой вы столкнетесь, заключается в том, что вы не будете знать, каковы аргументы, если, конечно, вы не используете это только для одного метода. Вы можете использовать MethodInfo.Name в операторе switch, если хотите изменить стратегию клавиш. Возможно, вы захотите использовать делегат и указать метод построения ключа при объявлении аспекта.

Вы можете попробовать использовать

if(Argument is List<State>) 
{
 //gen key based ons tates
} else
{
//gen key based on ToString()
}

Вы всегда можете отразить в аргументе, чтобы получить значение вместо ToString ()

[serializable]
public class MyAspect : OnMethodBoundaryAspect
{
   public MyKeyBuilderDelegate KeyBuildMethod;

  ...
}

затем объявите аспект как

[MyAspect(KeyBuilderMethod = BuildByState)]
public void MyMethod() { ... }
...