@@ -24,17 +24,22 @@ public sealed class ValidationRuleSet : IEnumerable<ValidationRule>
24
24
/// <summary>
25
25
/// Gets the default validation rule sets.
26
26
/// </summary>
27
- public static ValidationRuleSet DefaultRuleSet
27
+ /// <remarks>
28
+ /// This is a method instead of a property to signal that a new default ruleset object is created
29
+ /// per call. Making this a property may be misleading callers to think the returned rulesets from multiple calls
30
+ /// are the same objects.
31
+ /// </remarks>
32
+ public static ValidationRuleSet GetDefaultRuleSet ( )
28
33
{
29
- get
34
+ // Reflection can be an expensive operation, so we cache the default rule set that has already been built.
35
+ if ( _defaultRuleSet == null )
30
36
{
31
- if ( _defaultRuleSet == null )
32
- {
33
- _defaultRuleSet = BuildDefaultRuleSet ( ) ;
34
- }
35
-
36
- return _defaultRuleSet ;
37
+ _defaultRuleSet = BuildDefaultRuleSet ( ) ;
37
38
}
39
+
40
+ // We create a new instance of ValidationRuleSet per call as a safeguard
41
+ // against unintentional modification of the private _defaultRuleSet.
42
+ return new ValidationRuleSet ( _defaultRuleSet ) ;
38
43
}
39
44
40
45
/// <summary>
@@ -44,51 +49,68 @@ public ValidationRuleSet()
44
49
{
45
50
}
46
51
52
+ /// <summary>
53
+ /// Initializes a new instance of the <see cref="ValidationRuleSet"/> class.
54
+ /// </summary>
55
+ /// <param name="ruleSet">Rule set to be copied from.</param>
56
+ public ValidationRuleSet ( ValidationRuleSet ruleSet )
57
+ {
58
+ if ( ruleSet == null )
59
+ {
60
+ return ;
61
+ }
62
+
63
+ foreach ( ValidationRule rule in ruleSet )
64
+ {
65
+ Add ( rule ) ;
66
+ }
67
+ }
68
+
47
69
/// <summary>
48
70
/// Initializes a new instance of the <see cref="ValidationRuleSet"/> class.
49
71
/// </summary>
50
72
/// <param name="rules">Rules to be contained in this ruleset.</param>
51
73
public ValidationRuleSet ( IEnumerable < ValidationRule > rules )
52
74
{
53
- if ( rules ! = null )
75
+ if ( rules = = null )
54
76
{
55
- foreach ( ValidationRule rule in rules )
56
- {
57
- Add ( rule ) ;
58
- }
77
+ return ;
78
+ }
79
+
80
+ foreach ( ValidationRule rule in rules )
81
+ {
82
+ Add ( rule ) ;
59
83
}
60
84
}
61
85
62
86
/// <summary>
63
87
/// Gets the rules in this rule set.
64
88
/// </summary>
65
- public IEnumerable < ValidationRule > Rules
89
+ public IList < ValidationRule > Rules
66
90
{
67
91
get
68
92
{
69
- return _rules . Values . SelectMany ( v => v ) ;
93
+ return _rules . Values . SelectMany ( v => v ) . ToList ( ) ;
70
94
}
71
95
}
72
96
73
97
/// <summary>
74
- /// Add the new rule into rule set.
98
+ /// Add the new rule into the rule set.
75
99
/// </summary>
76
100
/// <param name="rule">The rule.</param>
77
101
public void Add ( ValidationRule rule )
78
102
{
79
- IList < ValidationRule > typeRules ;
80
- if ( ! _rules . TryGetValue ( rule . ElementType , out typeRules ) )
103
+ if ( ! _rules . ContainsKey ( rule . ElementType ) )
81
104
{
82
- typeRules = new List < ValidationRule > ( ) ;
83
- _rules [ rule . ElementType ] = typeRules ;
105
+ _rules [ rule . ElementType ] = new List < ValidationRule > ( ) ;
84
106
}
85
107
86
- if ( typeRules . Contains ( rule ) )
108
+ if ( _rules [ rule . ElementType ] . Contains ( rule ) )
87
109
{
88
110
throw new OpenApiException ( SRResource . Validation_RuleAddTwice ) ;
89
111
}
90
112
91
- typeRules . Add ( rule ) ;
113
+ _rules [ rule . ElementType ] . Add ( rule ) ;
92
114
}
93
115
94
116
/// <summary>
@@ -97,7 +119,7 @@ public void Add(ValidationRule rule)
97
119
/// <returns>The enumerator.</returns>
98
120
public IEnumerator < ValidationRule > GetEnumerator ( )
99
121
{
100
- foreach ( List < ValidationRule > ruleList in _rules . Values )
122
+ foreach ( var ruleList in _rules . Values )
101
123
{
102
124
foreach ( var rule in ruleList )
103
125
{
0 commit comments