我很确定我前段时间看到了很好的东西(可能在企业库中,不确定),但我现在不能谷歌 - 通用变量包装器通过将其存储在会话中来使其持久化。用法如下:
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 :(得分: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 :(得分: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;
}
}
这显示为一个简单的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( );
}
答案 2 :(得分:0)
感谢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); }
}
}
使用this thread,可以使用static
关键字声明帮助程序类。
答案 3 :(得分:-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);
}
}
可以用作:
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;
虽然对我来说只是感觉很脏......