@@ -10,40 +10,127 @@ namespace Topics.Radical.Validation
1010 /// </summary>
1111 public static class Ensure
1212 {
13+ #if DEBUG
14+ static SourceInfoLoadStrategy _sourceInfoLoadStrategy = SourceInfoLoadStrategy . Load ;
15+ #else
16+ static SourceInfoLoadStrategy _sourceInfoLoadStrategy = SourceInfoLoadStrategy . Skip ;
17+ #endif
18+
19+ /// <summary>
20+ /// Determines if the Ensure class tries to load the Stack before moving on.
21+ /// </summary>
22+ public static SourceInfoLoadStrategy SourceInfoLoadStrategy
23+ {
24+ get { return _sourceInfoLoadStrategy ; }
25+ set { _sourceInfoLoadStrategy = value ; }
26+ }
27+
1328 internal class SourceInfo
1429 {
1530 public readonly static SourceInfo Empty = new SourceInfo ( "" , "" , MemberTypes . Custom ) ;
1631
32+ private StackFrame frame ;
33+ private bool lazy ;
34+ private bool loaded ;
35+
36+ private MemberTypes _sourceType ;
37+ private string _className ;
38+ private string _methodName ;
39+
40+ public static SourceInfo FromStack ( StackTrace st , bool lazy )
41+ {
42+ SourceInfo si = SourceInfo . Empty ;
43+ if ( st . FrameCount > 0 )
44+ {
45+ var frame = st . GetFrame ( 0 ) ;
46+ si = new SourceInfo ( frame , lazy ) ;
47+ }
48+
49+ return si ;
50+ }
51+
1752 /// <summary>
1853 /// Initializes a new instance of the <see cref="SourceInfo"/> class.
1954 /// </summary>
2055 /// <param name="methodName">Name of the method.</param>
2156 /// <param name="className">Name of the class.</param>
2257 /// <param name="sourceType">Type of the source.</param>
23- public SourceInfo ( String methodName , String className , MemberTypes sourceType )
58+ private SourceInfo ( String methodName , String className , MemberTypes sourceType )
2459 {
25- this . MethodName = methodName ;
26- this . ClassName = className ;
27- this . SourceType = sourceType ;
60+ this . _methodName = methodName ;
61+ this . _className = className ;
62+ this . _sourceType = sourceType ;
63+ }
64+
65+ private SourceInfo ( StackFrame frame , bool lazy )
66+ {
67+ this . frame = frame ;
68+ this . lazy = lazy ;
69+ if ( ! this . lazy )
70+ {
71+ this . EnsureDataAreLoaded ( ) ;
72+ }
73+ }
74+
75+ void EnsureDataAreLoaded ( )
76+ {
77+ if ( ! this . loaded )
78+ {
79+ var mi = this . frame . GetMethod ( ) ;
80+ if ( mi != null )
81+ {
82+ this . _methodName = mi . Name ;
83+ this . _className = mi . DeclaringType . Name ;
84+ this . _sourceType = mi . MemberType ;
85+ }
86+ else
87+ {
88+ this . _methodName = SourceInfo . Empty . MethodName ;
89+ this . _className = SourceInfo . Empty . ClassName ;
90+ this . _sourceType = SourceInfo . Empty . SourceType ;
91+ }
92+
93+ this . loaded = true ;
94+ }
2895 }
2996
3097 /// <summary>
3198 /// Gets the name of the method.
3299 /// </summary>
33100 /// <value>The name of the method.</value>
34- public String MethodName { get ; private set ; }
101+ public String MethodName
102+ {
103+ get
104+ {
105+ this . EnsureDataAreLoaded ( ) ;
106+ return this . _methodName ;
107+ } }
35108
36109 /// <summary>
37110 /// Gets the name of the class.
38111 /// </summary>
39112 /// <value>The name of the class.</value>
40- public String ClassName { get ; private set ; }
113+ public String ClassName
114+ {
115+ get
116+ {
117+ this . EnsureDataAreLoaded ( ) ;
118+ return this . _className ;
119+ }
120+ }
41121
42122 /// <summary>
43123 /// Gets the type of the source.
44124 /// </summary>
45125 /// <value>The type of the source.</value>
46- public MemberTypes SourceType { get ; private set ; }
126+ public MemberTypes SourceType
127+ {
128+ get
129+ {
130+ this . EnsureDataAreLoaded ( ) ;
131+ return this . _sourceType ;
132+ }
133+ }
47134 }
48135
49136 /// <summary>
@@ -54,25 +141,40 @@ public SourceInfo( String methodName, String className, MemberTypes sourceType )
54141 /// <param name="obj">The object value to inspect.</param>
55142 /// <returns>The Ensure instance for fluent interface usage.</returns>
56143 public static IConfigurableEnsure < T > That < T > ( T obj )
144+ {
145+ return That < T > ( obj , Ensure . SourceInfoLoadStrategy ) ;
146+ }
147+
148+ /// <summary>
149+ /// Initialize a new instance of the generic Ensure class using the supplied
150+ /// value as the value to insepct.
151+ /// </summary>
152+ /// <typeparam name="T">The type of the inepcted object value.</typeparam>
153+ /// <param name="obj">The object value to inspect.</param>
154+ /// <param name="strategy">Determines if the Ensure instance should load the current Stack.</param>
155+ /// <returns>The Ensure instance for fluent interface usage.</returns>
156+ public static IConfigurableEnsure < T > That < T > ( T obj , SourceInfoLoadStrategy strategy )
57157 {
58158 var si = SourceInfo . Empty ;
59159
60160#if ! SILVERLIGHT
61161
62- var st = new StackTrace ( 1 ) ;
63- if ( st . FrameCount > 0 )
162+ if ( strategy != Validation . SourceInfoLoadStrategy . Skip )
64163 {
65- var f = st . GetFrame ( 0 ) ;
66- var mi = f . GetMethod ( ) ;
67- if ( mi != null )
68- {
69- si = new SourceInfo ( mi . Name , mi . DeclaringType . Name , mi . MemberType ) ;
70- }
164+ var lazy = strategy == Validation . SourceInfoLoadStrategy . LazyLoad ;
165+ si = SourceInfo . FromStack ( new StackTrace ( 1 ) , lazy : lazy ) ;
71166 }
72167
73168#endif
74169
75170 return new Ensure < T > ( obj , si ) ;
76171 }
77172 }
173+
174+ public enum SourceInfoLoadStrategy
175+ {
176+ Load = 0 ,
177+ Skip ,
178+ LazyLoad
179+ }
78180}
0 commit comments