Browse Source

First Commit

Felix 3 years ago
commit
81ce65a14e
13 changed files with 1083 additions and 0 deletions
  1. 26 0
      .vscode/launch.json
  2. 42 0
      .vscode/tasks.json
  3. 134 0
      CodeGenerator.cs
  4. 21 0
      FlutterCodeGenerator.csproj
  5. 33 0
      LetterConverterHelper.cs
  6. 69 0
      MethodMap.cs
  7. 426 0
      ModeType.cs
  8. 77 0
      ModeTypeGenerator.cs
  9. 34 0
      Program.cs
  10. 7 0
      README.md
  11. 141 0
      ServiceMap.cs
  12. BIN
      WingInterfaceLibrary.dll
  13. 73 0
      rpc.txt

+ 26 - 0
.vscode/launch.json

@@ -0,0 +1,26 @@
+{
+    "version": "0.2.0",
+    "configurations": [
+        {
+            // Use IntelliSense to find out which attributes exist for C# debugging
+            // Use hover for the description of the existing attributes
+            // For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md
+            "name": ".NET Core Launch (console)",
+            "type": "coreclr",
+            "request": "launch",
+            "preLaunchTask": "build",
+            // If you have changed target frameworks, make sure to update the program path.
+            "program": "${workspaceFolder}/bin/Debug/net5.0/FlutterCodeGenerator.dll",
+            "args": [],
+            "cwd": "${workspaceFolder}",
+            // For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console
+            "console": "internalConsole",
+            "stopAtEntry": false
+        },
+        {
+            "name": ".NET Core Attach",
+            "type": "coreclr",
+            "request": "attach"
+        }
+    ]
+}

+ 42 - 0
.vscode/tasks.json

@@ -0,0 +1,42 @@
+{
+    "version": "2.0.0",
+    "tasks": [
+        {
+            "label": "build",
+            "command": "dotnet",
+            "type": "process",
+            "args": [
+                "build",
+                "${workspaceFolder}/FlutterCodeGenerator.csproj",
+                "/property:GenerateFullPaths=true",
+                "/consoleloggerparameters:NoSummary"
+            ],
+            "problemMatcher": "$msCompile"
+        },
+        {
+            "label": "publish",
+            "command": "dotnet",
+            "type": "process",
+            "args": [
+                "publish",
+                "${workspaceFolder}/FlutterCodeGenerator.csproj",
+                "/property:GenerateFullPaths=true",
+                "/consoleloggerparameters:NoSummary"
+            ],
+            "problemMatcher": "$msCompile"
+        },
+        {
+            "label": "watch",
+            "command": "dotnet",
+            "type": "process",
+            "args": [
+                "watch",
+                "run",
+                "${workspaceFolder}/FlutterCodeGenerator.csproj",
+                "/property:GenerateFullPaths=true",
+                "/consoleloggerparameters:NoSummary"
+            ],
+            "problemMatcher": "$msCompile"
+        }
+    ]
+}

+ 134 - 0
CodeGenerator.cs

