4
4
using System ;
5
5
using System . Collections ;
6
6
using System . Collections . Generic ;
7
+ using System . Linq ;
7
8
using Microsoft . Framework . Internal ;
8
9
9
10
namespace Microsoft . AspNet . Http . Features
10
11
{
11
12
public class FeatureCollection : IFeatureCollection
12
13
{
13
- private readonly IFeatureCollection _defaults ;
14
+ private static KeyComparer FeatureKeyComparer = new FeatureCollection . KeyComparer ( ) ;
14
15
private readonly IDictionary < Type , object > _featureByFeatureType = new Dictionary < Type , object > ( ) ;
15
- private readonly object _containerSync = new object ( ) ;
16
+ private readonly IFeatureCollection _defaults ;
16
17
private volatile int _containerRevision ;
17
18
18
19
public FeatureCollection ( )
@@ -24,143 +25,78 @@ public FeatureCollection(IFeatureCollection defaults)
24
25
_defaults = defaults ;
25
26
}
26
27
27
- public object GetInterface ( )
28
+ public virtual int Revision
28
29
{
29
- return GetInterface ( null ) ;
30
+ get { return _containerRevision + ( _defaults ? . Revision ?? 0 ) ; }
30
31
}
31
32
32
- public object GetInterface ( [ NotNull ] Type type )
33
- {
34
- object feature ;
35
- if ( _featureByFeatureType . TryGetValue ( type , out feature ) )
36
- {
37
- return feature ;
38
- }
33
+ public bool IsReadOnly { get { return false ; } }
39
34
40
- if ( _defaults != null && _defaults . TryGetValue ( type , out feature ) )
41
- {
42
- return feature ;
43
- }
44
- return null ;
45
- }
46
-
47
- void SetInterface ( [ NotNull ] Type type , object feature )
35
+ public object this [ [ NotNull ] Type key ]
48
36
{
49
- if ( feature == null )
50
- {
51
- Remove ( type ) ;
52
- return ;
53
- }
54
-
55
- lock ( _containerSync )
56
- {
57
- _featureByFeatureType [ type ] = feature ;
58
- _containerRevision ++ ;
59
- }
37
+ get { return Get ( key ) ; }
38
+ set { Set ( key , value ) ; }
60
39
}
61
40
62
- public virtual int Revision
41
+ public object Get ( [ NotNull ] Type key )
63
42
{
64
- get { return _containerRevision ; }
43
+ object result ;
44
+ return _featureByFeatureType . TryGetValue ( key , out result ) ? result : _defaults ? . Get ( key ) ;
65
45
}
66
46
67
- public void Dispose ( )
47
+ public void Set ( [ NotNull ] Type key , object value )
68
48
{
69
- }
49
+ if ( value == null )
50
+ {
51
+ if ( _featureByFeatureType . Remove ( key ) )
52
+ {
53
+ _containerRevision ++ ;
54
+ }
55
+ return ;
56
+ }
70
57
71
- public IEnumerator < KeyValuePair < Type , object > > GetEnumerator ( )
72
- {
73
- throw new NotImplementedException ( ) ;
58
+ _featureByFeatureType [ key ] = value ;
59
+ _containerRevision ++ ;
74
60
}
75
61
76
62
IEnumerator IEnumerable . GetEnumerator ( )
77
63
{
78
64
return GetEnumerator ( ) ;
79
65
}
80
66
81
- public void Add ( KeyValuePair < Type , object > item )
82
- {
83
- SetInterface ( item . Key , item . Value ) ;
84
- }
85
-
86
- public void Clear ( )
87
- {
88
- throw new NotImplementedException ( ) ;
89
- }
90
-
91
- public bool Contains ( KeyValuePair < Type , object > item )
92
- {
93
- object value ;
94
- return TryGetValue ( item . Key , out value ) && Equals ( item . Value , value ) ;
95
- }
96
-
97
- public void CopyTo ( KeyValuePair < Type , object > [ ] array , int arrayIndex )
98
- {
99
- throw new NotImplementedException ( ) ;
100
- }
101
-
102
- public bool Remove ( KeyValuePair < Type , object > item )
103
- {
104
- return Contains ( item ) && Remove ( item . Key ) ;
105
- }
106
-
107
- public int Count
108
- {
109
- get { throw new NotImplementedException ( ) ; }
110
- }
111
-
112
- public bool IsReadOnly
113
- {
114
- get { return false ; }
115
- }
116
-
117
- public bool ContainsKey ( [ NotNull ] Type key )
118
- {
119
- return GetInterface ( key ) != null ;
120
- }
121
-
122
- public void Add ( [ NotNull ] Type key , [ NotNull ] object value )
67
+ public IEnumerator < KeyValuePair < Type , object > > GetEnumerator ( )
123
68
{
124
- if ( ContainsKey ( key ) )
69
+ foreach ( var pair in _featureByFeatureType )
125
70
{
126
- throw new ArgumentException ( ) ;
71
+ yield return pair ;
127
72
}
128
- SetInterface ( key , value ) ;
129
- }
130
73
131
- public bool Remove ( [ NotNull ] Type key )
132
- {
133
- lock ( _containerSync )
74
+ if ( _defaults != null )
134
75
{
135
- if ( _featureByFeatureType . Remove ( key ) )
76
+ // Don't return features masked by the wrapper.
77
+ foreach ( var pair in _defaults . Except ( _featureByFeatureType , FeatureKeyComparer ) )
136
78
{
137
- _containerRevision ++ ;
138
- return true ;
79
+ yield return pair ;
139
80
}
140
- return false ;
141
81
}
142
82
}
143
83
144
- public bool TryGetValue ( [ NotNull ] Type key , out object value )
145
- {
146
- value = GetInterface ( key ) ;
147
- return value != null ;
148
- }
149
-
150
- public object this [ Type key ]
84
+ public virtual void Dispose ( )
151
85
{
152
- get { return GetInterface ( key ) ; }
153
- set { SetInterface ( key , value ) ; }
86
+ _defaults ? . Dispose ( ) ;
154
87
}
155
88
156
- public ICollection < Type > Keys
89
+ private class KeyComparer : IEqualityComparer < KeyValuePair < Type , object > >
157
90
{
158
- get { throw new NotImplementedException ( ) ; }
159
- }
91
+ public bool Equals ( KeyValuePair < Type , object > x , KeyValuePair < Type , object > y )
92
+ {
93
+ return x . Key . Equals ( y . Key ) ;
94
+ }
160
95
161
- public ICollection < object > Values
162
- {
163
- get { throw new NotImplementedException ( ) ; }
96
+ public int GetHashCode ( KeyValuePair < Type , object > obj )
97
+ {
98
+ throw new NotImplementedException ( ) ;
99
+ }
164
100
}
165
101
}
166
102
}
0 commit comments