Skip to content

Commit 7ed09b3

Browse files
authored
feat: mc sdk & sdk unit test (#112)
* feat(websiteMessage):mc sdk * feat: mc sdk & sdk unit test * refactor:add model base class * refactor:process code review * refactor:decrease indent * refactor:Use Directory.Build.props
1 parent 00a623f commit 7ed09b3

23 files changed

+1002
-1
lines changed

Masa.Contrib.sln

+33
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Contrib.Dispatcher.Int
312312
EndProject
313313
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Contrib.Identity.IdentityModel.Tests", "test\Masa.Contrib.Identity.IdentityModel.Tests\Masa.Contrib.Identity.IdentityModel.Tests.csproj", "{4E237346-F948-46AC-801B-492545978280}"
314314
EndProject
315+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Contrib.BasicAbility.Mc", "src\BasicAbility\Masa.Contrib.BasicAbility.Mc\Masa.Contrib.BasicAbility.Mc.csproj", "{75A25CF6-9BA4-46F5-8BC3-90396230CB64}"
316+
EndProject
317+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.BuildingBlocks.BasicAbility.Mc", "src\BuildingBlocks\MASA.BuildingBlocks\src\BasicAbility\Masa.BuildingBlocks.BasicAbility.Mc\Masa.BuildingBlocks.BasicAbility.Mc.csproj", "{DA816A33-F164-4456-92DD-A672BAD1A6B1}"
318+
EndProject
319+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Contrib.BasicAbility.Mc.Tests", "test\Masa.Contrib.BasicAbility.Mc.Tests\Masa.Contrib.BasicAbility.Mc.Tests.csproj", "{23633E49-F11A-4D14-899A-E2599C8182CE}"
320+
EndProject
315321
Global
316322
GlobalSection(SolutionConfigurationPlatforms) = preSolution
317323
Debug|Any CPU = Debug|Any CPU
@@ -1296,6 +1302,30 @@ Global
12961302
{4E237346-F948-46AC-801B-492545978280}.Release|Any CPU.Build.0 = Release|Any CPU
12971303
{4E237346-F948-46AC-801B-492545978280}.Release|x64.ActiveCfg = Release|Any CPU
12981304
{4E237346-F948-46AC-801B-492545978280}.Release|x64.Build.0 = Release|Any CPU
1305+
{75A25CF6-9BA4-46F5-8BC3-90396230CB64}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
1306+
{75A25CF6-9BA4-46F5-8BC3-90396230CB64}.Debug|Any CPU.Build.0 = Debug|Any CPU
1307+
{75A25CF6-9BA4-46F5-8BC3-90396230CB64}.Debug|x64.ActiveCfg = Debug|Any CPU
1308+
{75A25CF6-9BA4-46F5-8BC3-90396230CB64}.Debug|x64.Build.0 = Debug|Any CPU
1309+
{75A25CF6-9BA4-46F5-8BC3-90396230CB64}.Release|Any CPU.ActiveCfg = Release|Any CPU
1310+
{75A25CF6-9BA4-46F5-8BC3-90396230CB64}.Release|Any CPU.Build.0 = Release|Any CPU
1311+
{75A25CF6-9BA4-46F5-8BC3-90396230CB64}.Release|x64.ActiveCfg = Release|Any CPU
1312+
{75A25CF6-9BA4-46F5-8BC3-90396230CB64}.Release|x64.Build.0 = Release|Any CPU
1313+
{DA816A33-F164-4456-92DD-A672BAD1A6B1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
1314+
{DA816A33-F164-4456-92DD-A672BAD1A6B1}.Debug|Any CPU.Build.0 = Debug|Any CPU
1315+
{DA816A33-F164-4456-92DD-A672BAD1A6B1}.Debug|x64.ActiveCfg = Debug|Any CPU
1316+
{DA816A33-F164-4456-92DD-A672BAD1A6B1}.Debug|x64.Build.0 = Debug|Any CPU
1317+
{DA816A33-F164-4456-92DD-A672BAD1A6B1}.Release|Any CPU.ActiveCfg = Release|Any CPU
1318+
{DA816A33-F164-4456-92DD-A672BAD1A6B1}.Release|Any CPU.Build.0 = Release|Any CPU
1319+
{DA816A33-F164-4456-92DD-A672BAD1A6B1}.Release|x64.ActiveCfg = Release|Any CPU
1320+
{DA816A33-F164-4456-92DD-A672BAD1A6B1}.Release|x64.Build.0 = Release|Any CPU
1321+
{23633E49-F11A-4D14-899A-E2599C8182CE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
1322+
{23633E49-F11A-4D14-899A-E2599C8182CE}.Debug|Any CPU.Build.0 = Debug|Any CPU
1323+
{23633E49-F11A-4D14-899A-E2599C8182CE}.Debug|x64.ActiveCfg = Debug|Any CPU
1324+
{23633E49-F11A-4D14-899A-E2599C8182CE}.Debug|x64.Build.0 = Debug|Any CPU
1325+
{23633E49-F11A-4D14-899A-E2599C8182CE}.Release|Any CPU.ActiveCfg = Release|Any CPU
1326+
{23633E49-F11A-4D14-899A-E2599C8182CE}.Release|Any CPU.Build.0 = Release|Any CPU
1327+
{23633E49-F11A-4D14-899A-E2599C8182CE}.Release|x64.ActiveCfg = Release|Any CPU
1328+
{23633E49-F11A-4D14-899A-E2599C8182CE}.Release|x64.Build.0 = Release|Any CPU
12991329
EndGlobalSection
13001330
GlobalSection(SolutionProperties) = preSolution
13011331
HideSolutionNode = FALSE
@@ -1451,6 +1481,9 @@ Global
14511481
{7C4B88FA-3681-4C29-BC3F-0FDB111C5681} = {FBD326D3-E59C-433E-A88E-14E179E3093D}
14521482
{592297DE-DA72-452D-9D88-61EE882FE9A6} = {38E6C400-90C0-493E-9266-C1602E229F1B}
14531483
{4E237346-F948-46AC-801B-492545978280} = {38E6C400-90C0-493E-9266-C1602E229F1B}
1484+
{75A25CF6-9BA4-46F5-8BC3-90396230CB64} = {5DFAF4A2-ECB5-46E4-904D-1EA5F48B2D48}
1485+
{DA816A33-F164-4456-92DD-A672BAD1A6B1} = {0D34A7F0-DC77-4789-A136-93089CBD15C3}
1486+
{23633E49-F11A-4D14-899A-E2599C8182CE} = {38E6C400-90C0-493E-9266-C1602E229F1B}
14541487
EndGlobalSection
14551488
GlobalSection(ExtensibilityGlobals) = postSolution
14561489
SolutionGuid = {40383055-CC50-4600-AD9A-53C14F620D03}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// Copyright (c) MASA Stack All rights reserved.
2+
// Licensed under the MIT License. See LICENSE.txt in the project root for license information.
3+
4+
namespace Masa.Contrib.BasicAbility.Mc;
5+
6+
internal class Constants
7+
{
8+
public const string DEFAULT_CLIENT_NAME = "masa.contrib.basicability.mc";
9+
}
10+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
// Copyright (c) MASA Stack All rights reserved.
2+
// Licensed under the MIT License. See LICENSE.txt in the project root for license information.
3+
4+
namespace System.Collections.Concurrent;
5+
6+
/// <summary>
7+
/// Extension methods for Dictionary.
8+
/// </summary>
9+
public static class DictionaryExtensions
10+
{
11+
/// <summary>
12+
/// This method is used to try to get a value in a dictionary if it does exists.
13+
/// </summary>
14+
/// <typeparam name="T">Type of the value</typeparam>
15+
/// <param name="dictionary">The collection object</param>
16+
/// <param name="key">Key</param>
17+
/// <param name="value">Value of the key (or default value if key not exists)</param>
18+
/// <returns>True if key does exists in the dictionary</returns>
19+
internal static bool TryGetValue<T>(this IDictionary<string, object> dictionary, string key, out T value)
20+
{
21+
object valueObj;
22+
if (dictionary.TryGetValue(key, out valueObj) && valueObj is T)
23+
{
24+
value = (T)valueObj;
25+
return true;
26+
}
27+
28+
value = default;
29+
return false;
30+
}
31+
32+
/// <summary>
33+
/// Gets a value from the dictionary with given key. Returns default value if can not find.
34+
/// </summary>
35+
/// <param name="dictionary">Dictionary to check and get</param>
36+
/// <param name="key">Key to find the value</param>
37+
/// <typeparam name="TKey">Type of the key</typeparam>
38+
/// <typeparam name="TValue">Type of the value</typeparam>
39+
/// <returns>Value if found, default if can not found.</returns>
40+
public static TValue? GetOrDefault<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key)
41+
{
42+
return dictionary.TryGetValue(key, out var obj) ? obj : default;
43+
}
44+
45+
/// <summary>
46+
/// Gets a value from the dictionary with given key. Returns default value if can not find.
47+
/// </summary>
48+
/// <param name="dictionary">Dictionary to check and get</param>
49+
/// <param name="key">Key to find the value</param>
50+
/// <typeparam name="TKey">Type of the key</typeparam>
51+
/// <typeparam name="TValue">Type of the value</typeparam>
52+
/// <returns>Value if found, default if can not found.</returns>
53+
public static TValue? GetOrDefault<TKey, TValue>(this IReadOnlyDictionary<TKey, TValue> dictionary, TKey key)
54+
{
55+
return dictionary.TryGetValue(key, out var obj) ? obj : default;
56+
}
57+
58+
/// <summary>
59+
/// Gets a value from the dictionary with given key. Returns default value if can not find.
60+
/// </summary>
61+
/// <param name="dictionary">Dictionary to check and get</param>
62+
/// <param name="key">Key to find the value</param>
63+
/// <typeparam name="TKey">Type of the key</typeparam>
64+
/// <typeparam name="TValue">Type of the value</typeparam>
65+
/// <returns>Value if found, default if can not found.</returns>
66+
public static TValue? GetOrDefault<TKey, TValue>(this ConcurrentDictionary<TKey, TValue> dictionary, TKey key)
67+
{
68+
return dictionary.TryGetValue(key, out var obj) ? obj : default;
69+
}
70+
71+
/// <summary>
72+
/// Gets a value from the dictionary with given key. Returns default value if can not find.
73+
/// </summary>
74+
/// <param name="dictionary">Dictionary to check and get</param>
75+
/// <param name="key">Key to find the value</param>
76+
/// <param name="factory">A factory method used to create the value if not found in the dictionary</param>
77+
/// <typeparam name="TKey">Type of the key</typeparam>
78+
/// <typeparam name="TValue">Type of the value</typeparam>
79+
/// <returns>Value if found, default if can not found.</returns>
80+
public static TValue GetOrAdd<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, [NotNull] TKey key, Func<TKey, TValue> factory)
81+
{
82+
TValue obj;
83+
if (dictionary.TryGetValue(key, out obj))
84+
{
85+
return obj;
86+
}
87+
88+
return dictionary[key] = factory(key);
89+
}
90+
91+
/// <summary>
92+
/// Gets a value from the dictionary with given key. Returns default value if can not find.
93+
/// </summary>
94+
/// <param name="dictionary">Dictionary to check and get</param>
95+
/// <param name="key">Key to find the value</param>
96+
/// <param name="factory">A factory method used to create the value if not found in the dictionary</param>
97+
/// <typeparam name="TKey">Type of the key</typeparam>
98+
/// <typeparam name="TValue">Type of the value</typeparam>
99+
/// <returns>Value if found, default if can not found.</returns>
100+
public static TValue GetOrAdd<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, [NotNull] TKey key, Func<TValue> factory)
101+
{
102+
return dictionary.GetOrAdd(key, k => factory());
103+
}
104+
105+
/// <summary>
106+
/// Gets a value from the concurrent dictionary with given key. Returns default value if can not find.
107+
/// </summary>
108+
/// <param name="dictionary">Concurrent dictionary to check and get</param>
109+
/// <param name="key">Key to find the value</param>
110+
/// <param name="factory">A factory method used to create the value if not found in the dictionary</param>
111+
/// <typeparam name="TKey">Type of the key</typeparam>
112+
/// <typeparam name="TValue">Type of the value</typeparam>
113+
/// <returns>Value if found, default if can not found.</returns>
114+
public static TValue GetOrAdd<TKey, TValue>(this ConcurrentDictionary<TKey, TValue> dictionary, [NotNull] TKey key, Func<TValue> factory)
115+
{
116+
return dictionary.GetOrAdd(key, k => factory());
117+
}
118+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// Copyright (c) MASA Stack All rights reserved.
2+
// Licensed under the MIT License. See LICENSE.txt in the project root for license information.
3+
4+
namespace System.Collections.Concurrent;
5+
6+
public static class ExtraPropertiesExtensions
7+
{
8+
public static bool HasProperty(this ExtraPropertyDictionary source, string name)
9+
{
10+
return source.ContainsKey(name);
11+
}
12+
13+
public static object GetProperty(this ExtraPropertyDictionary source, string name, object defaultValue = null)
14+
{
15+
return source.GetOrDefault(name)
16+
?? defaultValue;
17+
}
18+
19+
public static TProperty GetProperty<TProperty>(this ExtraPropertyDictionary source, string name, TProperty defaultValue = default)
20+
{
21+
var value = source.GetProperty(name);
22+
if (value == null)
23+
{
24+
return defaultValue;
25+
}
26+
27+
if (TypeHelper.IsPrimitiveExtended(typeof(TProperty), includeEnums: true))
28+
{
29+
var conversionType = typeof(TProperty);
30+
if (TypeHelper.IsNullable(conversionType))
31+
{
32+
conversionType = conversionType.GetFirstGenericArgumentIfNullable();
33+
}
34+
35+
if (conversionType == typeof(Guid))
36+
{
37+
return (TProperty)TypeDescriptor.GetConverter(conversionType).ConvertFromInvariantString(value.ToString());
38+
}
39+
40+
if (conversionType == typeof(DateTimeOffset))
41+
{
42+
return (TProperty)TypeDescriptor.GetConverter(conversionType).ConvertFromInvariantString(value.ToString());
43+
}
44+
45+
return (TProperty)Convert.ChangeType(value?.ToString(), conversionType, CultureInfo.InvariantCulture);
46+
}
47+
48+
throw new Exception("GetProperty<TProperty> does not support non-primitive types. Use non-generic GetProperty method and handle type casting manually.");
49+
}
50+
51+
public static TSource SetProperty<TSource>(
52+
this TSource source,
53+
string name,
54+
object value)
55+
where TSource : ExtraPropertyDictionary
56+
{
57+
source[name] = value;
58+
59+
return source;
60+
}
61+
}

0 commit comments

Comments
 (0)