@@ -0,0 +1,134 @@
+using System.Text;
+using System.Collections.Generic;
+using System.Reflection;
+using System.Linq;
+using System;
+using System.IO;
+namespace FlutterCodeGenerator
+{
+    public class CodeGenerator
+    {
+        private readonly string _generatedFolderPath;
+        private readonly string _dllPath;
+
+        private readonly string _rpcTextPath;
+        private readonly string _serviceFolderPath;
+        private const string _dllName = "WingInterfaceLibrary.dll";
+        public static readonly string StringDartCore = "import 'dart:core';";
+        public static readonly string StringClientBase = "import 'package:fisjsonrpc/client_base.dart';";
+        public static readonly string StringJsonConvert = "import 'package:fiscommon/json_convert.dart';";
+        private readonly string _indexDart = "index.dart";
+        private readonly string _rpcDart = "rpc.dart";
+        private Dictionary<string, ServiceMap> _serviceMapDictionary;
+        private List<string> _generatedServiceFileNameList;
+
+        public CodeGenerator(string dllPath, string filePath)
+        {
+
+            _generatedFolderPath = filePath;
+            _dllPath = dllPath;
+            _serviceFolderPath = Path.Combine(_generatedFolderPath, "services");
+            _rpcTextPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "rpc.txt");
+            _serviceMapDictionary = new Dictionary<string, ServiceMap>();
+            _generatedServiceFileNameList = new List<string>() { "platform.dart" };
+            LoadDll();
+        }
+
+        private void LoadDll()
+        {
+            var dll = Directory.GetFiles(_dllPath, _dllName).FirstOrDefault();
+            if (dll == null)
+            {
+                throw new Exception($"The {_dllName} is not found!");
+            }
+            var assemblybytes = File.ReadAllBytes(dll);
+            var assembly = Assembly.Load(assemblybytes);
+            var interfaceTypes = assembly.GetTypes().Where(x => !x.FullName.Contains("WingMongoDBModule") && x.Name.Contains("Service")).ToList();
+            foreach (var interfaceType in interfaceTypes)
+            {
+                var sericeName = interfaceType.Name[1..];
+                var serviceMap = new ServiceMap(interfaceType);
+                _serviceMapDictionary.Add(LetterConverterHelper.FirstCharToLower(sericeName), serviceMap);
+            }
+        }
+
+        private void CheckDirectory()
+        {
+            if (Directory.Exists(_generatedFolderPath))
+            {
+                Directory.Delete(_generatedFolderPath, true);
+            }
+            Directory.CreateDirectory(_generatedFolderPath);
+            Directory.CreateDirectory(_serviceFolderPath);
+        }
+        public void GeneratedCode()
+        {
+
+            CheckDirectory();
+            foreach (var serviceMap in _serviceMapDictionary)
+            {
+                var serviceDartFileName = serviceMap.Key[0..^7] + ".dart";
+                var serviceModelDartFileName = serviceMap.Key[0..^7] + ".m.dart";
+                var serviceDartPath = Path.Combine(_serviceFolderPath, serviceDartFileName);
+                var serviceModelDartPath = Path.Combine(_serviceFolderPath, serviceModelDartFileName);
+                var serviceString = serviceMap.Value.GetServiceDartString();
+                var serviceModelDartString = serviceMap.Value.GetServiceModelDartString();
+                var serviceDartString = new StringBuilder();
+                serviceDartString.AppendLine(StringDartCore);
+                serviceDartString.AppendLine();
+                serviceDartString.AppendLine(StringClientBase);
+                if (serviceString.Contains("FJsonConvert"))
+                {
+                    serviceDartString.AppendLine(StringJsonConvert);
+                }
+                serviceDartString.AppendLine();
+                if (serviceModelDartString != null)
+                {
+                    File.WriteAllText(serviceModelDartPath, serviceModelDartString);
+                    serviceDartString.AppendLine($"import '{serviceModelDartFileName}';");
+                }
+                serviceDartString.AppendLine();
+                serviceDartString.AppendLine(serviceString);
+                File.WriteAllText(serviceDartPath, serviceDartString.ToString());
+                _generatedServiceFileNameList.Add(serviceDartFileName);
+            }
+            GenerateIndexDart();
+            GenerateRpcDart();
+        }
+
+        private void GenerateRpcDart()
+        {
+            var dartString = new StringBuilder();
+            var rpcFilePath = Path.Combine(_generatedFolderPath, _rpcDart);
+            var rpcString = File.ReadAllText(_rpcTextPath);
+            var tempStringArray = rpcString.Split("*******Separator******");
+            if (tempStringArray.Length != 2)
+            {
+                throw new Exception("The rpc text is Wrong!");
+            }
+            dartString.AppendLine(tempStringArray[0]);
+            foreach (var serviceMap in _serviceMapDictionary)
+            {
+                var serviceName = LetterConverterHelper.FirstCharToUpper(serviceMap.Key);
+                var actionName = serviceMap.Key[0..^7];
+                dartString.AppendLine($"\t{serviceName} get {actionName} =>");
+                dartString.AppendLine($"\tfindService(() => new {serviceName}(currentHostAddress));");
+                dartString.AppendLine();
+            }
+            dartString.AppendLine(tempStringArray[1]);
+            File.WriteAllText(rpcFilePath, dartString.ToString());
+        }
+
+        private void GenerateIndexDart()
+        {
+            var dartString = new StringBuilder();
+            var indexFilePath = Path.Combine(_serviceFolderPath, _indexDart);
+
+            foreach (var fileName in _generatedServiceFileNameList.OrderBy(x => x))
+            {
+                dartString.AppendLine($"export '{fileName}';");
+            }
+            File.WriteAllText(indexFilePath, dartString.ToString());
+        }
+    }
+}

+ 21 - 0
FlutterCodeGenerator.csproj

@@ -0,0 +1,21 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <OutputType>Exe</OutputType>
+    <TargetFramework>net5.0</TargetFramework>
+  </PropertyGroup>
+
+	<ItemGroup>
+		<None Update="WingInterfaceLibrary.dll">
+			<CopyToOutputDirectory>Always</CopyToOutputDirectory>
+		</None>
+		<None Update="rpc.txt">
+			<CopyToOutputDirectory>Always</CopyToOutputDirectory>
+		</None>
+	</ItemGroup>
+
+	<ItemGroup>
+	  <PackageReference Include="WingRpcSDK" Version="1.0.0.2" />
+	</ItemGroup>
+
+</Project>

+ 33 - 0
LetterConverterHelper.cs

@@ -0,0 +1,33 @@
+using System.Linq;
+
+namespace FlutterCodeGenerator
+{
+    public class LetterConverterHelper
+    {
+        /// <summary>
+        /// 首字母小写写
+        /// </summary>
+        /// <param name="input"></param>
+        /// <returns></returns>
+        public static string FirstCharToLower(string input)
+        {
+            if (string.IsNullOrEmpty(input))
+                return input;
+            var str = input.First().ToString().ToLower() + input.Substring(1);
+            return str;
+        }
+
+        /// <summary>
+        /// 首字母大写
+        /// </summary>
+        /// <param name="input"></param>
+        /// <returns></returns>
+        public static string FirstCharToUpper(string input)
+        {
+            if (string.IsNullOrEmpty(input))
+                return input;
+            var str = input.First().ToString().ToUpper() + input.Substring(1);
+            return str;
+        }
+    }
+}

