1 | using System;
|
---|
2 | using System.Collections.Generic;
|
---|
3 | using System.Text;
|
---|
4 | using System.Reflection;
|
---|
5 |
|
---|
6 | namespace Persistence {
|
---|
7 |
|
---|
8 | [AttributeUsage(
|
---|
9 | AttributeTargets.Field | AttributeTargets.Property,
|
---|
10 | AllowMultiple=false,
|
---|
11 | Inherited=false)]
|
---|
12 | public class AutoStorableAttribute : Attribute {
|
---|
13 |
|
---|
14 | private string name = null;
|
---|
15 | private object defaultValue = null;
|
---|
16 |
|
---|
17 | public string Name {
|
---|
18 | get { return this.name; }
|
---|
19 | set { this.name = value; }
|
---|
20 | }
|
---|
21 |
|
---|
22 | public object DefaultValue {
|
---|
23 | get { return this.defaultValue; }
|
---|
24 | set { this.defaultValue = value; }
|
---|
25 | }
|
---|
26 |
|
---|
27 | private const BindingFlags instanceMembers =
|
---|
28 | BindingFlags.Instance |
|
---|
29 | BindingFlags.Public |
|
---|
30 | BindingFlags.NonPublic;
|
---|
31 |
|
---|
32 | public static Dictionary<string, DataMemberAccessor> GetAutostorableAccessors(object obj) {
|
---|
33 | Dictionary<string, DataMemberAccessor> autoStorableAccessors =
|
---|
34 | new Dictionary<string, DataMemberAccessor>();
|
---|
35 | foreach (MemberInfo memberInfo in obj.GetType().GetMembers(instanceMembers)) {
|
---|
36 | foreach (object attribute in memberInfo.GetCustomAttributes(false)) {
|
---|
37 | AutoStorableAttribute autoStorableAttribute =
|
---|
38 | attribute as AutoStorableAttribute;
|
---|
39 | if (autoStorableAttribute != null) {
|
---|
40 | autoStorableAccessors.Add(memberInfo.Name,
|
---|
41 | new DataMemberAccessor(memberInfo, autoStorableAttribute, obj));
|
---|
42 | }
|
---|
43 | }
|
---|
44 | }
|
---|
45 | return autoStorableAccessors;
|
---|
46 | }
|
---|
47 | }
|
---|
48 |
|
---|
49 | public interface IDataMemberAccessor {
|
---|
50 | string Name { get; }
|
---|
51 | Type Type { get; }
|
---|
52 | object DefaultValue { get; }
|
---|
53 | object Get();
|
---|
54 | void Set(object value);
|
---|
55 | }
|
---|
56 |
|
---|
57 | public class DataMemberAccessor : IDataMemberAccessor {
|
---|
58 |
|
---|
59 | public delegate object Getter();
|
---|
60 | public delegate void Setter(object value);
|
---|
61 |
|
---|
62 | private string name;
|
---|
63 | private Type type;
|
---|
64 | private object defaultValue;
|
---|
65 | private Getter getter;
|
---|
66 | private Setter setter;
|
---|
67 |
|
---|
68 | public DataMemberAccessor(
|
---|
69 | MemberInfo memberInfo,
|
---|
70 | AutoStorableAttribute autoStorableAttribute,
|
---|
71 | object obj) {
|
---|
72 | if (memberInfo.MemberType == MemberTypes.Field) {
|
---|
73 | this.getter = () => ((FieldInfo)memberInfo).GetValue(obj);
|
---|
74 | this.setter = (value) => ((FieldInfo)memberInfo).SetValue(obj, value);
|
---|
75 | } else if (memberInfo.MemberType == MemberTypes.Property) {
|
---|
76 | this.getter = () => ((PropertyInfo)memberInfo).GetValue(obj, null);
|
---|
77 | this.setter = (value) => ((PropertyInfo)memberInfo).SetValue(obj, value, null);
|
---|
78 | } else {
|
---|
79 | throw new NotSupportedException(
|
---|
80 | "The AutoStorable attribute can only be applied to fields and properties.\n" +
|
---|
81 | "However, it was applied to a member of type " + memberInfo.MemberType.ToString());
|
---|
82 | }
|
---|
83 | this.name = autoStorableAttribute.Name != null ? autoStorableAttribute.Name : memberInfo.Name;
|
---|
84 | this.type = memberInfo.ReflectedType;
|
---|
85 | this.defaultValue = autoStorableAttribute.DefaultValue;
|
---|
86 | }
|
---|
87 |
|
---|
88 | public DataMemberAccessor(
|
---|
89 | string name, Type type, object defaultValue,
|
---|
90 | Getter getter, Setter setter) {
|
---|
91 | this.name = name;
|
---|
92 | this.type = type;
|
---|
93 | this.defaultValue = defaultValue;
|
---|
94 | this.getter = getter;
|
---|
95 | this.setter = setter;
|
---|
96 | }
|
---|
97 |
|
---|
98 | public string Name {
|
---|
99 | get { return this.name; }
|
---|
100 | }
|
---|
101 |
|
---|
102 | public Type Type {
|
---|
103 | get { return this.type; }
|
---|
104 | }
|
---|
105 |
|
---|
106 | public object DefaultValue {
|
---|
107 | get { return this.defaultValue; }
|
---|
108 | }
|
---|
109 |
|
---|
110 | public object Get() {
|
---|
111 | return this.getter();
|
---|
112 | }
|
---|
113 |
|
---|
114 | public void Set(object value) {
|
---|
115 | this.setter(value);
|
---|
116 | }
|
---|
117 |
|
---|
118 | public override string ToString() {
|
---|
119 | return String.Format("Property({0}, {1}, {2}, {3}, {4}",
|
---|
120 | this.name,
|
---|
121 | this.type == null ? "<null>" : this.type.FullName,
|
---|
122 | this.defaultValue == null ? "<null>" : this.defaultValue,
|
---|
123 | this.getter.Method,
|
---|
124 | this.setter.Method);
|
---|
125 | }
|
---|
126 | }
|
---|
127 |
|
---|
128 |
|
---|
129 |
|
---|
130 |
|
---|
131 | }
|
---|