Кто-нибудь пытался реализовать C # .Auto-Property, который будет хранить значение в сеансе? - PullRequest
1 голос
/ 10 ноября 2011

Мне нравится использовать c-Auto-Property в коде, так как я нахожу это намного приятнее. Недавно я понял, как мне удастся использовать Auto-Property, но сохранить значение в Session. Просто по нескольким причинам: - избегайте опечаток в имени элемента сессии - избегайте лишнего кода - возможно для распространения на другие магазины, такие как ViewState и т. д.

Пока что я думаю, что Атрибут будет лучшим вариантом. Просто любопытно, если бы кто-то попробовал это, прежде чем я начну копаться и начну это реализовывать.

например.

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

вместо

public int Id{ get{return Session["Id"];} set{Session["Id"] = value;}}

Ответы [ 3 ]

4 голосов
/ 10 ноября 2011

Нет, вы не можете этого сделать.

Автоматически реализованные свойства только работают, когда желаемая реализация является «тривиальным» свойством, поддерживаемым полем. Это все, что поддерживается компилятором. Почти единственный способ, которым вы можете «настроить» автоматически реализованное свойство, - это установить доступность метода получения и установки по-разному.

Теперь, конечно, вы могли бы написать код для автоматической загрузки значения из сеанса при создании и сохранения его в сеансе при вызове определенного метода - но это не совсем то же самое.

1 голос
/ 10 ноября 2011

Вы не можете сделать это, используя автоматически реализованные свойства, как говорили другие.Но вы могли бы сделать что-то очень похожее, используя абстрактные свойства и Castle DynamicProxy (или аналогичный).

Например, вы могли бы получить код, подобный следующему:

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

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

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();
    }
}
1 голос
/ 10 ноября 2011

Вы не можете сделать это в vanilla C #, но вы можете получить эффект, который вам нужен, благодаря аспектам.

Postsharp - хорошая отправная точка для AOP:

http://www.sharpcrafters.com/

...