+ 69 - 0
MethodMap.cs

@@ -0,0 +1,69 @@
+using System.Data;
+using System.Collections.Generic;
+using System.Reflection;
+using System.Text;
+using System.Linq;
+
+namespace FlutterCodeGenerator
+{
+    internal class MethodMap
+    {
+        public List<ModelType> ParameterModeTypes;
+        public ModelType ReturnParameterModelType { get; set; }
+        private readonly string  _methodName;
+
+        public MethodMap(MethodInfo method)
+        {
+            ParameterModeTypes = new List<ModelType>();
+            _methodName = method.Name;
+            var returnParameterType = method.ReturnType.GetGenericArguments()[0];
+
+            ReturnParameterModelType = ModelTypeGenerator.Create(returnParameterType, "");
+
+            var parameters = method.GetParameters();
+            foreach (var parameter in parameters)
+            {
+                var parameterType = parameter.ParameterType;
+                var parameterModeType = ModelTypeGenerator.Create(parameterType, parameter.Name);
+                ParameterModeTypes.Add(parameterModeType);
+            }
+        }
+
+        public string GetMethodDartString()
+        {
+            var dartString = new StringBuilder();
+            var parameterNames = string.Join(",", ParameterModeTypes.Select(r => r.GetFlutterTypeName() + " " + r.Name_Lower));
+            var argumentNames = string.Join(",", ParameterModeTypes.Select(r => r.Name_Lower));
+            if (ParameterModeTypes.Count > 1)
+            {
+                argumentNames = "[" + argumentNames + "]";
+            }
+            dartString.AppendLine($"\tFuture<{ReturnParameterModelType.GetFlutterTypeName()}> {LetterConverterHelper.FirstCharToLower(_methodName)}({parameterNames}) async {{");
+            dartString.AppendLine($"\t\tvar rpcRst = await call(\"{_methodName}\", {argumentNames});");
+            if (ReturnParameterModelType is SimpleModelType && !(ReturnParameterModelType is IGenericType) && !(ReturnParameterModelType is ArrayModelType))
+            {
+                dartString.AppendLine("\t\treturn rpcRst;");
+            }
+            else if (ReturnParameterModelType is UserDefinedComplexModeType || ReturnParameterModelType is UserDefinedGenericComplexModelType)
+            {
+                dartString.AppendLine($"\t\tvar result = {ReturnParameterModelType.GetFlutterTypeName()}.fromJson(rpcRst as Map<String, dynamic>);");
+                dartString.AppendLine("\t\treturn result;");
+            }
+            else if (ReturnParameterModelType is ListModelType genericModelType)
+            {
+                if (genericModelType.GenericArgumentModelType is SimpleModelType simpleModelType)
+                {
+                    dartString.AppendLine($"\t\tvar result = (rpcRst as List).cast<{simpleModelType.GetFlutterTypeName()}>().toList();");
+                    dartString.AppendLine("\t\treturn result;");
+                }
+                else if (genericModelType.GenericArgumentModelType is UserDefinedComplexModeType userDefinedComplexModeType)
+                {
+                    dartString.AppendLine($"\t\tvar result = (rpcRst as List).map((e)=>{userDefinedComplexModeType.GetFlutterTypeName()}.fromJson(e as Map<String, dynamic>)).toList();");
+                    dartString.AppendLine("\t\treturn result;");
+                }
+            }
+            dartString.AppendLine("\t}");
+            return dartString.ToString();
+        }
+    }
+}

+ 426 - 0
ModeType.cs

