views:

855

answers:

2

We have a base object we use for some MVC-like system, where each property in a descendant is written like this:

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

This is done both for debugging purposes and for notification and validation purposes. We use the getter to alert us of cases where code that has explicitly flagged what it is going to read (in order for the base class to be able to call it only when those properties change) and gets it wrong, and we use the setter for property change notifications, dirty-flag handling, validation, etc.

For simplicity, let's assume the implementation of these methods looks like this:

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;
}

There's more code in both of these of course, but this code is not relevant to my question, or at least I hope so. If it is, I'll modify the question.

Anyway, I'd like to write a PostSharp aspect that automatically implements the calls for me, on automatic properties, like this:

public String FirstName { get; set; }

Is there anyone out there that has some idea how I would go about doing this?

I have made OnMethodBoundaryAspect classes myself, but the art of calling the generic implementation with a ref parameter eludes me.

Here's the two classes, I'd like to augment the TestObject class to automatically call the correct method on property get and 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;
    }
}


Edit: Posted on PostSharp forum as well.

+1  A: 

Wonder if you would be better of asking this question on PostSharp forum instead...

mmiika
Believe me, I will, but I've found that there's not much the SO crowd collectively doesn't know :)
Lasse V. Karlsen
Right :) I'm a noob here... but wondering now when to ask here and when at a specific forum
mmiika
+1  A: 

It should be very simple. You override the OnEntry and set the return value based on your own code. At the end you use: eventArgs.ReturnValue = GetValue(x,y); eventArgs.FlowBehavior = FlowBehavior.Return; which will effectively intercept the original Get/Set calls.

Refer to this blog which shows the cache aspect using the same pattern...

Brian Adams