Как реализовать атрибут кеша? - PullRequest
0 голосов
/ 14 мая 2011

Как я могу реализовать CacheAttribute, чтобы у меня была одинаковая логика для всех свойств в одном месте?

Я делаю это для кэширования

[TestClass]
public class All
{
    public string N
    {
        get
        {
            var value =
                MemoryCache.Default.Get("Website.Tests.All.N") as string;

            if (value != null)
            {
                return value;
            }

            value = DateTime.Now.ToString("HH:mm:ss.ffff");

            MemoryCache.Default.Add("Website.Tests.All.N", value,
                new CacheItemPolicy
                {
                    AbsoluteExpiration =
                        new DateTimeOffset(DateTime.Now.AddSeconds(5))
                });

            return value;
        }
    }

    [TestMethod]
    public void Extension()
    {
        var start = N;

        Thread.Sleep(1000);

        var end = N;

        Assert.AreEqual(start, end);
    }
}

И я хочу использовать это вместо

[TestClass]
public class All
{
    [Cache(Duration=5000)]
    public string N
    {
        get
        {
            return DateTime.Now.ToString("HH:mm:ss.ffff");
        }
    }

    [TestMethod]
    public void Extension()
    {
        var start = N;

        Thread.Sleep(1000);

        var end = N;

        Assert.AreEqual(start, end);
    }
}

Есть ли способ сделать этот синтаксис сахаром?

1 Ответ

0 голосов
/ 14 мая 2011

Похоже, вы хотите «принять» метод get для свойства, чтобы сначала проверить кеш, прежде чем возвращать «фактическое» значение из вашего свойства.Поскольку нет возможности осуществлять перехват свойств на разовой основе, вам придется заранее планировать эту возможность.

Одним из подходов было бы использование интерфейсов и запись ваших классов в интерфейс.Например,

public interface IAll 
{
    string N { get; set; }
}

Теперь вы можете использовать прокси для создания оболочки вокруг исходного экземпляра All, который также реализует этот интерфейс.Кроме того, так как вы полностью отвечаете за свойство сейчас, вы можете проверять кеш всякий раз, когда вызывается getter.Поскольку в вашем распоряжении будет PropertyInfo / MethodInfo, у вас не должно возникнуть проблем при создании уникального ключа для каждого свойства.

Поэтому, когда бы вы ни создавали экземпляр All, вы такжесоздать экземпляр этого прокси, передав ему экземпляр All.Все последующие использования этого экземпляра All должны вместо этого передаваться прокси.Как и любая реализация фабрики классов, для этого необходимо отказаться от использования оператора new .

В качестве альтернативы вы можете использовать виртуальные методы вместо интерфейсов.

...