@@ -0,0 +1,426 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace FlutterCodeGenerator
+{
+    public interface IGenericType
+    {
+        string GetGenericFlutterName();
+    }
+
+    public class ModelType
+    {
+        public Type ParameterType { get; set; }
+
+        /// <summary>
+        ///Name(First Character Lower Case) 
+        /// </summary>
+        public string Name_Lower { get; set; }
+
+
+        /// <summary>
+        ///Name(First Character Upper Case) 
+        /// </summary>
+        public string Name_Upper { get; set; }
+
+        public ModelType(Type type, string name)
+        {
+            ParameterType = type;
+            Name_Lower = LetterConverterHelper.FirstCharToLower(name);
+            Name_Upper = LetterConverterHelper.FirstCharToUpper(name);
+        }
+
+        public virtual string GetFlutterTypeName()
+        {
+            return ParameterType.Name;
+        }
+    }
+
+    public class SimpleModelType : ModelType
+    {
+        public SimpleModelType(Type type, string name) : base(type, name)
+        {
+        }
+    }
+
+    public class StringModeType : SimpleModelType
+    {
+        public StringModeType(string name) : base(typeof(string), name)
+        {
+        }
+    }
+
+    public class DateTimeModeType : SimpleModelType
+    {
+        public DateTimeModeType(string name) : base(typeof(DateTime), name)
+        {
+        }
+    }
+
+    public class IntModeType : SimpleModelType
+    {
+        public IntModeType(string name) : base(typeof(int), name)
+        {
+        }
+
+        public override string GetFlutterTypeName()
+        {
+            return "int";
+        }
+    }
+
+    public class DoubleModeType : SimpleModelType
+    {
+        public DoubleModeType(string name) : base(typeof(int), name)
+        {
+        }
+
+        public override string GetFlutterTypeName()
+        {
+            return "double";
+        }
+    }
+
+    public class BoolModeType : SimpleModelType
+    {
+        public BoolModeType(string name) : base(typeof(bool), name)
+        {
+        }
+
+        public override string GetFlutterTypeName()
+        {
+            return "bool";
+        }
+    }
+
+    public class ComplexModelType : ModelType
+    {
+        public List<ModelType> Children { get; set; }
+
+        public ComplexModelType(Type type, string name) : base(type, name)
+        {
+            Children = new List<ModelType>();
+        }
+
+        public override string GetFlutterTypeName()
+        {
+            return ParameterType.Name;
+        }
+
+        public virtual string GetDartString()
+        {
+            var dartString = new StringBuilder();
+            return dartString.ToString();
+        }
+    }
+
+    public class EnumModeType : ComplexModelType
+    {
+        public EnumModeType(Type type, string name) : base(type, name)
+        {
+        }
+
+        public override string GetDartString()
+        {
+            var dartString = new StringBuilder();
+            dartString.AppendLine($"enum {GetFlutterTypeName()} {{");
+            foreach (var enumvalue in Enum.GetValues(ParameterType))
+            {
+                dartString.AppendLine($"\t{enumvalue},");
+            }
+            dartString.AppendLine("}");
+            return dartString.ToString();
+        }
+    }
+
+    public class ArrayModelType : SimpleModelType
+    {
+        public ArrayModelType(Type type, string name) : base(type, name)
+        {
+            var arraytypeName = ParameterType.FullName.Replace("[]", string.Empty);
+            var arraytype = ParameterType.Assembly.GetType(arraytypeName);
+            ModelTypeGenerator.Create(arraytype, "");
+        }
+
+        public override string GetFlutterTypeName()
+        {
+            return $"List<{ParameterType.Name[0..^2]}>";
+        }
+    }
+
+    public class ListModelType : SimpleModelType, IGenericType
+    {
+        public ModelType GenericArgumentModelType;
+
+        public ListModelType(Type type, string name) : base(type, name)
+        {
+            var modelType = ModelTypeGenerator.Create(type.GetGenericArguments()[0], "");
+            GenericArgumentModelType = modelType;
+        }
+
+        public override string GetFlutterTypeName()
+        {
+            var flutterTypeName = ParameterType.Name[0..^2] + "<" + GenericArgumentModelType.GetFlutterTypeName() + ">";
+            return flutterTypeName;
+        }
+
+        public string GetGenericFlutterName()
+        {
+            var genericFlutterName = ParameterType.Name[0..^2] + "<T>";
+            return genericFlutterName;
+        }
+    }
+
+    public class DictionaryModelType : SimpleModelType, IGenericType
+    {
+        public List<ModelType> GenericArgumentModelTypeList;
+        public DictionaryModelType(Type type, string name) : base(type, name)
+        {
+            GenericArgumentModelTypeList = new List<ModelType>();
+            foreach (var argumentType in type.GetGenericArguments())
+            {
+                var modelType = ModelTypeGenerator.Create(argumentType, "");
+                GenericArgumentModelTypeList.Add(modelType);
+            }
+        }
+
+        public override string GetFlutterTypeName()
+        {
+            var flutterTypeName = ParameterType.Name[0..^2] + "<" + GenericArgumentModelTypeList[0].GetFlutterTypeName() + "," + GenericArgumentModelTypeList[1].GetFlutterTypeName() + ">";
+            flutterTypeName = flutterTypeName.Replace("Dictionary", "Map");
+            return flutterTypeName;
+        }
+
+        public string GetGenericFlutterName()
+        {
+            var genericFlutterName = ParameterType.Name[0..^2] + "<TKey,TValue>";
+            genericFlutterName = genericFlutterName.Replace("Dictionary", "Map");
+            return genericFlutterName;
+        }
+    }
+
+
+
+    public class UserDefinedGenericComplexModelType : ComplexModelType, IGenericType
+    {
+        public ModelType GenericArgumentModelType;
+
+        public UserDefinedGenericComplexModelType(Type type, string name) : base(type, name)
+        {
+            var properties = type.GetProperties();
+            foreach (var property in properties)
+            {
+                var child = ModelTypeGenerator.Create(property.PropertyType, property.Name);
+                Children.Add(child);
+            }
+            var modelType = ModelTypeGenerator.Create(type.GetGenericArguments()[0], "");
+            GenericArgumentModelType = modelType;
+        }
+
+        public override string GetFlutterTypeName()
+        {
+            var flutterTypeName = ParameterType.Name[0..^2] + "<" + GenericArgumentModelType.GetFlutterTypeName() + ">";
+            return flutterTypeName;
+        }
+
+        public string GetGenericFlutterName()
+        {
+            var flutterTypeName = ParameterType.Name[0..^2] + "<T>";
+            return flutterTypeName;
+        }
+
+        public override string GetDartString()
+        {
+            var dartString = new StringBuilder();
+            dartString.AppendLine($"class {GetGenericFlutterName()} {{");
+            foreach (var child in Children)
+            {
+                var genericType = child as IGenericType;
+                if (genericType != null)
+                {
+                    dartString.AppendLine($"\tfinal {genericType.GetGenericFlutterName()} {child.Name_Lower};");
+                }
+                else
+                {
+                    dartString.AppendLine($"\tfinal {child.GetFlutterTypeName()} {child.Name_Lower};");
+                }
+            }
+            dartString.AppendLine();
+            dartString.AppendLine($"\t{ParameterType.Name[0..^2]}({{");
+            foreach (var child in Children)
+            {
+                dartString.AppendLine($"\t\trequired this.{child.Name_Lower},");
+            }
+            dartString.AppendLine("\t});");
+            dartString.AppendLine();
+            dartString.AppendLine($"\tfactory {ParameterType.Name[0..^2]}.fromJson(Map<String, dynamic> map) {{");
+            foreach (var child in Children)
+            {
+                if (child is ArrayModelType)
+                {
+                    dartString.AppendLine($"\t\tfinal {child.Name_Lower}Data = map['{child.Name_Upper}'];");
+                }
+                var genericType = child as IGenericType;
+                if (genericType != null)
+                {
+                    if (child.ParameterType.GetGenericArguments().Length == 1)
+                    {
+                        dartString.AppendLine($"\t\t{genericType.GetGenericFlutterName()} {child.Name_Lower}List = [];");
+                        dartString.AppendLine($"\t\tif (map['{child.Name_Upper}'] != null) {{");
+                        dartString.AppendLine($"\t\t\t{child.Name_Lower}List.addAll((map['{child.Name_Upper}'] as List).map((e) => FJsonConvert.fromJson<T>(e)!));");
+                        dartString.AppendLine("\t\t}");
+                    }
+                    else if (child.ParameterType.GetGenericArguments().Length == 2)
+                    {
+                        dartString.AppendLine($"\t\t{genericType.GetGenericFlutterName()} {child.Name_Lower}Map = {{}};");
+                        dartString.AppendLine($"\t\tif (map['{child.Name_Upper}'] != null) {{");
+                        dartString.AppendLine($"\t\t\t{child.Name_Lower}Map.addAll(map['{child.Name_Upper}'].map((e) => FJsonConvert.fromJson<T>(e)!));");
+                        dartString.AppendLine("\t\t}");
+                    }
+                }
+            }
+            dartString.AppendLine($"\t\treturn {ParameterType.Name[0..^2]}( ");
+            foreach (var child in Children)
+            {
+                if (child is EnumModeType)
+                {
+                    dartString.AppendLine($"\t\t\t{child.Name_Lower}: {child.GetFlutterTypeName()}.values.firstWhere((e) => e.index == map['{child.Name_Upper}']),");
+                }
+                else if (child is ArrayModelType)
+                {
+                    dartString.AppendLine($"\t\t\t{child.Name_Lower}: {child.Name_Lower}Data != null ? ({child.Name_Lower}Data as List).map((e) => {child.Name_Lower.Replace("[]", string.Empty)}.fromJson(e)).toList(): const [],");
+                }
+                else if (child is IGenericType)
+                {
+                    var genericType = child as IGenericType;
+                    if (child.ParameterType.GetGenericArguments().Length == 1)
+                    {
+                        dartString.AppendLine($"\t\t\t{child.Name_Lower}: {child.Name_Lower}List,");
+                    }
+                    else if (child.ParameterType.GetGenericArguments().Length == 2)
+                    {
+                        dartString.AppendLine($"\t\t\t{child.Name_Lower}: {child.Name_Lower}Map,");
+                    }
+                }
+                else
+                {
+                    dartString.AppendLine($"\t\t\t{child.Name_Lower}: map['{child.Name_Upper}'],");
+                }
+            }
+            dartString.AppendLine("\t\t);");
+            dartString.AppendLine("\t}");
+            dartString.AppendLine();
+            dartString.AppendLine("\tMap<String, dynamic> toJson() {");
+            dartString.AppendLine("\t\tfinal map = Map<String, dynamic>();");
+            foreach (var child in Children)
+            {
+                if (child is EnumModeType)
+                {
+                    dartString.AppendLine($"\t\tmap['{child.Name_Upper}'] = {child.Name_Lower}.index;");
+                }
+                else if (child is ArrayModelType)
+                {
+                    dartString.AppendLine($"\t\tmap['{child.Name_Upper}'] = {child.Name_Lower}.map((e) => e.toJson()).toList();");
+                }
+                else if (child is IGenericType)
+                {
+                    dartString.AppendLine($"\t\tmap['{child.Name_Upper}'] = {child.Name_Lower}.map((dynamic e) => e.toJson()).toList();");
+                }
+                else
+                {
+                    dartString.AppendLine($"\t\tmap['{child.Name_Upper}'] = {child.Name_Lower};");
+                }
+            }
+            dartString.AppendLine("\t\treturn map;");
+            dartString.AppendLine("\t}");
+            dartString.AppendLine("}");
+            return dartString.ToString();
+        }
+    }
+
+    public class UserDefinedComplexModeType : ComplexModelType
+    {
+        public UserDefinedComplexModeType(Type type, string name) : base(type, name)
+        {
+            var properties = type.GetProperties();
+            foreach (var property in properties)
+            {
+                var child = ModelTypeGenerator.Create(property.PropertyType, property.Name);
+                Children.Add(child);
+            }
+        }
+
+        public override string GetFlutterTypeName()
+        {
+            return $"{ParameterType.Name}";
+        }
+
+        public override string GetDartString()
+        {
+            var dartString = new StringBuilder();
+            var flutterTypeName = GetFlutterTypeName();
+            dartString.AppendLine($"class {flutterTypeName} {{");
+            foreach (var child in Children)
+            {
+                dartString.AppendLine($"\tfinal {child.GetFlutterTypeName()} {child.Name_Lower};");
+            }
+            dartString.AppendLine();
+            dartString.AppendLine($"\t{flutterTypeName}({{");
+            foreach (var child in Children)
+            {
+                dartString.AppendLine($"\t\trequired this.{child.Name_Lower},");
+            }
+            dartString.AppendLine("\t});");
+            dartString.AppendLine();
+            dartString.AppendLine($"\tfactory {flutterTypeName}.fromJson(Map<String, dynamic> map) {{");
+            foreach (var child in Children)
+            {
+                if (child is ArrayModelType)
+                {
+                    dartString.AppendLine($"\t\tfinal {child.Name_Lower}Data = map['{child.Name_Upper}'];");
+                }
+            }
+            dartString.AppendLine($"\t\treturn {flutterTypeName}( ");
+            foreach (var child in Children)
+            {
+                if (child is EnumModeType)
+                {
+                    dartString.AppendLine($"\t\t\t{child.Name_Lower}: {child.GetFlutterTypeName()}.values.firstWhere((e) => e.index == map['{child.Name_Upper}']),");
+                }
+                else if (child is ArrayModelType)
+                {
+                    dartString.AppendLine($"\t\t\t{child.Name_Lower}: {child.Name_Lower}Data != null ? ({child.Name_Lower}Data as List).map((e) => {child.ParameterType.Name.Replace("[]", string.Empty)}.fromJson(e)).toList(): const [],");
+                }
+                else
+                {
+                    dartString.AppendLine($"\t\t\t{child.Name_Lower}: map['{child.Name_Upper}'],");
+                }
+            }
+            dartString.AppendLine("\t\t);");
+            dartString.AppendLine("\t}");
+            dartString.AppendLine();
+            dartString.AppendLine("\tMap<String, dynamic> toJson() {");
+            dartString.AppendLine("\t\tfinal map = Map<String, dynamic>();");
+            foreach (var child in Children)
+            {
+                if (child is EnumModeType)
+                {
+                    dartString.AppendLine($"\t\tmap['{child.Name_Upper}'] = {child.Name_Lower}.index;");
+                }
+                else if (child is ArrayModelType)
+                {
+                    dartString.AppendLine($"\t\tmap['{child.Name_Upper}'] = {child.Name_Lower}.map((e) => e.toJson()).toList();");
+                }
+                else
+                {
+                    dartString.AppendLine($"\t\tmap['{child.Name_Upper}'] = {child.Name_Lower};");
+                }
+            }
+            dartString.AppendLine("\t\treturn map;");
+            dartString.AppendLine("\t}");
+            dartString.AppendLine("}");
+            return dartString.ToString();
+        }
+    }
+}

