返回提交历史
Modified
AutoConfig.Analyzer.Test/Program.cs
+3
-0
Modified
AutoConfig.Analyzer.Test/SystemProfile.cs
+7
-1
Modified
AutoConfig.Analyzer.Test/UserProfile.cs
+3
-1
Modified
XFEExtension.NetCore.AutoConfig.Analyzer/Generator/ProfilePropertyAutoGenerator.cs
+209
-12
Modified
XFEExtension.NetCore.AutoConfig/ProfileDictionary.cs
+14
-10
Modified
XFEExtension.NetCore.AutoConfig/ProfileList.cs
+16
-12
Modified
XFEExtension.NetCore.AutoConfig/XFEProfile.cs
+17
-15
XFEstudio/XFEExtension.NetCore.AutoConfig
准备分为多个类
9905558
代码差异
7 个文件
+269
-51
@@ -13,6 +13,9 @@ public class Program
13
13
SystemProfile.MyText = Console.ReadLine();
14
14
Console.WriteLine(SystemProfile.MyText);
15
15
Console.ReadLine();
16
17
18
16
19
//Console.WriteLine($"上一次读取的值是:{UserProfile.UserInfoList.ToJson()}");
17
20
//Console.WriteLine("添加值:");
18
21
//Console.WriteLine("请输入店铺名称:");
@@ -4,8 +4,14 @@ namespace AutoConfig.Analyzer.Test;
4
4
5
5
public partial class SystemProfile : XFEProfile
6
6
{
7
7
8
[ProfileProperty]
8
9
private string myText = "";
9
10
[ProfileProperty]
10
11
private int myInt = 1;
11
}
12
13
public SystemProfile()
14
{
15
DefaultProfileOperationMode = ProfileOperationMode.Json;
16
}
17
}
@@ -11,5 +11,7 @@ internal partial class UserProfile : XFEProfile
11
11
/// 用户信息列表
12
12
/// </summary>
13
13
[ProfileProperty]
14
private ProfileList<UserProfile, UserInfo> userInfoList = [];
14
[ProfilePropertyAddGet("Current.userInfoList.CurrentProfile = Current")]
15
[ProfilePropertyAddGet("return Current.userInfoList")]
16
private ProfileList<UserInfo> userInfoList = [];
15
17
}
@@ -40,8 +40,8 @@ public class ProfilePropertyAutoGenerator : IIncrementalGenerator
40
40
var staticConstructorBlockStatements = new List<StatementSyntax>()
41
41
{
42
42
SyntaxFactory.ParseStatement($"Current = new {className}();"),
43
SyntaxFactory.ParseStatement($@"Current.ProfilePath = $""{{(string.IsNullOrEmpty(Current.ProfilePath) ? $""{{(global::XFEExtension.NetCore.AutoConfig.XFEProfile.ProfilesDefaultPath)}}\\{{nameof({className})}}"" : Current.ProfilePath)}}{{Current.ProfileFileExtension}}"";"),
44
SyntaxFactory.ParseStatement($"Current.SetProfileOperation();")
43
SyntaxFactory.ParseStatement($"Current.SetProfileOperation();"),
44
SyntaxFactory.ParseStatement($@"Current.ProfilePath = $""{{(string.IsNullOrEmpty(Current.ProfilePath) ? $""{{(global::XFEExtension.NetCore.AutoConfig.XFEProfile.ProfilesDefaultPath)}}\\{{nameof({className})}}"" : Current.ProfilePath)}}{{Current.ProfileFileExtension}}"";")
45
45
};
46
46
foreach (var fieldDeclarationSyntax in fieldDeclarationSyntaxes)
47
47
{
@@ -69,7 +69,7 @@ public class ProfilePropertyAutoGenerator : IIncrementalGenerator
69
69
#region Trivia头
70
70
var triviaText = $@"/// <inheritdoc cref=""{fieldName}""/>
71
71
/// <remarks>
72
/// <seealso cref=""{propertyName}""/> 是根据 <seealso cref=""{fieldName}""/> 自动生成的属性<br/><br/>
72
/// <seealso cref=""{propertyName}""/> 是根据 <seealso cref=""{fieldName}""/> 自动生成的静态属性<br/><br/>
73
73
/// <code><seealso langword=""get""/>方法已生成以下代码: ○ <seealso cref=""{className}.{getMethodName}()""/>;<br/>";
74
74
#endregion
75
75
var getExpressionStatements = new List<StatementSyntax>()
@@ -157,7 +157,7 @@ public class ProfilePropertyAutoGenerator : IIncrementalGenerator
157
157
/// </remarks>
158
158
";
159
159
#endregion
160
var property = SyntaxFactory.PropertyDeclaration(propertyType, propertyName)
160
var staticProperty = SyntaxFactory.PropertyDeclaration(propertyType, propertyName)
161
161
.WithModifiers(SyntaxFactory.TokenList(SyntaxFactory.Token(SyntaxKind.PublicKeyword), SyntaxFactory.Token(SyntaxKind.StaticKeyword)))
162
162
.AddAttributeLists(attributeSyntax)
163
163
.WithAccessorList(SyntaxFactory.AccessorList(
@@ -178,7 +178,22 @@ public class ProfilePropertyAutoGenerator : IIncrementalGenerator
178
178
.WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken));
179
179
members.Add(getMethod);
180
180
members.Add(setMethod);
181
properties.Add(property.NormalizeWhitespace());
181
members.Add(SyntaxFactory.PropertyDeclaration(propertyType, $"Instance{propertyName}")
182
.WithModifiers(SyntaxFactory.TokenList(SyntaxFactory.Token(SyntaxKind.PublicKeyword)))
183
.AddAttributeLists(attributeSyntax)
184
.WithAccessorList(SyntaxFactory.AccessorList(
185
SyntaxFactory.List(
186
[
187
SyntaxFactory.AccessorDeclaration(SyntaxKind.GetAccessorDeclaration)
188
.WithExpressionBody(SyntaxFactory.ArrowExpressionClause(SyntaxFactory.ParseExpression($"Current.{fieldName}"))),
189
SyntaxFactory.AccessorDeclaration(SyntaxKind.SetAccessorDeclaration)
190
.WithExpressionBody(SyntaxFactory.ArrowExpressionClause(SyntaxFactory.ParseExpression($"Current.{fieldName} = value")))
191
])))
192
.WithLeadingTrivia(SyntaxFactory.ParseLeadingTrivia($@"/// <inheritdoc cref=""{fieldName}""/>
193
/// <remarks>
194
/// <seealso cref=""{propertyName}""/> 是根据 <seealso cref=""{fieldName}""/> 自动生成的实例属性
195
/// </remarks>")));
196
properties.Add(staticProperty.NormalizeWhitespace());
182
197
}
183
198
staticConstructorBlockStatements.Add(SyntaxFactory.ParseStatement($"{className}.LoadProfile();"));
184
199
var staticConstructorSyntax = SyntaxFactory.ConstructorDeclaration(className)
@@ -204,7 +219,7 @@ public class ProfilePropertyAutoGenerator : IIncrementalGenerator
204
219
{
205
220
members.Add(staticConstructorSyntax);
206
221
}
207
var profileClassSyntaxTree = GenerateProfileClassSyntaxTree(classDeclaration, usingDirectives, properties, members, fileScopedNamespaceDeclarationSyntax);
222
var profileClassSyntaxTree = GenerateBasicProfileClassSyntaxTree(classDeclaration, usingDirectives, properties, members, fileScopedNamespaceDeclarationSyntax);
208
223
context.AddSource($"{className}.g.cs", profileClassSyntaxTree.ToString());
209
224
}
210
225
}
@@ -240,7 +255,93 @@ public class ProfilePropertyAutoGenerator : IIncrementalGenerator
240
255
public static IEnumerable<ClassDeclarationSyntax> GetClassDeclarations(SyntaxNode rootNode) => rootNode.DescendantNodes()
241
256
.OfType<ClassDeclarationSyntax>()
242
257
.Where(classDeclaration => classDeclaration.BaseList is not null && classDeclaration.BaseList.Types.Any(type => type.ToString() == "XFEProfile"));
243
private static SyntaxTree GenerateProfileClassSyntaxTree(ClassDeclarationSyntax classDeclaration, UsingDirectiveSyntax[] usingDirectiveSyntaxes, List<PropertyDeclarationSyntax> propertyDeclarationSyntaxes, List<MemberDeclarationSyntax> memberDeclarationSyntaxes, FileScopedNamespaceDeclarationSyntax fileScopedNamespaceDeclarationSyntax)
258
259
private static SyntaxTree GenerateBasicProfileClassSyntaxTree(ClassDeclarationSyntax classDeclaration, UsingDirectiveSyntax[] usingDirectiveSyntaxes, List<PropertyDeclarationSyntax> propertyDeclarationSyntaxes, List<MemberDeclarationSyntax> memberDeclarationSyntaxes, FileScopedNamespaceDeclarationSyntax fileScopedNamespaceDeclarationSyntax)
260
{
261
var className = classDeclaration.Identifier.ValueText;
262
memberDeclarationSyntaxes.Add(SyntaxFactory.PropertyDeclaration(SyntaxFactory.ParseTypeName(className), "Current")
263
.WithModifiers(SyntaxFactory.TokenList(SyntaxFactory.Token(SyntaxKind.PublicKeyword), SyntaxFactory.Token(SyntaxKind.StaticKeyword)))
264
.AddAttributeLists(SyntaxFactory.AttributeList(SyntaxFactory.SingletonSeparatedList(SyntaxFactory.Attribute(SyntaxFactory.ParseName("global::XFEExtension.NetCore.AutoConfig.ProfileInstanceAttribute")))))
265
.WithAccessorList(SyntaxFactory.AccessorList(SyntaxFactory.List(
266
[
267
SyntaxFactory.AccessorDeclaration(SyntaxKind.GetAccessorDeclaration)
268
.WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken)),
269
SyntaxFactory.AccessorDeclaration(SyntaxKind.SetAccessorDeclaration)
270
.WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken))
271
])))
272
.WithLeadingTrivia(SyntaxFactory.ParseLeadingTrivia($@"/// <summary>
273
/// 该配置文件的实例<br/><br/>
274
/// <seealso cref=""{className}.Current""/> 是 <seealso cref=""{className}""/> 配置文件类的实例数据
275
/// </summary>
276
")));
277
memberDeclarationSyntaxes.Add(SyntaxFactory.MethodDeclaration(SyntaxFactory.ParseTypeName("void"), "LoadProfile")
278
.WithModifiers(SyntaxFactory.TokenList(SyntaxFactory.Token(SyntaxKind.PublicKeyword), SyntaxFactory.Token(SyntaxKind.StaticKeyword)))
279
.WithExpressionBody(SyntaxFactory.ArrowExpressionClause(SyntaxFactory.ParseExpression($"Current = Current.InstanceLoadProfile() as {className}")))
280
.WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken))
281
.WithLeadingTrivia(SyntaxFactory.ParseLeadingTrivia($@"/// <summary>
282
/// 配置文件加载方法<br/><br/>
283
/// <seealso cref=""{className}.LoadProfile""/> 是根据 <seealso cref=""{className}""/> 生成的加载配置文件的静态方法
284
/// </summary>
285
")));
286
memberDeclarationSyntaxes.Add(SyntaxFactory.MethodDeclaration(SyntaxFactory.ParseTypeName("void"), "SaveProfile")
287
.WithModifiers(SyntaxFactory.TokenList(SyntaxFactory.Token(SyntaxKind.PublicKeyword), SyntaxFactory.Token(SyntaxKind.StaticKeyword)))
288
.WithExpressionBody(SyntaxFactory.ArrowExpressionClause(SyntaxFactory.ParseExpression($"Current.InstanceSaveProfile()")))
289
.WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken))
290
.WithLeadingTrivia(SyntaxFactory.ParseLeadingTrivia($@"/// <summary>
291
/// 配置文件保存方法<br/><br/>
292
/// <seealso cref=""{className}.SaveProfile""/> 是根据 <seealso cref=""{className}""/> 生成的保存配置文件的静态方法
293
/// </summary>
294
")));
295
memberDeclarationSyntaxes.Add(SyntaxFactory.MethodDeclaration(SyntaxFactory.ParseTypeName("string"), "ExportProfile")
296
.WithModifiers(SyntaxFactory.TokenList(SyntaxFactory.Token(SyntaxKind.PublicKeyword), SyntaxFactory.Token(SyntaxKind.StaticKeyword)))
297
.WithExpressionBody(SyntaxFactory.ArrowExpressionClause(SyntaxFactory.ParseExpression($"Current.InstanceExportProfile()")))
298
.WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken))
299
.WithLeadingTrivia(SyntaxFactory.ParseLeadingTrivia($@"/// <summary>
300
/// 配置文件导出方法<br/><br/>
301
/// <seealso cref=""{className}.ExportProfile""/> 是根据 <seealso cref=""{className}""/> 生成的导出配置文件的静态方法
302
/// </summary>
303
/// <returns>导出的配置文件字符串</returns>
304
")));
305
memberDeclarationSyntaxes.Add(SyntaxFactory.MethodDeclaration(SyntaxFactory.ParseTypeName("void"), "ImportProfile")
306
.WithModifiers(SyntaxFactory.TokenList(SyntaxFactory.Token(SyntaxKind.PublicKeyword), SyntaxFactory.Token(SyntaxKind.StaticKeyword)))
307
.AddParameterListParameters(SyntaxFactory.Parameter(SyntaxFactory.Identifier("profileString")).WithType(SyntaxFactory.ParseTypeName("string")))
308
.WithExpressionBody(SyntaxFactory.ArrowExpressionClause(SyntaxFactory.ParseExpression($"Current = Current.InstanceImportProfile(profileString) as {className}")))
309
.WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken))
310
.WithLeadingTrivia(SyntaxFactory.ParseLeadingTrivia($@"/// <summary>
311
/// 配置文件导入方法<br/><br/>
312
/// <seealso cref=""{className}.ImportProfile""/> 是根据 <seealso cref=""{className}""/> 生成的导入配置文件的静态方法
313
/// </summary>
314
/// <param name=""profileString"">待导入配置文件字符串</param>
315
")));
316
var profileClass = SyntaxFactory.ClassDeclaration(className)
317
.AddModifiers(SyntaxFactory.Token(SyntaxKind.PartialKeyword))
318
.AddMembers([.. memberDeclarationSyntaxes])
319
.NormalizeWhitespace();
320
MemberDeclarationSyntax memberDeclaration;
321
if (fileScopedNamespaceDeclarationSyntax is null)
322
{
323
var namespaceDeclaration = classDeclaration.FirstAncestorOrSelf<NamespaceDeclarationSyntax>();
324
if (namespaceDeclaration is null)
325
memberDeclaration = profileClass;
326
else
327
memberDeclaration = SyntaxFactory.NamespaceDeclaration(namespaceDeclaration.Name)
328
.WithLeadingTrivia(SyntaxFactory.ParseLeadingTrivia("#pragma warning disable\n#nullable enable"))
329
.AddMembers(profileClass);
330
}
331
else
332
{
333
memberDeclaration = SyntaxFactory.FileScopedNamespaceDeclaration(fileScopedNamespaceDeclarationSyntax.Name)
334
.WithLeadingTrivia(SyntaxFactory.ParseLeadingTrivia("#pragma warning disable\n#nullable enable"))
335
.AddMembers(profileClass);
336
}
337
var profileClassCompilationUnit = SyntaxFactory.CompilationUnit()
338
.AddUsings(usingDirectiveSyntaxes)
339
.AddMembers(memberDeclaration)
340
.NormalizeWhitespace();
341
return SyntaxFactory.SyntaxTree(profileClassCompilationUnit);
342
}
343
344
private static SyntaxTree GenerateProfileStaticPropertyClassSyntaxTree(ClassDeclarationSyntax classDeclaration, UsingDirectiveSyntax[] usingDirectiveSyntaxes, List<PropertyDeclarationSyntax> propertyDeclarationSyntaxes, List<MemberDeclarationSyntax> memberDeclarationSyntaxes, FileScopedNamespaceDeclarationSyntax fileScopedNamespaceDeclarationSyntax)
244
345
{
245
346
var className = classDeclaration.Identifier.ValueText;
246
347
var triviaText = $@"/// <remarks>
@@ -259,7 +360,97 @@ public class ProfilePropertyAutoGenerator : IIncrementalGenerator
259
360
.WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken))
260
361
])))
261
362
.WithLeadingTrivia(SyntaxFactory.ParseLeadingTrivia($@"/// <summary>
262
/// 该配置文件的实例<br/>
363
/// 该配置文件的实例<br/><br/>
364
/// <seealso cref=""{className}.Current""/> 是 <seealso cref=""{className}""/> 配置文件类的实例数据
365
/// </summary>
366
")));
367
memberDeclarationSyntaxes.Add(SyntaxFactory.MethodDeclaration(SyntaxFactory.ParseTypeName("void"), "LoadProfile")
368
.WithModifiers(SyntaxFactory.TokenList(SyntaxFactory.Token(SyntaxKind.PublicKeyword), SyntaxFactory.Token(SyntaxKind.StaticKeyword)))
369
.WithExpressionBody(SyntaxFactory.ArrowExpressionClause(SyntaxFactory.ParseExpression($"Current = Current.InstanceLoadProfile() as {className}")))
370
.WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken))
371
.WithLeadingTrivia(SyntaxFactory.ParseLeadingTrivia($@"/// <summary>
372
/// 配置文件加载方法<br/><br/>
373
/// <seealso cref=""{className}.LoadProfile""/> 是根据 <seealso cref=""{className}""/> 生成的加载配置文件的静态方法
374
/// </summary>
375
")));
376
memberDeclarationSyntaxes.Add(SyntaxFactory.MethodDeclaration(SyntaxFactory.ParseTypeName("void"), "SaveProfile")
377
.WithModifiers(SyntaxFactory.TokenList(SyntaxFactory.Token(SyntaxKind.PublicKeyword), SyntaxFactory.Token(SyntaxKind.StaticKeyword)))
378
.WithExpressionBody(SyntaxFactory.ArrowExpressionClause(SyntaxFactory.ParseExpression($"Current.InstanceSaveProfile()")))
379
.WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken))
380
.WithLeadingTrivia(SyntaxFactory.ParseLeadingTrivia($@"/// <summary>
381
/// 配置文件保存方法<br/><br/>
382
/// <seealso cref=""{className}.SaveProfile""/> 是根据 <seealso cref=""{className}""/> 生成的保存配置文件的静态方法
383
/// </summary>
384
")));
385
memberDeclarationSyntaxes.Add(SyntaxFactory.MethodDeclaration(SyntaxFactory.ParseTypeName("string"), "ExportProfile")
386
.WithModifiers(SyntaxFactory.TokenList(SyntaxFactory.Token(SyntaxKind.PublicKeyword), SyntaxFactory.Token(SyntaxKind.StaticKeyword)))
387
.WithExpressionBody(SyntaxFactory.ArrowExpressionClause(SyntaxFactory.ParseExpression($"Current.InstanceExportProfile()")))
388
.WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken))
389
.WithLeadingTrivia(SyntaxFactory.ParseLeadingTrivia($@"/// <summary>
390
/// 配置文件导出方法<br/><br/>
391
/// <seealso cref=""{className}.ExportProfile""/> 是根据 <seealso cref=""{className}""/> 生成的导出配置文件的静态方法
392
/// </summary>
393
/// <returns>导出的配置文件字符串</returns>
394
")));
395
memberDeclarationSyntaxes.Add(SyntaxFactory.MethodDeclaration(SyntaxFactory.ParseTypeName("void"), "ImportProfile")
396
.WithModifiers(SyntaxFactory.TokenList(SyntaxFactory.Token(SyntaxKind.PublicKeyword), SyntaxFactory.Token(SyntaxKind.StaticKeyword)))
397
.AddParameterListParameters(SyntaxFactory.Parameter(SyntaxFactory.Identifier("profileString")).WithType(SyntaxFactory.ParseTypeName("string")))
398
.WithExpressionBody(SyntaxFactory.ArrowExpressionClause(SyntaxFactory.ParseExpression($"Current = Current.InstanceImportProfile(profileString) as {className}")))
399
.WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken))
400
.WithLeadingTrivia(SyntaxFactory.ParseLeadingTrivia($@"/// <summary>
401
/// 配置文件导入方法<br/><br/>
402
/// <seealso cref=""{className}.ImportProfile""/> 是根据 <seealso cref=""{className}""/> 生成的导入配置文件的静态方法
403
/// </summary>
404
/// <param name=""profileString"">待导入配置文件字符串</param>
405
")));
406
memberDeclarationSyntaxes.Add(SyntaxFactory.MethodDeclaration(SyntaxFactory.ParseTypeName("global::XFEExtension.NetCore.AutoConfig.XFEProfile?"), "GetCurrent")
407
.WithModifiers(SyntaxFactory.TokenList(SyntaxFactory.Token(SyntaxKind.ProtectedKeyword), SyntaxFactory.Token(SyntaxKind.OverrideKeyword)))
408
.WithExpressionBody(SyntaxFactory.ArrowExpressionClause(SyntaxFactory.ParseExpression("Current")))
409
.WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken)));
410
memberDeclarationSyntaxes.AddRange(propertyDeclarationSyntaxes);
411
var profileClass = SyntaxFactory.ClassDeclaration(className)
412
.AddModifiers(SyntaxFactory.Token(SyntaxKind.PartialKeyword))
413
.AddMembers([.. memberDeclarationSyntaxes])
414
.WithLeadingTrivia(SyntaxFactory.ParseLeadingTrivia(triviaText))
415
.NormalizeWhitespace();
416
MemberDeclarationSyntax memberDeclaration;
417
if (fileScopedNamespaceDeclarationSyntax is null)
418
{
419
var namespaceDeclaration = classDeclaration.FirstAncestorOrSelf<NamespaceDeclarationSyntax>();
420
if (namespaceDeclaration is null)
421
memberDeclaration = profileClass;
422
else
423
memberDeclaration = SyntaxFactory.NamespaceDeclaration(namespaceDeclaration.Name)
424
.WithLeadingTrivia(SyntaxFactory.ParseLeadingTrivia("#pragma warning disable\n#nullable enable"))
425
.AddMembers(profileClass);
426
}
427
else
428
{
429
memberDeclaration = SyntaxFactory.FileScopedNamespaceDeclaration(fileScopedNamespaceDeclarationSyntax.Name)
430
.WithLeadingTrivia(SyntaxFactory.ParseLeadingTrivia("#pragma warning disable\n#nullable enable"))
431
.AddMembers(profileClass);
432
}
433
var profileClassCompilationUnit = SyntaxFactory.CompilationUnit()
434
.AddUsings(usingDirectiveSyntaxes)
435
.AddMembers(memberDeclaration)
436
.NormalizeWhitespace();
437
return SyntaxFactory.SyntaxTree(profileClassCompilationUnit);
438
}
439
private static SyntaxTree GenerateProfileMethodClassSyntaxTree(ClassDeclarationSyntax classDeclaration, UsingDirectiveSyntax[] usingDirectiveSyntaxes, List<PropertyDeclarationSyntax> propertyDeclarationSyntaxes, List<MemberDeclarationSyntax> memberDeclarationSyntaxes, FileScopedNamespaceDeclarationSyntax fileScopedNamespaceDeclarationSyntax)
440
{
441
var className = classDeclaration.Identifier.ValueText;
442
memberDeclarationSyntaxes.Add(SyntaxFactory.PropertyDeclaration(SyntaxFactory.ParseTypeName(className), "Current")
443
.WithModifiers(SyntaxFactory.TokenList(SyntaxFactory.Token(SyntaxKind.PublicKeyword), SyntaxFactory.Token(SyntaxKind.StaticKeyword)))
444
.AddAttributeLists(SyntaxFactory.AttributeList(SyntaxFactory.SingletonSeparatedList(SyntaxFactory.Attribute(SyntaxFactory.ParseName("global::XFEExtension.NetCore.AutoConfig.ProfileInstanceAttribute")))))
445
.WithAccessorList(SyntaxFactory.AccessorList(SyntaxFactory.List(
446
[
447
SyntaxFactory.AccessorDeclaration(SyntaxKind.GetAccessorDeclaration)
448
.WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken)),
449
SyntaxFactory.AccessorDeclaration(SyntaxKind.SetAccessorDeclaration)
450
.WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken))
451
])))
452
.WithLeadingTrivia(SyntaxFactory.ParseLeadingTrivia($@"/// <summary>
453
/// 该配置文件的实例<br/><br/>
263
454
/// <seealso cref=""{className}.Current""/> 是 <seealso cref=""{className}""/> 配置文件类的实例数据
264
455
/// </summary>
265
456
")));
@@ -268,7 +459,7 @@ public class ProfilePropertyAutoGenerator : IIncrementalGenerator
268
459
.WithExpressionBody(SyntaxFactory.ArrowExpressionClause(SyntaxFactory.ParseExpression($"Current = Current.InstanceLoadProfile() as {className}")))
269
460
.WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken))
270
461
.WithLeadingTrivia(SyntaxFactory.ParseLeadingTrivia($@"/// <summary>
271
/// 配置文件加载方法<br/>
462
/// 配置文件加载方法<br/><br/>
272
463
/// <seealso cref=""{className}.LoadProfile""/> 是根据 <seealso cref=""{className}""/> 生成的加载配置文件的静态方法
273
464
/// </summary>
274
465
")));
@@ -277,7 +468,7 @@ public class ProfilePropertyAutoGenerator : IIncrementalGenerator
277
468
.WithExpressionBody(SyntaxFactory.ArrowExpressionClause(SyntaxFactory.ParseExpression($"Current.InstanceSaveProfile()")))
278
469
.WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken))
279
470
.WithLeadingTrivia(SyntaxFactory.ParseLeadingTrivia($@"/// <summary>
280
/// 配置文件保存方法<br/>
471
/// 配置文件保存方法<br/><br/>
281
472
/// <seealso cref=""{className}.SaveProfile""/> 是根据 <seealso cref=""{className}""/> 生成的保存配置文件的静态方法
282
473
/// </summary>
283
474
")));
@@ -286,7 +477,7 @@ public class ProfilePropertyAutoGenerator : IIncrementalGenerator
286
477
.WithExpressionBody(SyntaxFactory.ArrowExpressionClause(SyntaxFactory.ParseExpression($"Current.InstanceExportProfile()")))
287
478
.WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken))
288
479
.WithLeadingTrivia(SyntaxFactory.ParseLeadingTrivia($@"/// <summary>
289
/// 配置文件导出方法<br/>
480
/// 配置文件导出方法<br/><br/>
290
481
/// <seealso cref=""{className}.ExportProfile""/> 是根据 <seealso cref=""{className}""/> 生成的导出配置文件的静态方法
291
482
/// </summary>
292
483
/// <returns>导出的配置文件字符串</returns>
@@ -297,11 +488,15 @@ public class ProfilePropertyAutoGenerator : IIncrementalGenerator
297
488
.WithExpressionBody(SyntaxFactory.ArrowExpressionClause(SyntaxFactory.ParseExpression($"Current = Current.InstanceImportProfile(profileString) as {className}")))
298
489
.WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken))
299
490
.WithLeadingTrivia(SyntaxFactory.ParseLeadingTrivia($@"/// <summary>
300
/// 配置文件导入方法<br/>
491
/// 配置文件导入方法<br/><br/>
301
492
/// <seealso cref=""{className}.ImportProfile""/> 是根据 <seealso cref=""{className}""/> 生成的导入配置文件的静态方法
302
493
/// </summary>
303
494
/// <param name=""profileString"">待导入配置文件字符串</param>
304
495
")));
496
memberDeclarationSyntaxes.Add(SyntaxFactory.MethodDeclaration(SyntaxFactory.ParseTypeName("global::XFEExtension.NetCore.AutoConfig.XFEProfile?"), "GetCurrent")
497
.WithModifiers(SyntaxFactory.TokenList(SyntaxFactory.Token(SyntaxKind.ProtectedKeyword), SyntaxFactory.Token(SyntaxKind.OverrideKeyword)))
498
.WithExpressionBody(SyntaxFactory.ArrowExpressionClause(SyntaxFactory.ParseExpression("Current")))
499
.WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken)));
305
500
memberDeclarationSyntaxes.AddRange(propertyDeclarationSyntaxes);
306
501
var profileClass = SyntaxFactory.ClassDeclaration(className)
307
502
.AddModifiers(SyntaxFactory.Token(SyntaxKind.PartialKeyword))
@@ -316,11 +511,13 @@ public class ProfilePropertyAutoGenerator : IIncrementalGenerator
316
511
memberDeclaration = profileClass;
317
512
else
318
513
memberDeclaration = SyntaxFactory.NamespaceDeclaration(namespaceDeclaration.Name)
514
.WithLeadingTrivia(SyntaxFactory.ParseLeadingTrivia("#pragma warning disable\n#nullable enable"))
319
515
.AddMembers(profileClass);
320
516
}
321
517
else
322
518
{
323
519
memberDeclaration = SyntaxFactory.FileScopedNamespaceDeclaration(fileScopedNamespaceDeclarationSyntax.Name)
520
.WithLeadingTrivia(SyntaxFactory.ParseLeadingTrivia("#pragma warning disable\n#nullable enable"))
324
521
.AddMembers(profileClass);
325
522
}
326
523
var profileClassCompilationUnit = SyntaxFactory.CompilationUnit()
@@ -7,10 +7,9 @@ namespace XFEExtension.NetCore.AutoConfig;
7
7
/// <summary>
8
8
/// 配置文件字典
9
9
/// </summary>
10
/// <typeparam name="TProfile">配置文件类型</typeparam>
11
10
/// <typeparam name="TKey">字典Key泛型</typeparam>
12
11
/// <typeparam name="TValue">字典Value泛型</typeparam>
13
public class ProfileDictionary<TProfile, TKey, TValue> : ICollection<KeyValuePair<TKey, TValue>>, IEnumerable<KeyValuePair<TKey, TValue>>, IEnumerable, IDictionary<TKey, TValue>, IReadOnlyCollection<KeyValuePair<TKey, TValue>>, IReadOnlyDictionary<TKey, TValue>, ICollection, IDictionary, IDeserializationCallback, ISerializable where TKey : notnull
12
public class ProfileDictionary<TKey, TValue> : ICollection<KeyValuePair<TKey, TValue>>, IEnumerable<KeyValuePair<TKey, TValue>>, IEnumerable, IDictionary<TKey, TValue>, IReadOnlyCollection<KeyValuePair<TKey, TValue>>, IReadOnlyDictionary<TKey, TValue>, ICollection, IDictionary, IDeserializationCallback, ISerializable where TKey : notnull
14
13
{
15
14
private readonly Dictionary<TKey, TValue> _innerDictionary;
16
15
@@ -33,6 +32,11 @@ public class ProfileDictionary<TProfile, TKey, TValue> : ICollection<KeyValuePai
33
32
///<inheritdoc/>
34
33
public int Count => ((ICollection<KeyValuePair<TKey, TValue>>)_innerDictionary).Count;
35
34
35
/// <summary>
36
/// 当前配置文件实例
37
/// </summary>
38
public XFEProfile? CurrentProfile { get; set; }
39
36
40
///<inheritdoc/>
37
41
public bool IsReadOnly => ((ICollection<KeyValuePair<TKey, TValue>>)_innerDictionary).IsReadOnly;
38
42
@@ -63,28 +67,28 @@ public class ProfileDictionary<TProfile, TKey, TValue> : ICollection<KeyValuePai
63
67
public void Add(KeyValuePair<TKey, TValue> item)
64
68
{
65
69
((ICollection<KeyValuePair<TKey, TValue>>)_innerDictionary).Add(item);
66
XFEProfile.SaveProfile(typeof(TProfile));
70
CurrentProfile?.InstanceSaveProfile();
67
71
}
68
72
69
73
///<inheritdoc/>
70
74
public void Add(TKey key, TValue value)
71
75
{
72
76
((IDictionary<TKey, TValue>)_innerDictionary).Add(key, value);
73
XFEProfile.SaveProfile(typeof(TProfile));
77
CurrentProfile?.InstanceSaveProfile();
74
78
}
75
79
76
80
///<inheritdoc/>
77
81
public void Add(object key, object? value)
78
82
{
79
83
((IDictionary)_innerDictionary).Add(key, value);
80
XFEProfile.SaveProfile(typeof(TProfile));
84
CurrentProfile?.InstanceSaveProfile();
81
85
}
82
86
83
87
///<inheritdoc/>
84
88
public void Clear()
85
89
{
86
90
((ICollection<KeyValuePair<TKey, TValue>>)_innerDictionary).Clear();
87
XFEProfile.SaveProfile(typeof(TProfile));
91
CurrentProfile?.InstanceSaveProfile();
88
92
}
89
93
90
94
///<inheritdoc/>
@@ -119,7 +123,7 @@ public class ProfileDictionary<TProfile, TKey, TValue> : ICollection<KeyValuePai
119
123
public bool Remove(KeyValuePair<TKey, TValue> item)
120
124
{
121
125
var result = ((ICollection<KeyValuePair<TKey, TValue>>)_innerDictionary).Remove(item);
122
XFEProfile.SaveProfile(typeof(TProfile));
126
CurrentProfile?.InstanceSaveProfile();
123
127
return result;
124
128
}
125
129
@@ -127,7 +131,7 @@ public class ProfileDictionary<TProfile, TKey, TValue> : ICollection<KeyValuePai
127
131
public bool Remove(TKey key)
128
132
{
129
133
var result = ((IDictionary<TKey, TValue>)_innerDictionary).Remove(key);
130
XFEProfile.SaveProfile(typeof(TProfile));
134
CurrentProfile?.InstanceSaveProfile();
131
135
return result;
132
136
}
133
137
@@ -135,7 +139,7 @@ public class ProfileDictionary<TProfile, TKey, TValue> : ICollection<KeyValuePai
135
139
public void Remove(object key)
136
140
{
137
141
((IDictionary)_innerDictionary).Remove(key);
138
XFEProfile.SaveProfile(typeof(TProfile));
142
CurrentProfile?.InstanceSaveProfile();
139
143
}
140
144
141
145
///<inheritdoc/>
@@ -145,7 +149,7 @@ public class ProfileDictionary<TProfile, TKey, TValue> : ICollection<KeyValuePai
145
149
public bool TryAdd(TKey key, TValue value)
146
150
{
147
151
var result = _innerDictionary.TryAdd(key, value);
148
XFEProfile.SaveProfile(typeof(TProfile));
152
CurrentProfile?.InstanceSaveProfile();
149
153
return result;
150
154
}
151
155
@@ -5,9 +5,8 @@ namespace XFEExtension.NetCore.AutoConfig;
5
5
/// <summary>
6
6
/// 配置文件列表
7
7
/// </summary>
8
/// <typeparam name="TProfile">配置文件类型</typeparam>
9
8
/// <typeparam name="TValue">列表泛型</typeparam>
10
public class ProfileList<TProfile, TValue> : ICollection<TValue>, IEnumerable<TValue>, IEnumerable, IList<TValue>, IReadOnlyCollection<TValue>, IReadOnlyList<TValue>, ICollection, IList where TProfile : XFEProfile
9
public class ProfileList<TValue> : ICollection<TValue>, IEnumerable<TValue>, IEnumerable, IList<TValue>, IReadOnlyCollection<TValue>, IReadOnlyList<TValue>, ICollection, IList
11
10
{
12
11
private readonly List<TValue> _innerList;
13
12
@@ -26,6 +25,11 @@ public class ProfileList<TProfile, TValue> : ICollection<TValue>, IEnumerable<TV
26
25
public TValue this[int index] { get => ((IList<TValue>)_innerList)[index]; set => ((IList<TValue>)_innerList)[index] = value; }
27
26
object? IList.this[int index] { get => ((IList)_innerList)[index]; set => ((IList)_innerList)[index] = value; }
28
27
28
/// <summary>
29
/// 当前配置文件实例
30
/// </summary>
31
public XFEProfile? CurrentProfile { get; set; }
32
29
33
///<inheritdoc/>
30
34
public int Count => ((ICollection<TValue>)_innerList).Count;
31
35
@@ -45,14 +49,14 @@ public class ProfileList<TProfile, TValue> : ICollection<TValue>, IEnumerable<TV
45
49
public void Add(TValue item)
46
50
{
47
51
((ICollection<TValue>)_innerList).Add(item);
48
XFEProfile.SaveProfile(typeof(TProfile));
52
CurrentProfile?.InstanceSaveProfile();
49
53
}
50
54
51
55
///<inheritdoc/>
52
56
public int Add(object? value)
53
57
{
54
58
var result = ((IList)_innerList).Add(value);
55
XFEProfile.SaveProfile(typeof(TProfile));
59
CurrentProfile?.InstanceSaveProfile();
56
60
return result;
57
61
}
58
62
@@ -60,21 +64,21 @@ public class ProfileList<TProfile, TValue> : ICollection<TValue>, IEnumerable<TV
60
64
public void AddRange(IEnumerable<TValue> collection)
61
65
{
62
66
_innerList.AddRange(collection);
63
XFEProfile.SaveProfile(typeof(TProfile));
67
CurrentProfile?.InstanceSaveProfile();
64
68
}
65
69
66
70
///<inheritdoc/>
67
71
public void AddRange(ReadOnlySpan<TValue> source)
68
72
{
69
73
_innerList.AddRange(source);
70
XFEProfile.SaveProfile(typeof(TProfile));
74
CurrentProfile?.InstanceSaveProfile();
71
75
}
72
76
73
77
///<inheritdoc/>
74
78
public void Clear()
75
79
{
76
80
((ICollection<TValue>)_innerList).Clear();
77
XFEProfile.SaveProfile(typeof(TProfile));
81
CurrentProfile?.InstanceSaveProfile();
78
82
}
79
83
80
84
///<inheritdoc/>
@@ -102,21 +106,21 @@ public class ProfileList<TProfile, TValue> : ICollection<TValue>, IEnumerable<TV
102
106
public void Insert(int index, TValue item)
103
107
{
104
108
((IList<TValue>)_innerList).Insert(index, item);
105
XFEProfile.SaveProfile(typeof(TProfile));
109
CurrentProfile?.InstanceSaveProfile();
106
110
}
107
111
108
112
///<inheritdoc/>
109
113
public void Insert(int index, object? value)
110
114
{
111
115
((IList)_innerList).Insert(index, value);
112
XFEProfile.SaveProfile(typeof(TProfile));
116
CurrentProfile?.InstanceSaveProfile();
113
117
}
114
118
115
119
///<inheritdoc/>
116
120
public bool Remove(TValue item)
117
121
{
118
122
var result = ((ICollection<TValue>)_innerList).Remove(item);
119
XFEProfile.SaveProfile(typeof(TProfile));
123
CurrentProfile?.InstanceSaveProfile();
120
124
return result;
121
125
}
122
126
@@ -124,14 +128,14 @@ public class ProfileList<TProfile, TValue> : ICollection<TValue>, IEnumerable<TV
124
128
public void Remove(object? value)
125
129
{
126
130
((IList)_innerList).Remove(value);
127
XFEProfile.SaveProfile(typeof(TProfile));
131
CurrentProfile?.InstanceSaveProfile();
128
132
}
129
133
130
134
///<inheritdoc/>
131
135
public void RemoveAt(int index)
132
136
{
133
137
((IList<TValue>)_innerList).RemoveAt(index);
134
XFEProfile.SaveProfile(typeof(TProfile));
138
CurrentProfile?.InstanceSaveProfile();
135
139
}
136
140
137
141
IEnumerator IEnumerable.GetEnumerator() => ((IEnumerable)_innerList).GetEnumerator();
@@ -18,35 +18,35 @@ public abstract class XFEProfile
18
18
/// <summary>
19
19
/// 配置文件存储位置
20
20
/// </summary>
21
public string ProfilePath { get; set; } = string.Empty;
21
internal protected string ProfilePath { get; set; } = string.Empty;
22
22
/// <summary>
23
23
/// 配置文件扩展名
24
24
/// </summary>
25
public string ProfileFileExtension { get; set; } = ".xpf";
25
internal protected string ProfileFileExtension { get; set; } = ".xpf";
26
26
/// <summary>
27
27
/// 默认配置文件存储和读取的操作模式
28
28
/// </summary>
29
public ProfileOperationMode DefaultProfileOperationMode { get; set; } = ProfileOperationMode.XFEDictionary;
29
internal protected ProfileOperationMode DefaultProfileOperationMode { get; set; } = ProfileOperationMode.XFEDictionary;
30
30
/// <summary>
31
31
/// 加载操作
32
32
/// </summary>
33
public ProfileLoadOperation LoadOperation { get; set; } = XFEDictionaryLoadProfileOperation;
33
internal protected ProfileLoadOperation LoadOperation { get; set; } = XFEDictionaryLoadProfileOperation;
34
34
/// <summary>
35
35
/// 保存操作
36
36
/// </summary>
37
public ProfileSaveOperation SaveOperation { get; set; } = XFEDictionarySaveProfileOperation;
37
internal protected ProfileSaveOperation SaveOperation { get; set; } = XFEDictionarySaveProfileOperation;
38
38
/// <summary>
39
39
/// 配置文件 “属性名称-属性类型” 字典
40
40
/// </summary>
41
public Dictionary<string, Type> PropertyInfoDictionary { get; set; } = [];
41
internal protected Dictionary<string, Type> PropertyInfoDictionary { get; set; } = [];
42
42
/// <summary>
43
43
/// 配置文件 “属性名称-属性设置方法” 字典
44
44
/// </summary>
45
public Dictionary<string, SetValueDelegate> PropertySetFuncDictionary { get; set; } = [];
45
internal protected Dictionary<string, SetValueDelegate> PropertySetFuncDictionary { get; set; } = [];
46
46
/// <summary>
47
47
/// 配置文件 “属性名称-属性获取方法” 字典
48
48
/// </summary>
49
public Dictionary<string, GetValueDelegate> PropertyGetFuncDictionary { get; set; } = [];
49
internal protected Dictionary<string, GetValueDelegate> PropertyGetFuncDictionary { get; set; } = [];
50
50
/// <summary>
51
51
/// 通过XFE字典加载配置文件方法(默认)
52
52
/// </summary>
@@ -129,18 +129,17 @@ public abstract class XFEProfile
129
129
/// 加载配置文件
130
130
/// </summary>
131
131
/// <returns>配置文件实例</returns>
132
public XFEProfile InstanceLoadProfile()
132
internal protected XFEProfile InstanceLoadProfile()
133
133
{
134
134
if (File.Exists(ProfilePath))
135
135
return LoadOperation(this, File.ReadAllText(ProfilePath), PropertyInfoDictionary, PropertySetFuncDictionary);
136
136
return this;
137
137
}
138
139
138
/// <summary>
140
139
/// 保存配置文件
141
140
/// </summary>
142
141
/// <returns>保存内容</returns>
143
public void InstanceSaveProfile()
142
internal protected void InstanceSaveProfile()
144
143
{
145
144
var saveContent = SaveOperation(this, PropertyInfoDictionary, PropertyGetFuncDictionary);
146
145
var fileSavePath = Path.GetDirectoryName(ProfilePath);
@@ -152,7 +151,7 @@ public abstract class XFEProfile
152
151
/// <summary>
153
152
/// 删除配置文件
154
153
/// </summary>
155
public void InstanceDeleteProfile()
154
internal protected void InstanceDeleteProfile()
156
155
{
157
156
if (File.Exists(ProfilePath))
158
157
File.Delete(ProfilePath);
@@ -161,31 +160,34 @@ public abstract class XFEProfile
161
160
/// 导出配置文件
162
161
/// </summary>
163
162
/// <returns></returns>
164
public string InstanceExportProfile() => SaveOperation(this, PropertyInfoDictionary, PropertyGetFuncDictionary);
163
internal protected string InstanceExportProfile() => SaveOperation(this, PropertyInfoDictionary, PropertyGetFuncDictionary);
165
164
/// <summary>
166
165
/// 导入配置文件
167
166
/// </summary>
168
167
/// <param name="profileString">配置文件字符串</param>
169
168
/// <returns></returns>
170
public XFEProfile InstanceImportProfile(string profileString) => LoadOperation(this, profileString, PropertyInfoDictionary, PropertySetFuncDictionary);
169
internal protected XFEProfile InstanceImportProfile(string profileString) => LoadOperation(this, profileString, PropertyInfoDictionary, PropertySetFuncDictionary);
171
170
/// <summary>
172
171
/// 设置配置文件加载和存储操作
173
172
/// </summary>
174
public void SetProfileOperation()
173
internal protected void SetProfileOperation()
175
174
{
176
175
switch (DefaultProfileOperationMode)
177
176
{
178
177
case ProfileOperationMode.XFEDictionary:
179
178
LoadOperation = XFEDictionaryLoadProfileOperation;
180
179
SaveOperation = XFEDictionarySaveProfileOperation;
180
ProfileFileExtension = ".xpf";
181
181
break;
182
182
case ProfileOperationMode.Json:
183
183
LoadOperation = JsonLoadProfileOperation;
184
184
SaveOperation = JsonSaveProfileOperation;
185
ProfileFileExtension = ".json";
185
186
break;
186
187
case ProfileOperationMode.Xml:
187
188
LoadOperation = XmlLoadProfileOperation;
188
189
SaveOperation = XmlSaveProfileOperation;
190
ProfileFileExtension = ".xml";
189
191
break;
190
192
case ProfileOperationMode.Custom:
191
193
break;