Browse Source

Add NotificationServiceMap

felix 2 years ago
parent
commit
78dd6a9a27
4 changed files with 152 additions and 19 deletions
  1. 33 11
      CodeGenerator.cs
  2. 6 6
      ModelType.cs
  3. 106 2
      NotificationServiceMap.cs
  4. 7 0
      VirtualNotification.cs

+ 33 - 11
CodeGenerator.cs

@@ -50,17 +50,23 @@ namespace FlutterCodeGenerator
             var restTypes = allTypes.Where(x => !x.FullName.Contains("DB") && !x.Name.EndsWith("ManagementService") && !x.Name.EndsWith("NotificationService")).ToList();
             var interfaceTypes = restTypes.Where(x => x.FullName.EndsWith("Service") && x.IsInterface).ToList();
             restTypes = restTypes.Except(interfaceTypes).ToList();
+            var inotificationDTOType = restTypes.FirstOrDefault(x => x.Name.Contains("INotificationDTO"));
+            var notificationEnumType = inotificationDTOType.GetProperties().First().PropertyType;
+            if (notificationEnumType == null)
+            {
+                throw new Exception("Find NotificationEnumType Failed");
+            }
             var notificationTypes = restTypes.Where(x => x.GetInterfaces().Any(x => x.Name.Contains("INotificationDTO"))).ToList();
             restTypes = restTypes.Except(notificationTypes).ToList();
             var restNeedGeneratedTypes = restTypes.Where(x => !x.GetProperties().Any(y => y.PropertyType == typeof(object)) && !x.GetProperties().Any(y => string.IsNullOrWhiteSpace(y.PropertyType.FullName))).ToList();
+            var notificationServiceMap = new NotificationServiceMap(notificationEnumType, notificationTypes);
+            _serviceMapDictionary.Add("notificationService", notificationServiceMap);
             foreach (var interfaceType in interfaceTypes)
             {
                 var sericeName = interfaceType.Name[1..];
                 var serviceMap = new ServiceMap(interfaceType);
                 _serviceMapDictionary.Add(LetterConverterHelper.FirstCharToLower(sericeName), serviceMap);
             }
-            var notificationServiceMap = new NotificationServiceMap(notificationTypes);
-            _serviceMapDictionary.Add("notificationService", notificationServiceMap);
             var otherServiceMap = new OtherServiceMap(restNeedGeneratedTypes);
             _serviceMapDictionary.Add("otherService", otherServiceMap);
         }
@@ -86,15 +92,7 @@ namespace FlutterCodeGenerator
                 var serviceModelDartPath = Path.Combine(_serviceFolderPath, serviceModelDartFileName);
                 var serviceModelDartString = serviceMap.Value.GetServiceModelDartString();
                 var serviceString = serviceMap.Value.GetServiceDartString();
-                if (string.IsNullOrWhiteSpace(serviceString))
-                {
-                    if (serviceModelDartString != null)
-                    {
-                        File.WriteAllText(serviceModelDartPath, serviceModelDartString);
-                        _generatedServiceModelFileNameList.Add(serviceModelDartFileName);
-                    }
-                }
-                else
+                if (serviceMap.Value is ServiceMap)
                 {
                     var serviceDartString = new StringBuilder();
                     serviceDartString.AppendLine(StringDartCore);
@@ -116,6 +114,30 @@ namespace FlutterCodeGenerator
                     File.WriteAllText(serviceDartPath, serviceDartString.ToString());
                     _generatedServiceFileNameList.Add(serviceDartFileName);
                 }
+                else if (serviceMap.Value is NotificationServiceMap notificationServiceMap)
+                {
+                    if (serviceModelDartString != null)
+                    {
+                        File.WriteAllText(serviceModelDartPath, serviceModelDartString);
+                        _generatedServiceModelFileNameList.Add(serviceModelDartFileName);
+                    }
+                    var decodeDartString = notificationServiceMap.GetDecodeDartString();
+                    if (decodeDartString != null)
+                    {
+                        var decodeDartFileName = "notificationdecoder.dart";
+                        var decodeDartPath = Path.Combine(_serviceFolderPath, decodeDartFileName);
+                        File.WriteAllText(decodeDartPath, decodeDartString);
+                        _generatedServiceFileNameList.Add(decodeDartFileName);
+                    }
+                }
+                else if (serviceMap.Value is OtherServiceMap)
+                {
+                    if (serviceModelDartString != null)
+                    {
+                        File.WriteAllText(serviceModelDartPath, serviceModelDartString);
+                        _generatedServiceModelFileNameList.Add(serviceModelDartFileName);
+                    }
+                }
             }
             GenerateIndexDart();
             GenerateRpcDart();