+ 77 - 0
ModeTypeGenerator.cs

@@ -0,0 +1,77 @@
+using System;
+using System.Linq;
+
+namespace FlutterCodeGenerator
+{
+    public class ModelTypeGenerator
+    {
+        public static ModelType Create(Type type, string argName)
+        {
+            if (type == typeof(int) || type == typeof(long) || type == typeof(short))
+            {
+                return new IntModeType(argName);
+            }
+            else if (type == typeof(float) || type == typeof(double))
+            {
+                return new DoubleModeType(argName);
+            }
+            else if (type == typeof(bool))
+            {
+                return new BoolModeType(argName);
+            }
+            else if (type == typeof(string) || type == typeof(char))
+            {
+                return new StringModeType(argName);
+            }
+            else if (type == typeof(DateTime))
+            {
+                return new DateTimeModeType(argName);
+            }
+            else if (type.IsEnum)
+            {
+                var modelType = new EnumModeType(type, argName);
+                if (!ServiceMap.TemporaryList.Any(x => x.ParameterType == type))
+                {
+                    ServiceMap.TemporaryList.Add(modelType);
+                }
+                return modelType;
+            }
+            else if (type.IsArray)
+            {
+                var modelType = new ArrayModelType(type, argName);
+                return modelType;
+            }
+            else if (type.IsGenericType)
+            {
+                if (type.Name == "List`1")
+                {
+                    var modelType = new ListModelType(type, argName);
+                    return modelType;
+                }
+                else if (type.Name == "Dictionary`2")
+                {
+                    var modelType = new DictionaryModelType(type, argName);
+                    return modelType;
+                }
+                else
+                {
+                    var modelType = new UserDefinedGenericComplexModelType(type, argName);
+                    if (!ServiceMap.TemporaryList.Any(x => x.ParameterType == type))
+                    {
+                        ServiceMap.TemporaryList.Add(modelType);
+                    }
+                    return modelType;
+                }
+            }
+            else
+            {
+                var modelType = new UserDefinedComplexModeType(type, argName);
+                if (!ServiceMap.TemporaryList.Any(x => x.ParameterType == type))
+                {
+                    ServiceMap.TemporaryList.Add(modelType);
+                }
+                return modelType;
+            }
+        }
+    }
+}

