44using System ;
55using System . Collections ;
66using System . Collections . Generic ;
7+ using System . Linq ;
78using Microsoft . Framework . Internal ;
89
910namespace Microsoft . AspNet . Http . Features
1011{
1112 public class FeatureCollection : IFeatureCollection
1213 {
13- private readonly IFeatureCollection _defaults ;
14+ private static KeyComparer FeatureKeyComparer = new FeatureCollection . KeyComparer ( ) ;
1415 private readonly IDictionary < Type , object > _featureByFeatureType = new Dictionary < Type , object > ( ) ;
15- private readonly object _containerSync = new object ( ) ;
16+ private readonly IFeatureCollection _defaults ;
1617 private volatile int _containerRevision ;
1718
1819 public FeatureCollection ( )
@@ -24,143 +25,78 @@ public FeatureCollection(IFeatureCollection defaults)
2425 _defaults = defaults ;
2526 }
2627
27- public object GetInterface ( )
28+ public virtual int Revision
2829 {
29- return GetInterface ( null ) ;
30+ get { return _containerRevision + ( _defaults ? . Revision ?? 0 ) ; }
3031 }
3132
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 ; } }
3934
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 ]
4836 {
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 ) ; }
6039 }
6140
62- public virtual int Revision
41+ public object Get ( [ NotNull ] Type key )
6342 {
64- get { return _containerRevision ; }
43+ object result ;
44+ return _featureByFeatureType . TryGetValue ( key , out result ) ? result : _defaults ? . Get ( key ) ;
6545 }
6646
67- public void Dispose ( )
47+ public void Set ( [ NotNull ] Type key , object value )
6848 {
69- }
49+ if ( value == null )
50+ {
51+ if ( _featureByFeatureType . Remove ( key ) )
52+ {
53+ _containerRevision ++ ;
54+ }
55+ return ;
56+ }
7057
71- public IEnumerator < KeyValuePair < Type , object > > GetEnumerator ( )
72- {
73- throw new NotImplementedException ( ) ;
58+ _featureByFeatureType [ key ] = value ;
59+ _containerRevision ++ ;
7460 }
7561
7662 IEnumerator IEnumerable . GetEnumerator ( )
7763 {
7864 return GetEnumerator ( ) ;
7965 }
8066
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 ( )
12368 {
124- if ( ContainsKey ( key ) )
69+ foreach ( var pair in _featureByFeatureType )
12570 {
126- throw new ArgumentException ( ) ;
71+ yield return pair ;
12772 }
128- SetInterface ( key , value ) ;
129- }
13073
131- public bool Remove ( [ NotNull ] Type key )
132- {
133- lock ( _containerSync )
74+ if ( _defaults != null )
13475 {
135- if ( _featureByFeatureType . Remove ( key ) )
76+ // Don't return features masked by the wrapper.
77+ foreach ( var pair in _defaults . Except ( _featureByFeatureType , FeatureKeyComparer ) )
13678 {
137- _containerRevision ++ ;
138- return true ;
79+ yield return pair ;
13980 }
140- return false ;
14181 }
14282 }
14383
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 ( )
15185 {
152- get { return GetInterface ( key ) ; }
153- set { SetInterface ( key , value ) ; }
86+ _defaults ? . Dispose ( ) ;
15487 }
15588
156- public ICollection < Type > Keys
89+ private class KeyComparer : IEqualityComparer < KeyValuePair < Type , object > >
15790 {
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+ }
16095
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+ }
164100 }
165101 }
166102}
0 commit comments