2011-09-07 3 views
1

나는 얼마 전 (어쩌면 엔터프라이즈 라이브러리에서) 멋진 것을 보았지만, 나는 이제 막 구글을 can not it it - 세션에 저장함으로써 영구적 인 변수 래퍼를 만들었다. . 이 같은 사용법 :세션 지속성을위한 가변 래퍼

물론 Persistent< string > Name {get;set;}

// reguest 1.

Name = "A"; // in fact storing to session.. maybe Name.Value = "A" is necessary, not sure if implicit cast can be done here

// reguest 2.

return Name; // returns string "A", implicit conversion

, 나는 이미 요청하기 전에 그것을 자신을 구현하는 것입니다,하지만 난 방법을 잘 만드는 변수에 대한 세션 키를 (결정하기 위해 어떤 (일관하고 빠른) 좋은 방법을 생각하지 못할, 나는 당신이 알고, 나이에 대한 이름마다 시간을 동일하지만 서로 다른를 얻을 것이다 ..)

고맙습니다,이 라인을 따라 로마

+0

당신은 세션 래퍼 객체를 만들려고하고 있습니까? – Tejs

답변

2

맞춤 세션 래퍼를 만들려면 표현을 사용하여 당신의 마술 문자열이 구형이 아닌지 확인하십시오.

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

그리고 세션 키가 무엇인가를 명확히하는 것을 잊지 말고' ThisClassInstance1.SomeProperty','ThatClassInstance1.SomeProperty','ThatClassInstance2.SomeProperty','ThisClassInstanceN.SomeProperty' 등 – LukeH

1

뭔가 :

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

: 대안이 같은 수 있습니다

.

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

네, 물론, 이것은 캡슐화하려는 간단한 해결책입니다. 왜냐하면 저는이 행동에 많은 변수가있을 것이고, 나는 DRY를 좋아할 것입니다. – rouen

-1

은 다음과 같습니다

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); 
    } 
} 
로 사용될 수

:

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

그냥 더러운 느낌이 있지만 : 사용과

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

나 ...

+0

이 해결책은 잘못되었습니다 - guid는 인스턴스가 생성 될 때마다 다를 것입니다 - 각 요청마다 ..이전 요청 처리에 저장된 값을 검색 할 수 없습니다. – rouen

0

감사합니다 jim31415 나는 다음과 같은 내 세션, this thread

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 키워드로 선언 할 수 있습니다 래퍼.

+1

좋은 접근! 오류가 발생하기 쉬운 캐스팅을 제거합니다. 하지만 HttpContextBase를 삽입하여 컨트롤러 나 서비스를 테스트 할 수 있도록 제안 할 것입니다. –

+0

SessionWrapper를 사용하려면'Set ()'과'Get ()'함수를 덮어 씀으로써 구현 될 수 있습니다. '테스트를 위해. – AechoLiu