+ 34 - 0
Program.cs

@@ -0,0 +1,34 @@
+using System.IO;
+using System;
+
+namespace FlutterCodeGenerator
+{
+    class Program
+    {
+        static void Main(string[] args)
+        {
+            try
+            {
+                var generatedFolderPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "GeneratedCode");
+                var dllPath = AppDomain.CurrentDomain.BaseDirectory;
+                if (args.Length == 2)
+                {
+                    dllPath = args[0];
+                    generatedFolderPath = args[1];
+                }
+                if (string.IsNullOrWhiteSpace(dllPath) || string.IsNullOrWhiteSpace(generatedFolderPath))
+                {
+                    throw new ArgumentException("The argments are invalid!");
+                }
+                var codeGenerator = new CodeGenerator(dllPath, generatedFolderPath);
+                codeGenerator.GeneratedCode();
+                Console.WriteLine($"The code has already generated! The path is {generatedFolderPath}");
+            }
+            catch (Exception ex)
+            {
+                Console.WriteLine($"An Error occured when generated!!! Error Message : {ex.Message}");
+
+            }
+        }
+    }
+}

+ 7 - 0
README.md

@@ -0,0 +1,7 @@
+# FlutterCodeGenerator
+
+Flutter代码生成器
+
+可输入参数:
+
+string[] args:dll路径,生成路径。

