uncategorized

EViL Decorating in the Igloo

Update #2:  JP called to tell me that this really isn’t a decorator pattern.  It’s actually the adapter pattern.  Like he said in his training course, identifying patterns in the wild is hard to do and takes a lot of practice.  Looks like I need a lot more practice.  He also asked about a factory class to create these items, and I figured that it would be nice if I put the one I had created up here too.

I’m working on some stuff for the EViL project again.  After my training last week, I’ve been looking at the work I do a little differently and this project is no different.  For me, the great thing about working on EViL is that it allows me to explore the depths of the System.Reflection namespace.  In the last couple of days I’ve found some interesting things.

I was working on some additions to allow for validation against private fields in classes and I noticed that the PropertyInfo and FieldInfo classes didn’t implement a common interface or base class that had the GetValue method on it.  In the end, I needed to be able to get all of the PropertyInfo and FieldInfo classes into one collection so that I could iterate through the values in search of matches to perform validation on.  Here’s how I went about it.  Now, it may not be the best way.  I may not have named this right.  Regardless, this solved the problem for me and I figured I’d share it.

In the end what I did was wrap the PropertyInfo and FieldInfo classes in a SmartPropertyInfo and SmartFieldInfo Decorator Adapter classes.  By creating the wrapper, and it’s correlating interface, I was able to make both PropertyInfo and FieldInfo data look and behave the same.  EViL is now completely agnostic to the classes that are provided by reflection.

Update:  After an email from David Woods I decided to implement one more level of refactoring to clean this up even more.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
public class SmartPropertyInfo : ISmartMethodInfo
{
private readonly PropertyInfo propertyInfo;

public SmartPropertyInfo(PropertyInfo info)
{
this.propertyInfo = info;
}

public string Name
{
get
{
return propertyInfo.Name;
}
}

public Type PropertyType
{
get
{
return propertyInfo.PropertyType;
}
}

public object GetValue(object entity, object[] index)
{
return propertyInfo.GetValue(entity, index);
}
}

public class SmartFieldInfo : ISmartMethodInfo
{
private readonly FieldInfo fieldInfo;

public SmartFieldInfo(FieldInfo info)
{
this.fieldInfo = info;
}

public string Name
{

get

{

return fieldInfo.Name;

}

}


public Type PropertyType

{

get

{

return fieldInfo.FieldType;

}

}


public object GetValue(object entity, object[] index)

{

return fieldInfo.GetValue(entity);

}

}
public static class PropertyFactory
{
public static IList<ISmartMethodInfo> GetProperties(object entity)
{
IList<ISmartMethodInfo> results = new List<ISmartMethodInfo>();

GetReflectedProperties(entity, results);

GetReflectedFields(entity, results);

return results;
}

private static void GetReflectedProperties(object entity, IList<ISmartMethodInfo> values)
{
PropertyInfo[] properties = entity.GetType().GetProperties();
foreach (PropertyInfo info in properties)
{
ISmartMethodInfo smartMethodInfo = new SmartPropertyInfo(info);
values.Add(smartMethodInfo);
}
}

private static void GetReflectedFields(object entity, IList<ISmartMethodInfo> values)
{
FieldInfo[] fields = entity.GetType().GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Static);

foreach (FieldInfo info in fields)
{
ISmartMethodInfo smartMethodInfo = new SmartFieldInfo(info);
values.Add(smartMethodInfo);
}
}
}