Skip to content

Commit 3bd47be

Browse files
committed
start scan Cuncurency
1 parent 16aac5e commit 3bd47be

File tree

4 files changed

+90
-11
lines changed

4 files changed

+90
-11
lines changed

src/Mapster.Tests/WhenRegisteringAndMappingRace.cs

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
using System;
1+
using Microsoft.VisualStudio.TestTools.UnitTesting;
2+
using Shouldly;
3+
using System;
24
using System.Collections.Generic;
5+
using System.Reflection;
36
using System.Threading.Tasks;
4-
using Microsoft.VisualStudio.TestTools.UnitTesting;
5-
using Shouldly;
67

78
namespace Mapster.Tests
89
{
@@ -131,11 +132,53 @@ public void Explicit_Mapping_Requirementd()
131132
}
132133
}
133134

135+
[TestMethod]
136+
public void Scan_Explicit_Mapping_Requirementd()
137+
{
138+
139+
TypeAdapterConfigFactory.GlobalSettings.RequireExplicitMapping = true;
140+
TypeAdapterConfigFactory.GlobalSettings.RequireDestinationMemberSource = true;
141+
142+
var simplePoco = new WhenAddingCustomMappings.SimplePoco { Id = Guid.NewGuid(), Name = "TestName" };
143+
144+
TypeAdapterConfigFactory.GlobalSettings.Scan(Assembly.GetExecutingAssembly());
145+
146+
//TypeAdapter.Adapt<WhenAddingCustomMappings.SimplePoco, WeirdPoco>(simplePoco);
147+
148+
for (int i = 0; i < 100; i++)
149+
{
150+
Parallel.Invoke(
151+
() =>
152+
{
153+
TypeAdapterConfigFactory.GlobalSettings.ScanConcurrency(Assembly.GetExecutingAssembly());
154+
155+
},
156+
() =>
157+
{
158+
TypeAdapter.Adapt<WeirdPoco>(simplePoco);
159+
}
160+
);
161+
}
162+
}
163+
134164
}
135165

136166

137167
#region TestClasses
138168

169+
public class RegData : IRegister
170+
{
171+
public void Register(ITypeAdapterConfig config)
172+
{
173+
config.NewConfig<WhenAddingCustomMappings.SimplePoco, WeirdPoco>()
174+
.Map(dest => dest.IHaveADifferentId, src => src.Id)
175+
.Map(dest => dest.MyNamePropertyIsDifferent, src => src.Name)
176+
.Ignore(dest => dest.Children);
177+
178+
}
179+
}
180+
181+
139182
public class SimplePoco
140183
{
141184
public Guid Id { get; set; }

src/Mapster/TypeAdapterConfig/TypeAdapterConfig.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,10 @@ public ITypeAdapterConfig Clone()
237237

238238
private ConcurrentDictionary<string, ITypeAdapterConfig>? _inlineConfigs;
239239
private ConcurrentDictionary<string, ITypeAdapterConfig> InlineConfigs =>
240-
_inlineConfigs ??= new ConcurrentDictionary<string, ITypeAdapterConfig>();
240+
_inlineConfigs ??= new ConcurrentDictionary<string, ITypeAdapterConfig>();
241+
242+
bool IConfigConcurrency.IsScanConcurrency { get; set; }
243+
241244
public ITypeAdapterConfig Fork(Action<ITypeAdapterConfig> action,
242245
#if !NET40
243246
[CallerFilePath]
@@ -386,5 +389,7 @@ public static void Clear()
386389
internal interface IConfigConcurrency
387390
{
388391
public bool ConcurrencyEnvironment { get; set; }
392+
393+
public bool IsScanConcurrency { get; set; }
389394
}
390395
}

src/Mapster/TypeAdapterConfig/TypeAdapterConfigIRegisterExtentions.cs

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,44 @@ public static void Apply(this ITypeAdapterConfig config, IEnumerable<Lazy<IRegis
3636
/// <returns>A list of registered mappings</returns>
3737
public static IList<IRegister> Scan(this ITypeAdapterConfig config, params Assembly[] assemblies)
3838
{
39-
List<IRegister> registers = assemblies.Select(assembly => assembly.GetLoadableTypes()
39+
if (config.ConcurrencyEnvironment)
40+
{
41+
config.Configure.WaitOne(-1, false);
42+
}
43+
44+
List<IRegister> registers = assemblies.Select(assembly => assembly.GetLoadableTypes()
4045
.Where(x => typeof(IRegister).GetTypeInfo().IsAssignableFrom(x.GetTypeInfo()) && x.GetTypeInfo().IsClass && !x.GetTypeInfo().IsAbstract))
4146
.SelectMany(registerTypes =>
4247
registerTypes.Select(registerType => (IRegister)Activator.CreateInstance(registerType))).ToList();
4348

4449
config.Apply(registers);
4550
return registers;
4651
}
52+
53+
public static IList<IRegister> ScanConcurrency(this ITypeAdapterConfig config, params Assembly[] assemblies)
54+
{
55+
56+
57+
if (config is IConfigConcurrency cfg)
58+
{
59+
cfg.ConcurrencyEnvironment = true;
60+
config.Configure.WaitOne(-1);
61+
cfg.IsScanConcurrency = true;
62+
}
63+
64+
try
65+
{
66+
return config.Scan(assemblies);
67+
}
68+
finally
69+
{
70+
if (config is IConfigConcurrency cfg2)
71+
{
72+
config.Configure.Set();
73+
cfg2.ConcurrencyEnvironment = false;
74+
}
75+
}
76+
77+
}
4778
}
4879
}

src/Mapster/TypeAdapterConfig/TypeAdapterConfigTSetterExtentions.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@ public static class TypeAdapterConfigTSetterExtentions
1515
/// <returns></returns>
1616
public static TypeAdapterSetter NewConfig(this ITypeAdapterConfig config, Type sourceType, Type destinationType)
1717
{
18-
if (config.ConcurrencyEnvironment)
18+
if (config.ConcurrencyEnvironment && config is IConfigConcurrency cfg)
1919
{
20-
// config.AdaptMutex.WaitOne(-1);
21-
config.Configure.WaitOne(-1, false);
20+
if(!cfg.IsScanConcurrency)
21+
config.Configure.WaitOne(-1, false);
2222
}
2323

2424
config.Remove(sourceType, destinationType);
@@ -33,10 +33,10 @@ public static TypeAdapterSetter NewConfig(this ITypeAdapterConfig config, Type s
3333
/// <returns></returns>
3434
public static TypeAdapterSetter<TSource, TDestination> NewConfig<TSource, TDestination>(this ITypeAdapterConfig config)
3535
{
36-
if (config.ConcurrencyEnvironment)
36+
if (config.ConcurrencyEnvironment && config is IConfigConcurrency cfg)
3737
{
38-
// config.AdaptMutex.WaitOne(-1);
39-
config.Configure.WaitOne(-1, false);
38+
if (!cfg.IsScanConcurrency)
39+
config.Configure.WaitOne(-1, false);
4040
}
4141

4242
config.Remove(typeof(TSource), typeof(TDestination));

0 commit comments

Comments
 (0)