Question

I like using c# Auto-Property in code as I found it much more nicer. Recently got an idea how I would manage to use Auto-Property, but store the value in Session. Simply for few reason: - avoid typos in Session item name - avoid extra code - possibly for extending to other stores like ViewState, etc.

So far I am thinking the Attribute would be the best option. Just curious if someone tried this before I dig in and start implementing it.

E.g.

[Session] 
public int Id{get;set;}

instead of

public int Id{ get{return Session["Id"];} set{Session["Id"] = value;}}
Was it helpful?

Solution

No, you can't do this.

Automatically implemented properties only work when the desired implementation is a "trivial" property backed by a field. That's all that's supported by the compiler. Just about the only way you can "tweak" an automatically implemented property is to set the accessibility of the getter and the setter differently.

Now of course you could write code to automatically load the value from the session on creation and save it to the session on a particular method call - but that's not really the same thing.

OTHER TIPS

You can't do this in vanilla C#, but you could get the effect you are after through aspects.

Postsharp is a good starting point for AOP:

http://www.sharpcrafters.com/

You can't do this using automatically implemented properties, as others said. Butyou could do something very similar using abstract properties and Castle DynamicProxy (or similar).

For example, you could have code like this:

public abstract class Foo : IWithSession
{
    public IDictionary<string, object> Session { get; private set; }

    protected Foo()
    {
        Session = new Dictionary<string, object>();
    }

    [Session]
    public abstract int Id { get; set; }
}

The interceptor that would actually implement the getter and setter would look like this:

class SessionInterceptor : IInterceptor
{
    public void Intercept(IInvocation invocation)
    {
        var method = invocation.Method;

        bool isGetter = method.IsSpecialName && method.Name.StartsWith("get_");
        bool isSetter = method.IsSpecialName && method.Name.StartsWith("set_");

        if (isGetter || isSetter)
        {
            string propertyName = method.Name.Substring(4);

            var property = invocation.TargetType.GetProperty(propertyName);

            bool hasSessionAttribute = property.GetCustomAttributes(typeof(SessionAttribute), false).Any();

            if (hasSessionAttribute)
            {
                var session = ((IWithSession)invocation.InvocationTarget).Session;

                if (isGetter)
                {
                    invocation.ReturnValue = session[propertyName];
                    return;
                }
                else
                {
                    session[propertyName] = invocation.Arguments[0];
                    return;
                }
            }
        }

        invocation.Proceed();
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top