Переменная оболочка для сессионного сопротивления - PullRequest
1 голос
/ 07 сентября 2011

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

Persistent< string > Name {get;set;} </p> <p>// reguest 1.</p> <p>Name = "A"; // in fact storing to session.. maybe Name.Value = "A" is necessary, not sure if implicit cast can be done here</p> <p>// reguest 2.</p> <p>return Name; // returns string "A", implicit conversion

Конечно, я бы сам реализовал это, прежде чем спрашивать, но я не могу придумать какой-либо хороший (последовательный и быстрый) способ определения ключей сеанса для переменных(как убедиться, что я получу одно и то же для Имени каждый раз, но разное для Эпохи, понимаешь ..)

Спасибо, Роман

Ответы [ 4 ]

2 голосов
/ 07 сентября 2011

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

 public int SomeProperty
 {
     get { return GetValueFor(x => x.SomeProperty); }
     set { SetValueFor(x => x.SomeProperty, value); }
 }

 protected T GetValueFor<T>(Expression<Func<ThisClass, T>> propertySelector)
 {
     string propertyName = // Get Value from expression.. to loo long to post here

     return (T)_session[propertyName];
 }

 protected SetValueFor<T>(Expression<Func<ThisClass, T>> propertySelector, object value)
 {
     string propertyName = // Get value from expression

     _session[propertyName] = value;
 }

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

1 голос
/ 07 сентября 2011

Что-то вроде этого:

private int CustomerID
{
    get
    {
        if( Session["CustomerID"] != null )
            return Convert.ToInt32( Session["CustomerID"] );
        else
            return 0;
    }
    set { Session["CustomerID"] = value; }
}

РЕДАКТИРОВАТЬ:

Альтернативой может быть что-то вроде этого:

public class Persist<T>
{
    private string ObjectName;

    public Persist( string Name )
    {
        ObjectName = Name;
    }

    public T Get()
    {
        return (T)(HttpContext.Current.Session[ObjectName]); 
    }

    public void Set(T value)
    {
        HttpContext.Current.Session[ObjectName] = value;
    }
}

показано, завернутый в простой класс Singleton.

public class SV
{
    private static readonly SV instance = new SV( );

    public Persist<DateTime> FiscalDate;
    public Persist<decimal> Revenue;

    private SV( )
    {
        FiscalDate = new Persist<DateTime>( "FiscalDate" );
        Revenue = new Persist<decimal>( "Revenue" );
    }

   public static SV Instance
   {
      get 
      {
         return instance; 
      }
   }
}

Использование, к сожалению, немного многословно.

protected void Page_Load( object sender, EventArgs e )
{
    if( !Page.IsPostBack )
    {
        SV.Instance.Revenue.Set( 1234567890M );
        SV.Instance.FiscalDate.Set( new DateTime( 2011, 3, 15 ) );
    }
}

protected void Button1_Click( object sender, EventArgs e )
{
    DateTime when = SV.Instance.FiscalDate.Get( );
    decimal amount = SV.Instance.Revenue.Get( );
}
0 голосов
/ 03 сентября 2012

Спасибо jim31415, и я упаковываю свою сессию следующим образом,

internal class SessionHelper {
    private void Set<T>(string key, T value) {
        HttpContext.Current.Session[key] = value;
    }
    private T Get<T>(string key) {
        return (T)HttpContext.Current.Session[key];
    }

    public int MemberID {
        get { return Get<int>("SK_MemberID"); }
        set { Set<int>("SK_MemberID", value); }
    }
    public string MemberAccount {
        get { return Get<string>("SK_MemberAccount"); }
        set { Set<string>("SK_MemberAccount", value); }
    }
    public string MemberDisplayName {
        get { return Get<string>("SK_MemberDisplayName"); }
        set { Set<string>("SK_MemberDisplayName", value); }
    }
    public string MemberGuid {
        get { return Get<string>("SK_MemberGuid"); }
        set { Set<string>("SK_MemberGuid", value); }
    }
}

При этой теме вспомогательный класс может быть объявлен с ключевым словом static.

0 голосов
/ 07 сентября 2011

Я думаю, вы могли бы сделать это одним из следующих способов:

public class Persistent<T>
{
    private readonly string _sessionKey;
    private static readonly bool _valueType;

    static Persistent()
    {
        _valueType = typeof(T).IsValueType;
    }

    public Persistent(T value = default(T))
    {
        _sessionKey = Guid.NewGuid().ToString();
        SetValue(value);
    }

    private void SetValue(T value)
    {
        var item = (_valueType)
          ? new PersistentWrapper { Value = value }
          : (object)value;

        HttpContext.Current.Session[_sessionKey] = item;
    }

    private T GetValue()
    {
        object item = HttpContext.Current.Session[_sessionKey];
        if (item != null)
        {
            if (_valueType) return ((PersistentWrapper)item).Value;

            return (T)item;
        }

        return default(T);
    }

    [Serializable]
    private class PersistentWrapper
    {
        public T Value { get; set; }
    }

    public static implicit operator T(Persistent<T> value)
    {
        if (value == null) return default(T);
        return value.GetValue();
    }

    public static implicit operator Persistent<T>(T value)
    {
        return new Persistent<T>(value);
    }
}

Что можно использовать как:

public class Person
{
    public Persistent<string> Name { get; set; }
    public Persistent<int> Age { get; set; }
}

При использовании:

var person = new Person();
person.Name = "Matt";
person.Age = 27;

Хотямне это кажется грязным ...

...