Imagine the following class:
public class Settings
{
[FileBackedProperty("foo.txt")]
public string Foo { get; set; }
}
I would like to be able to write something similar to the above and have settings.Foo
read from the file "foo.txt" and settings.Foo = "bar"
write to "foo.txt".
Obviously this is a simplified example and I wouldn't do the above in a production application, but there are other examples, like if I wanted Foo to be stored in ASP.net Session state "foo" but I get tired of writing the following code over and over:
public int Foo
{
get
{
if (Session["foo"] != null)
return Convert.ToInt32(Session["foo"]);
else
// Throw an exception or return a default value
}
set
{
Session["foo"] = value;
}
}
(Once again this example is simplified and I wouldn't write the above code, actually I'm lying, I have the above code and am working to refactor it, thus this question)
The above example is fine unless you have 50 different session values that all have similar logic. So is there someway I could convert the second property into something similar to the first? (Using attributes and reflection, or maybe some other method?)
I know this is not what you (and also I) needed; but this is the closest without using a third party library. You can change the logic for get&set methods and add some cahcing for GetProperty and GetCustomAttributes methods or if you already have a base class you can write get&set methods as static in a helper class. Again not the perfect answer and also may have a bad performance but at least it decreases the code you copy and paste (:
NOTE: It is important to make properties virtual in order to prevent compiler inlining them.
public class SampleClass : SessionObject
{
[Session(Key = "SS_PROP")]
public virtual int SampleProperty
{
get { return get(); }
set { set(value); }
}
[Session(Key = "SS_PROP2")]
public virtual string SampleProperty2
{
get { return get(); }
set { set(value); }
}
}
[AttributeUsage(AttributeTargets.Property)]
public class SessionAttribute : Attribute
{
public string Key { get; set; }
}
public abstract class SessionObject
{
Dictionary<string, object> Session = new Dictionary<string, object>();
protected void set(object value)
{
StackFrame caller = new StackFrame(1);
MethodBase method = caller.GetMethod();
string propName = method.Name.Substring(4);
Type type = method.ReflectedType;
PropertyInfo pi = type.GetProperty(propName);
object[] attributes = pi.GetCustomAttributes(typeof(SessionAttribute), true);
if (attributes != null && attributes.Length == 1)
{
SessionAttribute ssAttr = attributes[0] as SessionAttribute;
Session[ssAttr.Key] = value;
}
}
protected dynamic get()
{
StackFrame caller = new StackFrame(1);
MethodBase method = caller.GetMethod();
string propName = method.Name.Substring(4);
Type type = method.ReflectedType;
PropertyInfo pi = type.GetProperty(propName);
object[] attributes = pi.GetCustomAttributes(typeof(SessionAttribute), true);
if (attributes != null && attributes.Length == 1)
{
SessionAttribute ssAttr = attributes[0] as SessionAttribute;
if (Session.ContainsKey(ssAttr.Key))
{
return Session[ssAttr.Key];
}
}
return default(dynamic);
}
}
Another option could be for you is use of PostSharp.
You define attributes and it injects an IL
in final code, so it's not going to change your source code. Which has its bads and its goods.
This product is not free.
Some Getting started tips.
Hope this helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With