+ 141 - 0
ServiceMap.cs

@@ -0,0 +1,141 @@
+using System.Linq;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace FlutterCodeGenerator
+{
+    internal class ServiceMap
+    {
+        public List<MethodMap> MethodMapList;
+
+        public static List<ComplexModelType> TemporaryList { get; set; }
+        private List<ComplexModelType> _usedComplexModelTypeList;
+        private List<string> _userDefinedComplexReturnTypeList;
+        private string _serviceName;
+
+        public ServiceMap(Type type)
+        {
+            _usedComplexModelTypeList = new List<ComplexModelType>();
+            TemporaryList = new List<ComplexModelType>();
+            MethodMapList = new List<MethodMap>();
+            var methodsList = type.GetMethods();
+            _serviceName = type.Name[1..];
+
+            foreach (var method in methodsList)
+            {
+                var methodMap = new MethodMap(method);
+                MethodMapList.Add(methodMap);
+            }
+            _usedComplexModelTypeList.AddRange(TemporaryList);
+        }
+
+        public string GetServiceModelDartString()
+        {
+            var dartString = new StringBuilder();
+            foreach (var modelType in _usedComplexModelTypeList)
+            {
+                dartString.AppendLine(modelType.GetDartString());
+            }
+            if (string.IsNullOrWhiteSpace(dartString.ToString()))
+            {
+                return null;
+            }
+            var serviceModelDartString = new StringBuilder();
+            if (dartString.ToString().Contains("FJsonConvert"))
+            {
+                serviceModelDartString.AppendLine(CodeGenerator.StringJsonConvert);
+                serviceModelDartString.AppendLine();
+            }
+            serviceModelDartString.AppendLine(dartString.ToString());
+            return serviceModelDartString.ToString();
+        }
+
+        public string GetServiceDartString()
+        {
+            var serviceDartString = new StringBuilder();
+            serviceDartString.AppendLine($"class {_serviceName} extends JsonRpcClientBase {{");
+            serviceDartString.AppendLine($"\t{_serviceName}(");
+            serviceDartString.AppendLine("\t\tString host, {");
+            serviceDartString.AppendLine($"\t\tString serviceName = \"I{_serviceName}\",");
+            serviceDartString.AppendLine("\t\tMap<String, String>? headers,");
+            serviceDartString.AppendLine("\t\tint? timeout,");
+            serviceDartString.AppendLine("\t}) : super(");
+            serviceDartString.AppendLine("\t\t\t\t\t\thost,");
+            serviceDartString.AppendLine("\t\t\t\t\t\tserviceName,");
+            serviceDartString.AppendLine("\t\t\t\t\t\theaders: headers,");
+            serviceDartString.AppendLine("\t\t\t\t\t\ttimeout: timeout,");
+
+            var complexReturnTypeNameList = GetUserDefinedComplexReturnTypeList();
+            if (complexReturnTypeNameList.Count() == 0)
+            {
+                serviceDartString.AppendLine("\t\t\t\t);");
+            }
+            else
+            {
+                serviceDartString.AppendLine("\t\t\t\t) {");
+                serviceDartString.AppendLine("\t\t/// 注册响应实体反序列化处理器");
+                foreach (var complexRetrunTypeName in complexReturnTypeNameList)
+                {
+                    serviceDartString.AppendLine($"\t\tFJsonConvert.setDecoder((map) => {complexRetrunTypeName}.fromJson(map));");
+                }
+                serviceDartString.AppendLine("\t}");
+            }
+            serviceDartString.AppendLine();
+            foreach (var methodMap in MethodMapList)
+            {
+                serviceDartString.AppendLine(methodMap.GetMethodDartString());
+            }
+
+            serviceDartString.AppendLine("}");
+
+            return serviceDartString.ToString();
+        }
+
+        public List<string> GetUserDefinedComplexReturnTypeList()
+        {
+            _userDefinedComplexReturnTypeList = new List<string>();
+            foreach (var method in MethodMapList)
+            {
+                var veturnParameterModelType = method.ReturnParameterModelType;
+                AddUserDefinedComplexReturnType(veturnParameterModelType);
+
+            }
+            return _userDefinedComplexReturnTypeList;
+        }
+
+
+
+        private void AddUserDefinedComplexReturnType(ModelType modelType)
+        {
+            if (modelType is UserDefinedComplexModeType)
+            {
+                if (!_userDefinedComplexReturnTypeList.Contains(modelType.GetFlutterTypeName()))
+                {
+                    _userDefinedComplexReturnTypeList.Add(modelType.GetFlutterTypeName());
+                }
+            }
+            else if (modelType is UserDefinedGenericComplexModelType userDefinedGenericComplexModelType)
+            {
+                if (!_userDefinedComplexReturnTypeList.Contains(userDefinedGenericComplexModelType.GetFlutterTypeName()))
+                {
+                    _userDefinedComplexReturnTypeList.Add(userDefinedGenericComplexModelType.GetFlutterTypeName());
+                }
+                var argumentModelType = userDefinedGenericComplexModelType.GenericArgumentModelType;
+                AddUserDefinedComplexReturnType(argumentModelType);
+            }
+            else if (modelType is ListModelType listModelType)
+            {
+                var argumentModelType = listModelType.GenericArgumentModelType;
+                AddUserDefinedComplexReturnType(argumentModelType);
+            }
+            else if (modelType is DictionaryModelType dictionaryModelType)
+            {
+                foreach (var argumentModelType in dictionaryModelType.GenericArgumentModelTypeList)
+                {
+                    AddUserDefinedComplexReturnType(argumentModelType);
+                }
+            }
+        }
+    }
+}

