#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:
Ответ №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();
}
}