1- using System ;
1+ using Mapster . Adapters ;
2+ using Mapster . Models ;
3+ using Mapster . Utils ;
4+ using System ;
25using System . Collections . Concurrent ;
36using System . Collections . Generic ;
47using System . Linq ;
58using System . Linq . Expressions ;
69using System . Reflection ;
710using System . Runtime . CompilerServices ;
8- using Mapster . Adapters ;
9- using Mapster . Models ;
10- using Mapster . Utils ;
11+ using System . Threading ;
1112
1213namespace Mapster
1314{
1415 public class TypeAdapterConfig
1516 {
17+ #region ConcurrencyMod
18+
19+ [ AdaptIgnore ]
20+ public AutoResetEvent ConfigureSync { get ; set ; }
21+
22+ [ AdaptIgnore ]
23+ public AutoResetEvent ApplySync { get ; set ; }
24+
25+ public bool IsConcurrencyEnvironment { get ; set ; }
26+ public bool IsScanConcurrency { get ; set ; }
27+
28+ #endregion ConcurrencyMod
29+
1630 public static List < TypeAdapterRule > RulesTemplate { get ; } = CreateRuleTemplate ( ) ;
1731 public static TypeAdapterConfig GlobalSettings { get ; } = new TypeAdapterConfig ( ) ;
1832
@@ -95,6 +109,9 @@ private static List<TypeAdapterRule> CreateRuleTemplate()
95109
96110 public TypeAdapterConfig ( )
97111 {
112+ ConfigureSync = new ( true ) ;
113+ ApplySync = new ( true ) ;
114+
98115 Rules = RulesTemplate . ToList ( ) ;
99116 var settings = new TypeAdapterSettings ( ) ;
100117 Default = new TypeAdapterSetter ( settings , this ) ;
@@ -148,6 +165,9 @@ public TypeAdapterSetter When(Func<PreCompileArgument, bool> canMap)
148165 /// <returns></returns>
149166 public TypeAdapterSetter < TSource , TDestination > NewConfig < TSource , TDestination > ( )
150167 {
168+ if ( IsConcurrencyEnvironment && ! IsScanConcurrency )
169+ ConfigureSync . WaitOne ( - 1 , false ) ;
170+
151171 Remove ( typeof ( TSource ) , typeof ( TDestination ) ) ;
152172 return ForType < TSource , TDestination > ( ) ;
153173 }
@@ -161,6 +181,9 @@ public TypeAdapterSetter<TSource, TDestination> NewConfig<TSource, TDestination>
161181 /// <returns></returns>
162182 public TypeAdapterSetter NewConfig ( Type sourceType , Type destinationType )
163183 {
184+ if ( IsConcurrencyEnvironment && ! IsScanConcurrency )
185+ ConfigureSync . WaitOne ( - 1 , false ) ;
186+
164187 Remove ( sourceType , destinationType ) ;
165188 return ForType ( sourceType , destinationType ) ;
166189 }
@@ -385,6 +408,12 @@ internal Expression CreateDynamicMapInvokeExpressionBody(Type destinationType, E
385408
386409 public LambdaExpression CreateMapExpression ( TypeTuple tuple , MapType mapType )
387410 {
411+ if ( IsConcurrencyEnvironment )
412+ ConfigureSync . WaitOne ( - 1 ) ;
413+
414+ if ( IsScanConcurrency )
415+ ApplySync . WaitOne ( - 1 ) ;
416+
388417 var context = new CompileContext ( this ) ;
389418 context . Running . Add ( tuple ) ;
390419 Action < TypeAdapterConfig > ? fork = null ;
@@ -403,6 +432,9 @@ public LambdaExpression CreateMapExpression(TypeTuple tuple, MapType mapType)
403432 }
404433 finally
405434 {
435+ ApplySync . Set ( ) ;
436+ ConfigureSync . Set ( ) ;
437+
406438 if ( fork != null )
407439 context . Configs . Pop ( ) ;
408440 context . Running . Remove ( tuple ) ;
@@ -738,12 +770,29 @@ public IList<IRegister> Scan(params Assembly[] assemblies)
738770 return registers ;
739771 }
740772
773+ public IList < IRegister > ScanConcurrency ( params Assembly [ ] assemblies )
774+ {
741775
742- /// <summary>
743- /// Applies type mappings.
744- /// </summary>
745- /// <param name="registers">collection of IRegister interface to apply mapping.</param>
746- public void Apply ( IEnumerable < Lazy < IRegister > > registers )
776+ IsConcurrencyEnvironment = true ;
777+ ConfigureSync . WaitOne ( - 1 ) ;
778+ IsScanConcurrency = true ;
779+
780+ try
781+ {
782+ return Scan ( assemblies ) ;
783+ }
784+ finally
785+ {
786+ ConfigureSync . Set ( ) ;
787+ IsConcurrencyEnvironment = false ;
788+ }
789+ }
790+
791+ /// <summary>
792+ /// Applies type mappings.
793+ /// </summary>
794+ /// <param name="registers">collection of IRegister interface to apply mapping.</param>
795+ public void Apply ( IEnumerable < Lazy < IRegister > > registers )
747796 {
748797 Apply ( registers . Select ( register => register . Value ) ) ;
749798 }
@@ -755,10 +804,14 @@ public void Apply(IEnumerable<Lazy<IRegister>> registers)
755804 /// <param name="registers">collection of IRegister interface to apply mapping.</param>
756805 public void Apply ( IEnumerable < IRegister > registers )
757806 {
807+ ApplySync . WaitOne ( - 1 , false ) ;
808+
758809 foreach ( IRegister register in registers )
759810 {
760811 register . Register ( this ) ;
761812 }
813+
814+ ApplySync . Set ( ) ;
762815 }
763816
764817
@@ -882,4 +935,37 @@ public static void Clear()
882935 TypeAdapterConfig . GlobalSettings . Remove ( typeof ( TSource ) , typeof ( TDestination ) ) ;
883936 }
884937 }
938+
939+ public static class TypeAdapterConfigConcurrency < TSource , TDestination >
940+ {
941+ /// <summary>
942+ /// Creates a new configuration for mapping between the source and destination types.
943+ /// </summary>
944+ /// <returns></returns>
945+ public static TypeAdapterSetter < TSource , TDestination > NewConfig ( )
946+ {
947+ TypeAdapterConfig . GlobalSettings . IsConcurrencyEnvironment = true ;
948+ return TypeAdapterConfig . GlobalSettings . NewConfig < TSource , TDestination > ( ) ;
949+ }
950+
951+
952+ /// <summary>
953+ /// Creates a configuration for mapping between the source and destination types.
954+ /// </summary>
955+ /// <returns></returns>
956+ public static TypeAdapterSetter < TSource , TDestination > ForType ( )
957+ {
958+ TypeAdapterConfig . GlobalSettings . IsConcurrencyEnvironment = true ;
959+ return TypeAdapterConfig . GlobalSettings . ForType < TSource , TDestination > ( ) ;
960+ }
961+
962+
963+ /// <summary>
964+ /// Clears the type mapping configuration for the specified source and destination types.
965+ /// </summary>
966+ public static void Clear ( )
967+ {
968+ TypeAdapterConfig . GlobalSettings . Remove ( typeof ( TSource ) , typeof ( TDestination ) ) ;
969+ }
970+ }
885971}
0 commit comments