+ 6 - 6
ModelType.cs

@@ -485,11 +485,11 @@ namespace FlutterCodeGenerator
 
     public class EnumModelType : ComplexModelType
     {
-        private Dictionary<int, string> _userDefinedEnumDictionary;
+        public Dictionary<int, string> UserDefinedEnumDictionary { get; }
 
         public EnumModelType(Type type, string name) : base(type, name)
         {
-            _userDefinedEnumDictionary = new Dictionary<int, string>();
+            UserDefinedEnumDictionary = new Dictionary<int, string>();
             var fields = ParameterType.GetFields();
             if (fields != null && fields.Length > 1)
             {
@@ -503,12 +503,12 @@ namespace FlutterCodeGenerator
                     }
                     else
                     {
-                        _userDefinedEnumDictionary.Add(fieldValue, fieldName);
+                        UserDefinedEnumDictionary.Add(fieldValue, fieldName);
                     }
                 }
-                _userDefinedEnumDictionary = _userDefinedEnumDictionary.OrderBy(x => x.Key).ToDictionary(p => p.Key, o => o.Value);
+                UserDefinedEnumDictionary = UserDefinedEnumDictionary.OrderBy(x => x.Key).ToDictionary(p => p.Key, o => o.Value);
             }
-            var firstChildName = _userDefinedEnumDictionary.FirstOrDefault().Value;
+            var firstChildName = UserDefinedEnumDictionary.FirstOrDefault().Value;
             DefaultValue = $"{GetFlutterTypeName()}.{firstChildName}";
         }
 
@@ -517,7 +517,7 @@ namespace FlutterCodeGenerator
             var dartString = new StringBuilder();
             dartString.AppendLine($"enum {GetFlutterTypeName()} {{");
             int lastValue = 0;