BIN
WingInterfaceLibrary.dll


+ 73 - 0
rpc.txt

@@ -0,0 +1,73 @@
+library fisjsonrpc;
+
+import 'dart:collection';
+
+import 'package:fiscommon/extensions/type.dart';
+
+import 'client_base.dart';
+import 'services/index.dart';
+
+export 'services/index.dart';
+
+typedef T ServiceBuilder<T extends JsonRpcClientBase>();
+
+/// 默认地址标识
+const String _defaultAddressSign = "FLYINSONO";
+
+/// JSON-RPC 代理
+class JsonRpcProxy {
+  JsonRpcProxy({
+    this.defaultServerHost = "cloud.fis.plus",
+    this.platformHost = "platform.fis.plus",
+  }) {
+    _currentHost = this.defaultServerHost;
+  }
+
+  /// 默认主机地址
+  final String defaultServerHost;
+
+  /// 宿主平台代理地址
+  final String platformHost;
+
+  late String _currentHost;
+
+  /// 当前服务主机地址
+  String get currentHostAddress => "http://$_currentHost";
+
+  String get defaultAddressSign => _defaultAddressSign;
+
+  HashMap<Type, dynamic> _serviceCache = HashMap();
+
+  static PlatformService? _platformService;
+
+  /* 服务代理设置 Start */
+
+  /// 平台服务
+  PlatformService get platform {
+    if (_platformService == null)
+      _platformService = PlatformService(platformHost);
+    return _platformService!;
+  }
+*******Separator******
+    /* 服务代理设置 End */
+
+  /// 设置服务主机地址
+  void setServerHost(String address) {
+    if (address == _defaultAddressSign) {
+      address = defaultServerHost;
+    }
+    _currentHost = address;
+  }
+
+  /// 清空缓存
+  void clearCache() => _serviceCache.clear();
+
+  /// 查找Service实例
+  T findService<T extends JsonRpcClientBase>(ServiceBuilder<T> builder) {
+    Type serviceType = typeOf<T>();
+    if (!_serviceCache.containsKey(serviceType)) {
+      _serviceCache[serviceType] = builder.call();
+    }
+    return _serviceCache[serviceType] as T;
+  }
+}