Аспект PostSharp для установщиков свойств, вызывающий общий метод

У нас есть базовый объект, который мы используем для некоторой 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, чтобы он автоматически вызывал правильный метод для получения и установки свойства.

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.


person Lasse V. Karlsen    schedule 29.10.2008    source источник


Ответы (1)


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

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

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

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

person Brian Adams    schedule 03.11.2008