XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFEExtension.NetCore.AutoConfig

【DLL】自动实现配置文件的存储

公开
关注 0 Fork 0 Star 0
返回提交历史

XFEstudio/XFEExtension.NetCore.AutoConfig

修复部分bug,并改用Initialize方法进行初始化

1b31fbb
XFE工作室室长 <mail@xfegzs.com>
提交于

代码差异

5 个文件 +94 -76
Modified AutoConfig.Analyzer.Test/Program.cs +36 -33
@@ -1,4 +1,5 @@
1 using System.Text.Json;
1 using System.Diagnostics.CodeAnalysis;
2 using System.Text.Json;
2 3 using XFEExtension.NetCore.StringExtension;
3 4 using XFEExtension.NetCore.StringExtension.Json;
4 5
@@ -6,41 +7,43 @@ namespace AutoConfig.Analyzer.Test;
6 7
7 8 public class Program
8 9 {
10 [DynamicDependency(DynamicallyAccessedMemberTypes.PublicProperties, typeof(UserInfo))]
9 11 public static void Main(string[] args)
10 12 {
11 Console.WriteLine($"上一次读取的值是{SystemProfile.MyText}");
12 var current = SystemProfile.Current;
13 Console.Write("添加值:");
14 SystemProfile.MyText = Console.ReadLine();
15 Console.WriteLine(SystemProfile.MyText);
16 Console.ReadLine();
17
13 //Console.WriteLine($"上一次读取的值是{SystemProfile.MyText}");
14 //var current = SystemProfile.Current;
15 //Console.Write("添加值:");
16 //SystemProfile.MyText = Console.ReadLine();
17 //Console.WriteLine(SystemProfile.MyText);
18 //Console.ReadLine();
18 19
19 20
20 //Console.WriteLine($"上一次读取的值是:{UserProfile.UserInfoList.ToJson()}");
21 //Console.WriteLine("添加值:");
22 //Console.WriteLine("请输入店铺名称:");
23 //var shopName = Console.ReadLine();
24 //Console.WriteLine("请输入店铺ID:");
25 //var shopID = Console.ReadLine() ?? "暂无ID";
26 //Console.WriteLine("创建对象...");
27 //var target = new UserInfo()
28 //{
29 // SessionID = Guid.NewGuid().ToString(),
30 // ShopID = shopID,
31 // RecentShopName = shopName,
32 // CurrentIpAddress = "198.131.114.41",
33 // Banned = false,
34 // EndDateTime = DateTime.Now
35 //};
36 //Console.WriteLine(target.ShopID);
37 //Console.WriteLine(JsonSerializer.Serialize(target));
38 //Console.WriteLine("对象创建完成!准备进行分析...");
39 //target.X();
40 //Console.WriteLine(target.ToJson());
41 //Console.WriteLine("分析完成!");
42 //UserProfile.UserInfoList.Add(target);
43 //Console.WriteLine(UserProfile.UserInfoList.ToJson());
44 //Console.ReadLine();
21 var type = typeof(UserInfo);
22 Console.WriteLine(type.Name);
23 Console.WriteLine($"上一次读取的值是:{UserProfile.UserInfoList.ToJson()}");
24 Console.WriteLine("添加值:");
25 Console.WriteLine("请输入店铺名称:");
26 var shopName = Console.ReadLine();
27 Console.WriteLine("请输入店铺ID:");
28 var shopID = Console.ReadLine() ?? "暂无ID";
29 Console.WriteLine("创建对象...");
30 var target = new UserInfo()
31 {
32 SessionID = Guid.NewGuid().ToString(),
33 ShopID = shopID,
34 RecentShopName = shopName,
35 CurrentIpAddress = "198.131.114.41",
36 Banned = false,
37 EndDateTime = DateTime.Now
38 };
39 Console.WriteLine(target.ShopID);
40 Console.WriteLine(JsonSerializer.Serialize(target));
41 Console.WriteLine("对象创建完成!准备进行分析...");
42 target.X();
43 Console.WriteLine(target.ToJson());
44 Console.WriteLine("分析完成!");
45 UserProfile.UserInfoList.Add(target);
46 Console.WriteLine(UserProfile.UserInfoList.ToJson());
47 Console.ReadLine();
45 48 }
46 49 }
Modified AutoConfig.Analyzer.Test/SystemProfile.cs +1 -1
@@ -11,6 +11,6 @@ public partial class SystemProfile : XFEProfile
11 11
12 12 public SystemProfile()
13 13 {
14 DefaultProfileOperationMode = ProfileOperationMode.Json;
14 DefaultProfileOperationMode = ProfileOperationMode.Xml;
15 15 }
16 16 }
Modified AutoConfig.Analyzer.Test/UserInfo.cs +1 -1
@@ -16,7 +16,7 @@ public class UserInfo
16 16 /// <summary>
17 17 /// 当前活动期ID
18 18 /// </summary>
19 public required string SessionID { get; set; }
19 public required string SessionID { get; set; } = Guid.NewGuid().ToString();
20 20 /// <summary>
21 21 /// 最近一次登录的IP地址
22 22 /// </summary>
Modified XFEExtension.NetCore.AutoConfig.Analyzer/Generator/ProfilePropertyAutoGenerator.cs +34 -31
@@ -39,11 +39,10 @@ public class ProfilePropertyAutoGenerator : IIncrementalGenerator
39 39 var instanceProperties = new List<PropertyDeclarationSyntax>();
40 40 var basicProfileMembers = new List<MemberDeclarationSyntax>();
41 41 var methodMembers = new List<MemberDeclarationSyntax>();
42 var staticConstructorBlockStatements = new List<StatementSyntax>()
42 var initializerBlockStatements = new List<StatementSyntax>()
43 43 {
44 SyntaxFactory.ParseStatement($"Current = new {className}();"),
45 SyntaxFactory.ParseStatement($"Current.SetProfileOperation();"),
46 SyntaxFactory.ParseStatement($@"Current.ProfilePath = $""{{(string.IsNullOrEmpty(Current.ProfilePath) ? $""{{(global::XFEExtension.NetCore.AutoConfig.XFEProfile.ProfilesDefaultPath)}}\\{{nameof({className})}}"" : Current.ProfilePath)}}{{Current.ProfileFileExtension}}"";")
44 SyntaxFactory.ParseStatement($"this.SetProfileOperation();"),
45 SyntaxFactory.ParseStatement($@"this.ProfilePath = $""{{(string.IsNullOrEmpty(this.ProfilePath) ? $""{{(global::XFEExtension.NetCore.AutoConfig.XFEProfile.ProfilesDefaultPath)}}\\{{nameof({className})}}"" : this.ProfilePath)}}{{this.ProfileFileExtension}}"";")
47 46 };
48 47 foreach (var fieldDeclarationSyntax in fieldDeclarationSyntaxes)
49 48 {
@@ -54,9 +53,9 @@ public class ProfilePropertyAutoGenerator : IIncrementalGenerator
54 53 var instancePropertyName = $"Instance{propertyName}";
55 54 var getMethodName = $"Get{propertyName}Property";
56 55 var setMethodName = $"Set{propertyName}Property";
57 staticConstructorBlockStatements.Add(SyntaxFactory.ParseStatement($"Current.PropertyInfoDictionary.Add(nameof({propertyName}), typeof({propertyType}));"));
58 staticConstructorBlockStatements.Add(SyntaxFactory.ParseStatement($"Current.PropertySetFuncDictionary.Add(nameof({propertyName}), (value) => Current.{fieldName} = ({propertyType})value);"));
59 staticConstructorBlockStatements.Add(SyntaxFactory.ParseStatement($"Current.PropertyGetFuncDictionary.Add(nameof({propertyName}), () => Current.{fieldName});"));
56 initializerBlockStatements.Add(SyntaxFactory.ParseStatement($"this.PropertyInfoDictionary.Add(nameof({propertyName}), typeof({propertyType}));"));
57 initializerBlockStatements.Add(SyntaxFactory.ParseStatement($"this.PropertySetFuncDictionary.Add(nameof({propertyName}), (value) => this.{fieldName} = ({propertyType})value);"));
58 initializerBlockStatements.Add(SyntaxFactory.ParseStatement($"this.PropertyGetFuncDictionary.Add(nameof({propertyName}), () => this.{fieldName});"));
60 59 GetProfilePropertyAttributeList(fieldDeclarationSyntax).ForEach(attribute =>
61 60 {
62 61 if (attribute.ArgumentList is null)
@@ -209,30 +208,9 @@ public class ProfilePropertyAutoGenerator : IIncrementalGenerator
209 208 ")));
210 209 staticProperties.Add(staticProperty.NormalizeWhitespace());
211 210 }
212 staticConstructorBlockStatements.Add(SyntaxFactory.ParseStatement($"{className}.LoadProfile();"));
213 var staticConstructorSyntax = SyntaxFactory.ConstructorDeclaration(className)
214 .AddModifiers(SyntaxFactory.Token(SyntaxKind.StaticKeyword))
215 .WithBody(SyntaxFactory.Block(staticConstructorBlockStatements));
216 if (classDeclaration.AttributeLists.Any(IsAutoLoadProfileAttribute))
217 {
218 var autoLoadProfileAttribute = classDeclaration.AttributeLists.First(IsAutoLoadProfileAttribute).Attributes.First();
219 if (autoLoadProfileAttribute.ArgumentList != null)
220 {
221 var argument = autoLoadProfileAttribute.ArgumentList.Arguments.First();
222 if (argument.Expression is LiteralExpressionSyntax literalExpressionSyntax && literalExpressionSyntax.Token.ValueText == "true")
223 {
224 basicProfileMembers.Add(staticConstructorSyntax);
225 }
226 }
227 else
228 {
229 basicProfileMembers.Add(staticConstructorSyntax);
230 }
231 }
232 else
233 {
234 basicProfileMembers.Add(staticConstructorSyntax);
235 }
211 basicProfileMembers.Add(SyntaxFactory.MethodDeclaration(SyntaxFactory.ParseTypeName("void"), "Initialize")
212 .WithModifiers(SyntaxFactory.TokenList(SyntaxFactory.Token(SyntaxKind.PublicKeyword), SyntaxFactory.Token(SyntaxKind.OverrideKeyword)))
213 .WithBody(SyntaxFactory.Block(initializerBlockStatements)));
236 214 var basicProfileClassSyntaxTree = GenerateBasicProfileClassSyntaxTree(classDeclaration, usingDirectives, basicProfileMembers, fileScopedNamespaceDeclarationSyntax);
237 215 var profileStaticPropertyClassSyntaxTree = GenerateProfileStaticPropertyClassSyntaxTree(classDeclaration, usingDirectives, staticProperties, fileScopedNamespaceDeclarationSyntax);
238 216 var profileInstancePropertyClassSyntaxTree = GenerateProfileInstancePropertyClassSyntaxTree(classDeclaration, usingDirectives, instanceProperties, fileScopedNamespaceDeclarationSyntax);
@@ -299,6 +277,29 @@ public class ProfilePropertyAutoGenerator : IIncrementalGenerator
299 277 private static SyntaxTree GenerateBasicProfileClassSyntaxTree(ClassDeclarationSyntax classDeclaration, UsingDirectiveSyntax[] usingDirectiveSyntaxes, List<MemberDeclarationSyntax> memberDeclarationSyntaxes, FileScopedNamespaceDeclarationSyntax fileScopedNamespaceDeclarationSyntax)
300 278 {
301 279 var className = classDeclaration.Identifier.ValueText;
280 var staticConstructorSyntax = SyntaxFactory.ConstructorDeclaration(className)
281 .AddModifiers(SyntaxFactory.Token(SyntaxKind.StaticKeyword))
282 .WithBody(SyntaxFactory.Block(SyntaxFactory.ParseStatement($"Current.Initialize();"), SyntaxFactory.ParseStatement($"{className}.LoadProfile();")));
283 if (classDeclaration.AttributeLists.Any(IsAutoLoadProfileAttribute))
284 {
285 var autoLoadProfileAttribute = classDeclaration.AttributeLists.First(IsAutoLoadProfileAttribute).Attributes.First();
286 if (autoLoadProfileAttribute.ArgumentList != null)
287 {
288 var argument = autoLoadProfileAttribute.ArgumentList.Arguments.First();
289 if (argument.Expression is LiteralExpressionSyntax literalExpressionSyntax && literalExpressionSyntax.Token.ValueText == "true")
290 {
291 memberDeclarationSyntaxes.Add(staticConstructorSyntax);
292 }
293 }
294 else
295 {
296 memberDeclarationSyntaxes.Add(staticConstructorSyntax);
297 }
298 }
299 else
300 {
301 memberDeclarationSyntaxes.Add(staticConstructorSyntax);
302 }
302 303 memberDeclarationSyntaxes.Add(SyntaxFactory.PropertyDeclaration(SyntaxFactory.ParseTypeName(className), "Current")
303 304 .WithModifiers(SyntaxFactory.TokenList(SyntaxFactory.Token(SyntaxKind.PublicKeyword), SyntaxFactory.Token(SyntaxKind.StaticKeyword)))
304 305 .AddAttributeLists(SyntaxFactory.AttributeList(SyntaxFactory.SingletonSeparatedList(SyntaxFactory.Attribute(SyntaxFactory.ParseName("global::XFEExtension.NetCore.AutoConfig.ProfileInstanceAttribute")))))
@@ -309,6 +310,8 @@ public class ProfilePropertyAutoGenerator : IIncrementalGenerator
309 310 SyntaxFactory.AccessorDeclaration(SyntaxKind.SetAccessorDeclaration)
310 311 .WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken))
311 312 ])))
313 .WithInitializer(SyntaxFactory.EqualsValueClause(SyntaxFactory.ParseExpression($"new()")))
314 .WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken))
312 315 .WithLeadingTrivia(SyntaxFactory.ParseLeadingTrivia($@"/// <summary>
313 316 /// 该配置文件的实例<br/><br/>
314 317 /// <seealso cref=""{className}.Current""/> 是 <seealso cref=""{className}""/> 配置文件类的实例数据
Modified XFEExtension.NetCore.AutoConfig/XFEProfile.cs +22 -10
@@ -15,7 +15,7 @@ public abstract class XFEProfile
15 15 /// <summary>
16 16 /// 配置文件所在的默认目录
17 17 /// </summary>
18 public static string ProfilesDefaultPath { get; set; } = $"{AppDomain.CurrentDomain.BaseDirectory}/Profiles";
18 public static string ProfilesDefaultPath { get; set; } = $@"{AppDomain.CurrentDomain.BaseDirectory}Profiles";
19 19 /// <summary>
20 20 /// 配置文件存储位置
21 21 /// </summary>
@@ -56,13 +56,13 @@ public abstract class XFEProfile
56 56 /// <param name="propertyInfoDictionary">配置文件 “属性名称-属性类型” 字典</param>
57 57 /// <param name="propertySetFuncDictionary">配置文件 “属性名称-属性设置方法” 字典</param>
58 58 /// <returns>配置文件实例</returns>
59 public static XFEProfile XFEDictionaryLoadProfileOperation(XFEProfile profileInstance, string profileString, Dictionary<string, Type> propertyInfoDictionary, Dictionary<string, SetValueDelegate> propertySetFuncDictionary)
59 public static XFEProfile? XFEDictionaryLoadProfileOperation(XFEProfile profileInstance, string profileString, Dictionary<string, Type> propertyInfoDictionary, Dictionary<string, SetValueDelegate> propertySetFuncDictionary)
60 60 {
61 61 XFEDictionary propertyFileContent = profileString;
62 62 foreach (var property in propertyFileContent)
63 63 if (propertySetFuncDictionary.TryGetValue(property.Header, out var setValueDelegate) && propertyInfoDictionary.TryGetValue(property.Header, out var type))
64 64 setValueDelegate(JsonSerializer.Deserialize(property.Content, type));
65 return profileInstance;
65 return null;
66 66 }
67 67 /// <summary>
68 68 /// 通过XFE字典保存配置文件方法(默认)
@@ -88,7 +88,7 @@ public abstract class XFEProfile
88 88 /// <param name="propertyInfoDictionary">配置文件 “属性名称-属性类型” 字典</param>
89 89 /// <param name="propertySetFuncDictionary">配置文件 “属性名称-属性设置方法” 字典</param>
90 90 /// <returns>配置文件实例</returns>
91 public static XFEProfile JsonLoadProfileOperation(XFEProfile profileInstance, string profileString, Dictionary<string, Type> propertyInfoDictionary, Dictionary<string, SetValueDelegate> propertySetFuncDictionary) => JsonSerializer.Deserialize(profileString, profileInstance.GetType()) is XFEProfile xFEProfile ? xFEProfile : profileInstance;
91 public static XFEProfile? JsonLoadProfileOperation(XFEProfile profileInstance, string profileString, Dictionary<string, Type> propertyInfoDictionary, Dictionary<string, SetValueDelegate> propertySetFuncDictionary) => JsonSerializer.Deserialize(profileString, profileInstance.GetType()) is XFEProfile xFEProfile ? xFEProfile : null;
92 92
93 93 /// <summary>
94 94 /// 通过Json保存配置文件方法
@@ -106,7 +106,8 @@ public abstract class XFEProfile
106 106 /// <param name="propertyInfoDictionary">配置文件 “属性名称-属性类型” 字典</param>
107 107 /// <param name="propertySetFuncDictionary">配置文件 “属性名称-属性设置方法” 字典</param>
108 108 /// <returns>配置文件实例</returns>
109 public static XFEProfile XmlLoadProfileOperation(XFEProfile profileInstance, string profileString, Dictionary<string, Type> propertyInfoDictionary, Dictionary<string, SetValueDelegate> propertySetFuncDictionary) => string.IsNullOrEmpty(profileString) ? new XmlSerializer(profileInstance.GetType()).Deserialize(new MemoryStream(Encoding.UTF8.GetBytes(profileString))) is XFEProfile xFEProfile ? xFEProfile : profileInstance : profileInstance;
109 public static XFEProfile? XmlLoadProfileOperation(XFEProfile profileInstance, string profileString, Dictionary<string, Type> propertyInfoDictionary, Dictionary<string, SetValueDelegate> propertySetFuncDictionary) => !string.IsNullOrEmpty(profileString) && new XmlSerializer(profileInstance.GetType()).Deserialize(new MemoryStream(Encoding.UTF8.GetBytes(profileString))) is XFEProfile xFEProfile ? xFEProfile : null;
110
110 111 /// <summary>
111 112 /// 通过XML保存配置文件方法
112 113 /// </summary>
@@ -129,8 +130,11 @@ public abstract class XFEProfile
129 130 /// <returns>配置文件实例</returns>
130 131 internal protected XFEProfile InstanceLoadProfile()
131 132 {
132 if (File.Exists(ProfilePath))
133 return LoadOperation(this, File.ReadAllText(ProfilePath), PropertyInfoDictionary, PropertySetFuncDictionary);
133 if (File.Exists(ProfilePath) && LoadOperation(this, File.ReadAllText(ProfilePath), PropertyInfoDictionary, PropertySetFuncDictionary) is XFEProfile xFEProfile)
134 {
135 xFEProfile.Initialize();
136 return xFEProfile;
137 }
134 138 return this;
135 139 }
136 140 /// <summary>
@@ -164,7 +168,15 @@ public abstract class XFEProfile
164 168 /// </summary>
165 169 /// <param name="profileString">配置文件字符串</param>
166 170 /// <returns></returns>
167 internal protected XFEProfile InstanceImportProfile(string profileString) => LoadOperation(this, profileString, PropertyInfoDictionary, PropertySetFuncDictionary);
171 internal protected XFEProfile InstanceImportProfile(string profileString)
172 {
173 if (LoadOperation(this, File.ReadAllText(ProfilePath), PropertyInfoDictionary, PropertySetFuncDictionary) is XFEProfile xFEProfile)
174 {
175 xFEProfile.Initialize();
176 return xFEProfile;
177 }
178 return this;
179 }
168 180 /// <summary>
169 181 /// 设置配置文件加载和存储操作
170 182 /// </summary>
@@ -196,7 +208,7 @@ public abstract class XFEProfile
196 208 /// <summary>
197 209 /// 初始化
198 210 /// </summary>
199 protected virtual void Initialize() => SetProfileOperation();
211 public virtual void Initialize() => SetProfileOperation();
200 212 #region 已过时
201 213 [Obsolete("SaveProfilesFunc属性现已过时,对于每个配置文件实例,请使用 XXXProfile.SaveOperation")]
202 214 private static Func<object?, ProfileEntryInfo, string> SaveProfilesFunc { get; set; } = (i, p) =>
@@ -520,7 +532,7 @@ public delegate string ProfileSaveOperation(XFEProfile profileInstance, Dictiona
520 532 /// <param name="profileString">配置文件字符串</param>
521 533 /// <param name="propertyInfoDictionary">配置文件 “属性名称-属性类型” 字典</param>
522 534 /// <param name="propertySetFuncDictionary">配置文件 “属性名称-属性设置方法” 字典</param>
523 public delegate XFEProfile ProfileLoadOperation(XFEProfile profileInstance, string profileString, Dictionary<string, Type> propertyInfoDictionary, Dictionary<string, SetValueDelegate> propertySetFuncDictionary);
535 public delegate XFEProfile? ProfileLoadOperation(XFEProfile profileInstance, string profileString, Dictionary<string, Type> propertyInfoDictionary, Dictionary<string, SetValueDelegate> propertySetFuncDictionary);
524 536 /// <summary>
525 537 /// 设置配置文件属性值委托
526 538 /// </summary>