1+ using System . Collections . Concurrent ;
12using System . Reflection ;
23using System ;
34using System . Linq ;
@@ -9,75 +10,116 @@ namespace SpotifyAPI.Web
910{
1011 public abstract class RequestParams
1112 {
13+ private static readonly ConcurrentDictionary < PropertyInfo , BodyParamAttribute > _bodyParamsCache =
14+ new ConcurrentDictionary < PropertyInfo , BodyParamAttribute > ( ) ;
1215 public JObject BuildBodyParams ( )
1316 {
1417 // Make sure everything is okay before building body params
1518 CustomEnsure ( ) ;
1619
17- var bodyProps = GetType ( ) . GetProperties ( BindingFlags . NonPublic | BindingFlags . Instance | BindingFlags . Public )
18- . Where ( prop => prop . GetCustomAttributes ( typeof ( BodyParamAttribute ) , true ) . Length > 0 ) ;
19-
20- var obj = new JObject ( ) ;
21- foreach ( var prop in bodyProps )
20+ var body = new JObject ( ) ;
21+ if ( ! _bodyParamsCache . IsEmpty )
22+ {
23+ foreach ( var bodyParam in _bodyParamsCache )
24+ {
25+ AddBodyParam ( body , bodyParam . Key , bodyParam . Value ) ;
26+ }
27+ }
28+ else
2229 {
23- object value = prop . GetValue ( this ) ;
24- if ( value != null && prop . GetCustomAttribute ( typeof ( BodyParamAttribute ) ) is BodyParamAttribute attribute )
30+ var bodyProps = GetType ( )
31+ . GetProperties ( BindingFlags . NonPublic | BindingFlags . Instance | BindingFlags . Public )
32+ . Where ( prop => prop . GetCustomAttributes ( typeof ( BodyParamAttribute ) , true ) . Length > 0 ) ;
33+
34+ foreach ( var prop in bodyProps )
2535 {
26- obj [ attribute . Key ?? prop . Name ] = JToken . FromObject ( value ) ;
36+ var attribute = ( BodyParamAttribute ) prop . GetCustomAttribute ( typeof ( BodyParamAttribute ) ) ;
37+ _bodyParamsCache [ prop ] = attribute ;
38+ AddBodyParam ( body , prop , attribute ) ;
2739 }
2840 }
29- return obj ;
41+
42+ return body ;
43+ }
44+
45+ private void AddBodyParam ( JObject body , PropertyInfo prop , BodyParamAttribute attribute )
46+ {
47+ object value = prop . GetValue ( this ) ;
48+ if ( value != null )
49+ {
50+ body [ attribute . Key ?? prop . Name ] = JToken . FromObject ( value ) ;
51+ }
3052 }
3153
54+ private static readonly ConcurrentDictionary < PropertyInfo , QueryParamAttribute > _queryParamsCache =
55+ new ConcurrentDictionary < PropertyInfo , QueryParamAttribute > ( ) ;
3256 public Dictionary < string , string > BuildQueryParams ( )
3357 {
3458 // Make sure everything is okay before building query params
3559 CustomEnsure ( ) ;
3660
37- var queryProps = GetType ( ) . GetProperties ( BindingFlags . NonPublic | BindingFlags . Instance | BindingFlags . Public )
61+ var queryParams = new Dictionary < string , string > ( ) ;
62+
63+ if ( ! _queryParamsCache . IsEmpty )
64+ {
65+ foreach ( var queryParam in _queryParamsCache )
66+ {
67+ AddQueryParam ( queryParams , queryParam . Key , queryParam . Value ) ;
68+ }
69+ }
70+ else
71+ {
72+ var queryProps = GetType ( ) . GetProperties ( BindingFlags . NonPublic | BindingFlags . Instance | BindingFlags . Public )
3873 . Where ( prop => prop . GetCustomAttributes ( typeof ( QueryParamAttribute ) , true ) . Length > 0 ) ;
3974
40- var queryParams = new Dictionary < string , string > ( ) ;
41- foreach ( var prop in queryProps )
75+ foreach ( var prop in queryProps )
76+ {
77+ var attribute = ( QueryParamAttribute ) prop . GetCustomAttribute ( typeof ( QueryParamAttribute ) ) ;
78+ _queryParamsCache [ prop ] = attribute ;
79+ AddQueryParam ( queryParams , prop , attribute ) ;
80+ }
81+ }
82+
83+ AddCustomQueryParams ( queryParams ) ;
84+
85+ return queryParams ;
86+ }
87+
88+ private void AddQueryParam ( Dictionary < string , string > queryParams , PropertyInfo prop , QueryParamAttribute attribute )
89+ {
90+ object value = prop . GetValue ( this ) ;
91+ if ( value != null )
4292 {
43- object value = prop . GetValue ( this ) ;
44- if ( value != null && prop . GetCustomAttribute ( typeof ( QueryParamAttribute ) ) is QueryParamAttribute attribute )
93+ if ( value is IList < string > list && list . Count > 0 )
4594 {
46- if ( value is IList < string > list && list . Count > 0 )
47- {
48- var str = string . Join ( "," , list ) ;
49- queryParams . Add ( attribute . Key ?? prop . Name , str ) ;
50- }
51- else if ( value is Enum valueAsEnum )
52- {
53- var enumType = valueAsEnum . GetType ( ) ;
54- var valueList = new List < string > ( ) ;
95+ var str = string . Join ( "," , list ) ;
96+ queryParams . Add ( attribute . Key ?? prop . Name , str ) ;
97+ }
98+ else if ( value is Enum valueAsEnum )
99+ {
100+ var enumType = valueAsEnum . GetType ( ) ;
101+ var valueList = new List < string > ( ) ;
55102
56- foreach ( Enum enumVal in Enum . GetValues ( valueAsEnum . GetType ( ) ) )
103+ foreach ( Enum enumVal in Enum . GetValues ( valueAsEnum . GetType ( ) ) )
104+ {
105+ if ( valueAsEnum . HasFlag ( enumVal ) )
57106 {
58- if ( valueAsEnum . HasFlag ( enumVal ) )
107+ if ( enumType
108+ . GetMember ( enumVal . ToString ( ) ) [ 0 ]
109+ . GetCustomAttributes ( typeof ( StringAttribute ) )
110+ . FirstOrDefault ( ) is StringAttribute stringAttr )
59111 {
60- if ( enumType
61- . GetMember ( enumVal . ToString ( ) ) [ 0 ]
62- . GetCustomAttributes ( typeof ( StringAttribute ) )
63- . FirstOrDefault ( ) is StringAttribute stringAttr )
64- {
65- valueList . Add ( stringAttr . Value ) ;
66- }
112+ valueList . Add ( stringAttr . Value ) ;
67113 }
68114 }
69- queryParams . Add ( attribute . Key ?? prop . Name , string . Join ( "," , valueList ) ) ;
70- }
71- else
72- {
73- queryParams . Add ( attribute . Key ?? prop . Name , value . ToString ( ) ) ;
74115 }
116+ queryParams . Add ( attribute . Key ?? prop . Name , string . Join ( "," , valueList ) ) ;
117+ }
118+ else
119+ {
120+ queryParams . Add ( attribute . Key ?? prop . Name , value . ToString ( ) ) ;
75121 }
76122 }
77-
78- AddCustomQueryParams ( queryParams ) ;
79-
80- return queryParams ;
81123 }
82124
83125 protected virtual void CustomEnsure ( ) { }
0 commit comments