Reputation: 5124
i am pretty sure i saw nice thing some time ago (maybe in Enterprise library, not sure), but i just cant google it now - generic variable wrapper for making it persistent by storing it in session. Usage like this:
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
of course, I would implement it myself already before asking, but i cant think of any good (consistent and fast) way to determine session keys for variables (how to make sure, I will get the same for the Name every time, but different for Age, you know..)
Thanx, Roman
Upvotes: 1
Views: 978
Reputation: 18378
Thanks jim31415 and I wrapper my session like followings,
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); }
}
}
With this thread, the helper class can be declared with static
keyword.
Upvotes: 0
Reputation: 8808
Something along these lines:
private int CustomerID
{
get
{
if( Session["CustomerID"] != null )
return Convert.ToInt32( Session["CustomerID"] );
else
return 0;
}
set { Session["CustomerID"] = value; }
}
EDIT:
An alternative might be something like this:
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;
}
}
This is shown wrapped into a simple Singleton class.
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;
}
}
}
Usage is a bit wordy, unfortunately.
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( );
}
Upvotes: 1
Reputation: 61589
I guess one way you could do it is:
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);
}
}
Which could be used as:
public class Person
{
public Persistent<string> Name { get; set; }
public Persistent<int> Age { get; set; }
}
With usage:
var person = new Person();
person.Name = "Matt";
person.Age = 27;
Although it just feels dirty to me...
Upvotes: -1
Reputation: 41236
If you're going to make a custom session wrapper, I would suggest using an expression to make sure your magic strings don't get outdated.
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;
}
This way, all your properties are just mapped on the session object in a strongly typed way, and if you ever refactor, you dont have to worry about magic strings.
Upvotes: 2