Кто-нибудь пробовал реализовать C #.Автоматическое свойство, которое сохраняло бы значение в сеансе?

#c# #session #attributes #automatic-properties

#c# #сеанс #атрибуты #автоматические свойства

Вопрос:

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

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

Например.

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

вместо

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

Ответ №1:

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

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

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

Ответ №2:

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

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

http://www.sharpcrafters.com/

Ответ №3:

Вы не можете сделать это, используя автоматически реализованные свойства, как говорили другие. Но вы могли бы сделать что-то очень похожее, используя абстрактные свойства и 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 amp;amp; method.Name.StartsWith("get_");
        bool isSetter = method.IsSpecialName amp;amp; 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();
    }
}