-            foreach (var userDefinedEnum in _userDefinedEnumDictionary)
+            foreach (var userDefinedEnum in UserDefinedEnumDictionary)
             {
                 var index = userDefinedEnum.Key;
                 var name = userDefinedEnum.Value;

+ 106 - 2
NotificationServiceMap.cs

@@ -2,6 +2,7 @@
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;
+using System.Text.Json;
 
 namespace FlutterCodeGenerator
 {
@@ -9,19 +10,25 @@ namespace FlutterCodeGenerator
     {
         private List<Type> _typeList;
         private string _serviceName;
+
+        private EnumModelType _notificationEnumModelType;
+        private List<ModelType> _notificationModelTypeList;
+
         public List<ComplexModelType> UsedComplexModelTypeList { get; }
 
-        public NotificationServiceMap(List<Type> types)
+        public NotificationServiceMap(Type notificationEnumType, List<Type> types)
         {
             _typeList = types;
             UsedComplexModelTypeList = new List<ComplexModelType>();
             GenerateDataCache.Instance.SetCurrentServiceMap(this);
+            _notificationModelTypeList = new List<ModelType>();
+            _notificationEnumModelType = (EnumModelType)ModelTypeGenerator.Create(notificationEnumType, notificationEnumType.Name, true);
             _serviceName = "NotificationService";
             foreach (var type in _typeList)
             {
                 try
                 {
-                    var parameterModelType = ModelTypeGenerator.Create(type, type.Name, true);
+                    _notificationModelTypeList.Add(ModelTypeGenerator.Create(type, type.Name, true));
                 }
                 catch (Exception ex)
                 {
@@ -90,5 +97,102 @@ namespace FlutterCodeGenerator
             serviceModelDartString.AppendLine(dartStringInfo);
             return serviceModelDartString.ToString();
         }
+
+        public string GetDecodeDartString()
+        {
+            var dartString = new StringBuilder();
+            var importServiceList = new List<string>();
+            var alreadyGeneratedList = GenerateDataCache.Instance.AlreadyGeneratedList;
+            dartString.AppendLine("typedef _ModelBuilder<T> = T Function(Map<String, dynamic> map);");
+            dartString.AppendLine("class NotificationDecoder {");
+            dartString.AppendLine("\tNotificationDecoder._();");
+            dartString.AppendLine("");
+            dartString.AppendLine("\tstatic final _builders = _ModelBuilderCollection();");
+            dartString.AppendLine("");
+            dartString.AppendLine("\tstatic T decode<T>(Map<String, dynamic> map) {");
+            dartString.AppendLine("\t\tfinal type = decodeType(map);");
+            dartString.AppendLine("\t\tfinal builder = _builders.find(type);");
+            dartString.AppendLine("\t\tfinal model = builder.call(map) as T;");
+            dartString.AppendLine("\t\treturn model;");
+            dartString.AppendLine("\t}");
+            dartString.AppendLine($"\tstatic {_notificationEnumModelType.Name_Upper} decodeType(Map<String, dynamic> map) {{");
+            dartString.AppendLine("\t\tfinal typeInt = map['type'] as int;");
+            dartString.AppendLine($"\t\treturn {_notificationEnumModelType.Name_Upper}.values[typeInt];");
+            dartString.AppendLine("\t}");
+            dartString.AppendLine("");
+            dartString.AppendLine("\tstatic void setup() {");
+            dartString.AppendLine("\t\t/** Register notification model builders here */");
+            if (alreadyGeneratedList.Any(x => x.Key.ParameterType.Name == _notificationEnumModelType.ParameterType.Name && x.Key.ParameterType.Namespace == _notificationEnumModelType.ParameterType.Namespace))
+            {
+                var importService = alreadyGeneratedList.FirstOrDefault(x => x.Key.ParameterType.Name == _notificationEnumModelType.ParameterType.Name && x.Key.ParameterType.Namespace == _notificationEnumModelType.ParameterType.Namespace).Value;
+                if (importService == null)
+                {
+                    throw new Exception("Import Service is null");
+                }
+                if (!importServiceList.Contains(importService))
+                {
+                    importServiceList.Add(importService);
+                }
+            }
+            foreach (var notificationModelType in _notificationModelTypeList)
+            {
+                if (alreadyGeneratedList.Any(x => x.Key.ParameterType.Name == notificationModelType.ParameterType.Name && x.Key.ParameterType.Namespace == notificationModelType.ParameterType.Namespace))
+                {
+                    var importService = alreadyGeneratedList.FirstOrDefault(x => x.Key.ParameterType.Name == notificationModelType.ParameterType.Name && x.Key.ParameterType.Namespace == notificationModelType.ParameterType.Namespace).Value;
+                    if (importService == null)
+                    {
+                        throw new Exception("Import Service is null");
+                    }
+                    if (!importServiceList.Contains(importService))
+                    {
+                        importServiceList.Add(importService);
+                    }
+                }
+                var instance = Activator.CreateInstance(notificationModelType.ParameterType);
+                var instanceString = JsonSerializer.Serialize(instance);
+                try
+                {
+                    var notificationType = JsonSerializer.Deserialize<VirtualNotification>(instanceString);
+                    if (notificationType != null)
+                    {
+                        var value = _notificationEnumModelType.UserDefinedEnumDictionary[notificationType.NotificationType];
+                        dartString.AppendLine($"\t\t_builders.add({_notificationEnumModelType.Name_Upper}.{value},");
+                        dartString.AppendLine($"\t\t\t\t(map) => {notificationModelType.Name_Upper}.fromJson(map));");
+                        dartString.AppendLine("");
+                    }
+                }
+                catch (Exception ex)
+                {
+                    Console.WriteLine($"Notification Deserialize Error:{ex}");
+                    continue;
+                }
+            }
+            dartString.AppendLine("\t}");
+            dartString.AppendLine("}");
+            dartString.AppendLine("");
+            dartString.AppendLine("class _ModelBuilderCollection {");
+            dartString.AppendLine($"\tfinal Map<{_notificationEnumModelType.Name_Upper}, _ModelBuilder> _source = {{}};");
+            dartString.AppendLine("");
+            dartString.AppendLine($"\tvoid add({_notificationEnumModelType.Name_Upper} type, _ModelBuilder builder) {{");
+            dartString.AppendLine("\t\t_source[type] = builder;");
+            dartString.AppendLine("\t}");
+            dartString.AppendLine("");
+            dartString.AppendLine($"\t_ModelBuilder find({_notificationEnumModelType.Name_Upper} type) {{");
+            dartString.AppendLine("\t\tfinal builder = _source[type];");
+            dartString.AppendLine("\t\treturn builder!;");
+            dartString.AppendLine("\t}");
+            dartString.AppendLine("}");
+            var decodeDartString = new StringBuilder();
+            foreach (var importService in importServiceList)
+            {
+                decodeDartString.AppendLine($"import '{LetterConverterHelper.FirstCharToLower(importService[0..^7])}.m.dart';");
+            }
+            if (importServiceList.Count > 0)
+            {
+                decodeDartString.AppendLine();
+            }
+            decodeDartString.AppendLine(dartString.ToString());
+            return decodeDartString.ToString();
+        }
     }
 }

+ 7 - 0
VirtualNotification.cs

@@ -0,0 +1,7 @@
+namespace FlutterCodeGenerator
+{
+    internal class VirtualNotification
+    {
+        public int NotificationType { get; set; }
+    }
+}