22// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
33// Website: https://www.blazor.zone or https://argozhang.github.io/
44
5- #if NET9_0_OR_GREATER
6- using System . Collections . Frozen ;
7- #endif
8-
95using System . Collections . Concurrent ;
106using System . Runtime . CompilerServices ;
117using System . Text . Json ;
@@ -14,9 +10,9 @@ namespace BootstrapBlazor.Components;
1410
1511class DefaultRegionService : IRegionService
1612{
17- private static readonly ConcurrentDictionary < string , IReadOnlySet < string > > _citiesCache = new ( ) ;
18- private static readonly ConcurrentDictionary < string , IReadOnlySet < CountyItem > > _countiesCache = new ( ) ;
19- private static readonly ConcurrentDictionary < string , IReadOnlySet < string > > _detailCache = new ( ) ;
13+ private static readonly ConcurrentDictionary < string , HashSet < string > > _citiesCache = new ( ) ;
14+ private static readonly ConcurrentDictionary < string , HashSet < CountyItem > > _countiesCache = new ( ) ;
15+ private static readonly ConcurrentDictionary < string , HashSet < string > > _detailCache = new ( ) ;
2016
2117 private static bool _initialized = false ;
2218
@@ -26,35 +22,35 @@ class DefaultRegionService : IRegionService
2622 private static readonly object _lock = new ( ) ;
2723#endif
2824
29- public IReadOnlySet < string > GetProvinces ( ) => Provinces ;
25+ #if NET9_0_OR_GREATER
26+ private static readonly Lock _lockDetail = new ( ) ;
27+ #else
28+ private static readonly object _lockDetail = new ( ) ;
29+ #endif
30+
31+ public HashSet < string > GetProvinces ( ) => Provinces ;
3032
31- public IReadOnlySet < string > GetCities ( string province )
33+ public HashSet < string > GetCities ( string province )
3234 {
3335 LoadCityData ( ) ;
34- return _citiesCache . TryGetValue ( province , out var cities ) ? cities : new HashSet < string > ( ) ;
36+ return _citiesCache . TryGetValue ( province , out var cities ) ? cities : [ ] ;
3537 }
3638
37- public IReadOnlySet < CountyItem > GetCounties ( string city )
39+ public HashSet < CountyItem > GetCounties ( string city )
3840 {
3941 LoadCityData ( ) ;
40- return _countiesCache . TryGetValue ( city , out var counties ) ? counties : new HashSet < CountyItem > ( ) ;
42+ return _countiesCache . TryGetValue ( city , out var counties ) ? counties : [ ] ;
4143 }
4244
43- public IReadOnlySet < string > GetDetails ( string countyCode )
45+ public HashSet < string > GetDetails ( string countyCode )
4446 {
45- LoadDetailData ( countyCode ) ;
46- return _detailCache . TryGetValue ( countyCode , out var details ) ? details : new HashSet < string > ( ) ;
47+ return _detailCache . GetOrAdd ( countyCode , LoadDetailData ) ;
4748 }
4849
49- private static IReadOnlySet < string > LoadDetailData ( string countyCode )
50+ private static HashSet < string > LoadDetailData ( string countyCode )
5051 {
51- if ( _detailCache . TryGetValue ( countyCode , out var detail ) )
52- {
53- return detail ;
54- }
55-
5652 var details = new HashSet < string > ( ) ;
57- var data = typeof ( DefaultRegionService ) . Assembly . GetManifestResourceStream ( $ "BootstrapBlazor.Components.Data.town.{ countyCode } .json") ;
53+ using var data = typeof ( DefaultRegionService ) . Assembly . GetManifestResourceStream ( $ "BootstrapBlazor.Components.Data.town.{ countyCode } .json") ;
5854 if ( data != null )
5955 {
6056 var document = JsonDocument . Parse ( data ) ;
@@ -68,79 +64,79 @@ private static IReadOnlySet<string> LoadDetailData(string countyCode)
6864 }
6965 }
7066 }
71- _detailCache . TryAdd ( countyCode , details ) ;
7267 return details ;
7368 }
7469
7570 private static void LoadCityData ( )
7671 {
77- if ( _initialized )
72+ if ( ! _initialized )
7873 {
79- return ;
74+ lock ( _lock )
75+ {
76+ if ( ! _initialized )
77+ {
78+ using var data = typeof ( DefaultRegionService ) . Assembly . GetManifestResourceStream ( "BootstrapBlazor.Components.Data.data.json" ) ;
79+ if ( data != null )
80+ {
81+ LoadDataCore ( data ) ;
82+ }
83+ _initialized = true ;
84+ }
85+ }
8086 }
87+ }
8188
82- lock ( _lock )
89+ private static void LoadDataCore ( Stream data )
90+ {
91+ var city = "" ;
92+ HashSet < string > cities = [ ] ;
93+ HashSet < CountyItem > ? counties = null ;
94+ using var stream = new StreamReader ( data ) ;
95+ while ( ! stream . EndOfStream )
8396 {
84- if ( _initialized )
97+ var content = stream . ReadLine ( ) ;
98+ if ( ! string . IsNullOrEmpty ( content ) )
8599 {
86- return ;
87- }
100+ var index = content . IndexOf ( ':' ) ;
101+ if ( index == - 1 )
102+ {
103+ continue ;
104+ }
88105
89- _initialized = true ;
90- var data = typeof ( DefaultRegionService ) . Assembly . GetManifestResourceStream ( "BootstrapBlazor.Components.Data.data.json" ) ;
91- if ( data != null )
92- {
93- var city = "" ;
94- HashSet < string > cities = [ ] ;
95- HashSet < CountyItem > ? counties = null ;
96- using var stream = new StreamReader ( data ) ;
97- while ( ! stream . EndOfStream )
106+ var mem = content . AsMemory ( ) ;
107+ var code = Trim ( mem [ 0 ..index ] . ToString ( ) ) ;
108+ var value = Trim ( mem [ ( index + 1 ) ..( mem . Length - 1 ) ] . ToString ( ) ) ;
109+
110+ if ( code [ 2 ..] == "0000" )
98111 {
99- var content = stream . ReadLine ( ) ;
100- if ( ! string . IsNullOrEmpty ( content ) )
112+ city = value ;
113+ cities = [ ] ;
114+
115+ if ( value == "北京市" || value == "天津市" || value == "上海市" || value == "重庆市" || value == "香港特别行政区" || value == "澳门特别行政区" )
101116 {
102- var index = content . IndexOf ( ':' ) ;
103- if ( index == - 1 )
104- {
105- continue ;
106- }
107-
108- var mem = content . AsMemory ( ) ;
109- var code = Trim ( mem [ 0 ..index ] . ToString ( ) ) ;
110- var value = Trim ( mem [ ( index + 1 ) ..( mem . Length - 1 ) ] . ToString ( ) ) ;
111-
112- if ( code [ 2 ..] == "0000" )
113- {
114- city = value ;
115- cities = [ ] ;
116-
117- if ( value == "北京市" || value == "天津市" || value == "上海市" || value == "重庆市" || value == "香港特别行政区" || value == "澳门特别行政区" )
118- {
119- cities . Add ( value ) ;
120- }
121-
122- _citiesCache . TryAdd ( value , cities ) ;
123- counties = null ;
124- continue ;
125- }
126-
127- if ( code [ 4 ..] == "00" )
128- {
129- cities . Add ( value ) ;
130- counties = [ ] ;
131- _countiesCache . TryAdd ( value , counties ) ;
132- continue ;
133- }
134-
135- if ( counties == null )
136- {
137- counties = [ ] ;
138- _countiesCache . TryAdd ( city , counties ) ;
139- }
140-
141- counties . Add ( new CountyItem ( ) { Name = value , Code = code } ) ;
117+ cities . Add ( value ) ;
142118 }
119+
120+ _citiesCache . TryAdd ( value , cities ) ;
121+ counties = null ;
122+ continue ;
123+ }
124+
125+ if ( code [ 4 ..] == "00" )
126+ {
127+ cities . Add ( value ) ;
128+ counties = [ ] ;
129+ _countiesCache . TryAdd ( value , counties ) ;
130+ continue ;
143131 }
132+
133+ if ( counties == null )
134+ {
135+ counties = [ ] ;
136+ _countiesCache . TryAdd ( city , counties ) ;
137+ }
138+
139+ counties . Add ( new CountyItem ( ) { Name = value , Code = code } ) ;
144140 }
145141 }
146142 }
0 commit comments