Аспект PostSharp для установщиков свойств, вызывающий универсальный метод - PullRequest
2 голосов
/ 29 октября 2008

У нас есть базовый объект, который мы используем для некоторой MVC-подобной системы, где каждое свойство в потомке записывается так:

public String FirstName
{
    get { return GetProperty<String>("FirstName", ref _FirstName); }
    set { SetProperty<String>("FirstName", ref _FirstName, value); }
}

Это делается как в целях отладки, так и в целях уведомления и проверки. Мы используем метод получения, чтобы предупредить нас о случаях, когда код явно помечал то, что он собирается прочитать (для того, чтобы базовый класс мог вызывать его только при изменении этих свойств), и ошибался, и мы используем установщик для уведомлений об изменении свойств, обработки грязных флагов, проверки и т. д.

Для простоты предположим, что реализация этих методов выглядит следующим образом:

protected T GetProperty<T>(String propertyName,
    ref T backingField)
{
    return backingField;
}

protected Boolean SetProperty<T>(String propertyName,
    ref T backingField,
    T newValue)
{
    backingField = newValue;
    return true;
}

В обоих случаях, конечно, есть больше кода, но этот код не имеет отношения к моему вопросу, или, по крайней мере, я на это надеюсь. Если это так, я изменю вопрос.

В любом случае, я хотел бы написать аспект PostSharp, который автоматически реализует вызовы для меня, на автоматических свойствах, например:

public String FirstName { get; set; }

Есть ли кто-нибудь, кто знает, как мне поступить?

Я сам создал классы OnMethodBoundaryAspect, но искусство вызова универсальной реализации с параметром ref ускользает от меня.

Вот два класса, я хотел бы расширить класс TestObject, чтобы автоматически вызывать правильный метод для свойства get и set.

public class BaseObject
{
    protected T GetProperty<T>(String propertyName,
        ref T backingField)
    {
        return backingField;
    }

    protected Boolean SetProperty<T>(String propertyName,
        ref T backingField,
        T newValue)
    {
        backingField = newValue;
    }
}

public class TestObject : BaseObject
{
    public String FirstName
    {
        get;
        set;
    }

    public String LastName
    {
        get;
        set;
    }
}

Редактировать: Размещено на PostSharp форум .

1 Ответ

2 голосов
/ 04 ноября 2008

Это должно быть очень просто. Вы переопределяете OnEntry и устанавливаете возвращаемое значение на основе вашего собственного кода. В конце вы используете:

eventArgs.ReturnValue = GetValue(x,y);  
eventArgs.FlowBehavior = FlowBehavior.Return;

, который будет эффективно перехватывать исходные вызовы Get / Set.

См. этот блог , который показывает аспект кэша, используя тот же шаблон ...

...