From c45f382cf361d60185a8dad1624c417048138b4b Mon Sep 17 00:00:00 2001 From: baozhangchi Date: Wed, 20 Mar 2024 17:38:42 +0800 Subject: [PATCH 1/3] Add GetRestFulControllerName Support --- Plus.AutoApi/AutoApiConvention.cs | 144 ++++++++--------------- Plus.AutoApi/AutoApiOptions.cs | 2 + Plus.AutoApi/AutoApiServiceExtensions.cs | 1 + Plus.AutoApi/PlusConsts.cs | 2 + 4 files changed, 52 insertions(+), 97 deletions(-) diff --git a/Plus.AutoApi/AutoApiConvention.cs b/Plus.AutoApi/AutoApiConvention.cs index 0ec9170..9e8ec30 100644 --- a/Plus.AutoApi/AutoApiConvention.cs +++ b/Plus.AutoApi/AutoApiConvention.cs @@ -1,13 +1,13 @@ -using Microsoft.AspNetCore.Mvc; +using System; +using System.Linq; +using System.Reflection; +using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.ActionConstraints; using Microsoft.AspNetCore.Mvc.ApplicationModels; using Microsoft.AspNetCore.Mvc.ModelBinding; using Plus.AutoApi.Attributes; using Plus.AutoApi.Extensions; using Plus.AutoApi.Helpers; -using System; -using System.Linq; -using System.Reflection; namespace Plus.AutoApi { @@ -22,7 +22,7 @@ public void Apply(ApplicationModel application) if (typeof(IAutoApi).GetTypeInfo().IsAssignableFrom(type)) { - controller.ControllerName = controller.ControllerName.RemoveSuffix(PlusConsts.ControllerSuffixes.ToArray()); + controller.ControllerName = GetRestFulControllerName(controller.ControllerName); ConfigureArea(controller, attribute); @@ -48,13 +48,9 @@ private void ConfigureArea(ControllerModel controller, AutoApiAttribute attribut if (!controller.RouteValues.ContainsKey("area")) { if (!string.IsNullOrEmpty(attribute.AreaName)) - { controller.RouteValues["area"] = attribute.AreaName; - } else if (!string.IsNullOrEmpty(PlusConsts.DefaultAreaName)) - { controller.RouteValues["area"] = PlusConsts.DefaultAreaName; - } } } @@ -68,59 +64,35 @@ private void ConfigureAutoApi(ControllerModel controller, AutoApiAttribute attri private void ConfigureApiExplorer(ControllerModel controller) { if (string.IsNullOrEmpty(controller.ApiExplorer.GroupName)) - { controller.ApiExplorer.GroupName = controller.ControllerName; - } - if (controller.ApiExplorer.IsVisible == null) - { - controller.ApiExplorer.IsVisible = true; - } + if (controller.ApiExplorer.IsVisible == null) controller.ApiExplorer.IsVisible = true; - foreach (var action in controller.Actions) - { - ConfigureApiExplorer(action); - } + foreach (var action in controller.Actions) ConfigureApiExplorer(action); } private void ConfigureApiExplorer(ActionModel action) { - if (action.ApiExplorer.IsVisible == null) - { - action.ApiExplorer.IsVisible = true; - } + if (action.ApiExplorer.IsVisible == null) action.ApiExplorer.IsVisible = true; } private void ConfigureSelector(ControllerModel controller, AutoApiAttribute attribute) { - if (controller.Selectors.Any(selector => selector.AttributeRouteModel != null)) - { - return; - } + if (controller.Selectors.Any(selector => selector.AttributeRouteModel != null)) return; var areaName = string.Empty; - if (attribute != null) - { - areaName = attribute.AreaName; - } + if (attribute != null) areaName = attribute.AreaName; - foreach (var action in controller.Actions) - { - ConfigureSelector(areaName, controller.ControllerName, action); - } + foreach (var action in controller.Actions) ConfigureSelector(areaName, controller.ControllerName, action); } private void ConfigureSelector(string areaName, string controllerName, ActionModel action) { if (!action.Selectors.Any() || action.Selectors.Any(x => !x.ActionConstraints.Any())) - { AddApplicationServiceSelector(areaName, controllerName, action); - } else - { NormalizeSelectorRoutes(areaName, controllerName, action); - } } private void AddApplicationServiceSelector(string areaName, string controllerName, ActionModel action) @@ -132,9 +104,7 @@ private void AddApplicationServiceSelector(string areaName, string controllerNam var appServiceSelectorModel = action.Selectors[0]; if (appServiceSelectorModel.AttributeRouteModel == null) - { appServiceSelectorModel.AttributeRouteModel = CreateActionRouteModel(areaName, controllerName, action); - } if (!appServiceSelectorModel.ActionConstraints.Any()) { @@ -164,53 +134,52 @@ private void NormalizeSelectorRoutes(string areaName, string controllerName, Act action.ActionName = GetRestFulActionName(action.ActionName); foreach (var selector in action.Selectors) - { - selector.AttributeRouteModel = selector.AttributeRouteModel == null ? - CreateActionRouteModel(areaName, controllerName, action) : - AttributeRouteModel.CombineAttributeRouteModel(CreateActionRouteModel(areaName, controllerName, action), selector.AttributeRouteModel); - } + selector.AttributeRouteModel = selector.AttributeRouteModel == null + ? CreateActionRouteModel(areaName, controllerName, action) + : AttributeRouteModel.CombineAttributeRouteModel( + CreateActionRouteModel(areaName, controllerName, action), selector.AttributeRouteModel); } private static string GetHttpVerb(ActionModel action) { - var getValueSuccess = PlusConsts.AssemblyAutoApiOptions.TryGetValue(action.Controller.ControllerType.Assembly, out AssemblyAutoApiOptions assemblyAutoApiOptions); + var getValueSuccess = + PlusConsts.AssemblyAutoApiOptions.TryGetValue(action.Controller.ControllerType.Assembly, + out var assemblyAutoApiOptions); if (getValueSuccess && !string.IsNullOrWhiteSpace(assemblyAutoApiOptions?.HttpVerb)) - { return assemblyAutoApiOptions.HttpVerb; - } var verbKey = action.ActionName.GetPascalOrCamelCaseFirstWord().ToLower(); - return PlusConsts.HttpVerbs.ContainsKey(verbKey) ? PlusConsts.HttpVerbs[verbKey] : PlusConsts.DefaultHttpVerb; + return PlusConsts.HttpVerbs.ContainsKey(verbKey) + ? PlusConsts.HttpVerbs[verbKey] + : PlusConsts.DefaultHttpVerb; } - private string GetRestFulActionName(string actionName) + private string GetRestFulControllerName(string controllerName) { - var name = PlusConsts.GetRestFulActionName?.Invoke(actionName); - if (name != null) - { - return name; - } + controllerName = controllerName.RemoveSuffix(PlusConsts.ControllerSuffixes.ToArray()); + var name = PlusConsts.GetRestFulControllerName?.Invoke(controllerName); + if (!string.IsNullOrWhiteSpace(name)) return name; + return controllerName; + } + + private string GetRestFulActionName(string actionName) + { actionName = actionName.RemoveSuffix(PlusConsts.ActionSuffixes.ToArray()); + var name = PlusConsts.GetRestFulActionName?.Invoke(actionName); + if (name != null) return name; var verbKey = actionName.GetPascalOrCamelCaseFirstWord().ToLower(); if (PlusConsts.HttpVerbs.ContainsKey(verbKey)) { if (actionName.Length == verbKey.Length) - { return ""; - } - else - { - return actionName.Substring(verbKey.Length); - } - } - else - { - return actionName; + return actionName.Substring(verbKey.Length); } + + return actionName; } private AttributeRouteModel CreateActionRouteModel(string areaName, string controllerName, ActionModel action) @@ -223,12 +192,12 @@ private AttributeRouteModel CreateActionRouteModel(string areaName, string contr private static string GetApiPreFix(ActionModel action) { - var getValueSuccess = PlusConsts.AssemblyAutoApiOptions.TryGetValue(action.Controller.ControllerType.Assembly, out AssemblyAutoApiOptions assemblyAutoApiOptions); + var getValueSuccess = + PlusConsts.AssemblyAutoApiOptions.TryGetValue(action.Controller.ControllerType.Assembly, + out var assemblyAutoApiOptions); if (getValueSuccess && !string.IsNullOrWhiteSpace(assemblyAutoApiOptions?.ApiPrefix)) - { return assemblyAutoApiOptions.ApiPrefix; - } return PlusConsts.DefaultApiPreFix; } @@ -236,50 +205,31 @@ private static string GetApiPreFix(ActionModel action) private void ConfigureParameters(ControllerModel controller) { foreach (var action in controller.Actions) + foreach (var para in action.Parameters) { - foreach (var para in action.Parameters) - { - if (para.BindingInfo != null) - { - continue; - } + if (para.BindingInfo != null) continue; - if (!TypeHelper.IsPrimitiveExtendedIncludingNullable(para.ParameterInfo.ParameterType)) - { - if (CanUseFormBodyBinding(action, para)) - { - para.BindingInfo = BindingInfo.GetBindingInfo(new[] { new FromBodyAttribute() }); - } - } - } + if (!TypeHelper.IsPrimitiveExtendedIncludingNullable(para.ParameterInfo.ParameterType)) + if (CanUseFormBodyBinding(action, para)) + para.BindingInfo = BindingInfo.GetBindingInfo(new[] { new FromBodyAttribute() }); } } private bool CanUseFormBodyBinding(ActionModel action, ParameterModel parameter) { - if (PlusConsts.FormBodyBindingIgnoredTypes.Any(t => t.IsAssignableFrom(parameter.ParameterInfo.ParameterType))) - { - return false; - } + if (PlusConsts.FormBodyBindingIgnoredTypes.Any(t => + t.IsAssignableFrom(parameter.ParameterInfo.ParameterType))) return false; foreach (var selector in action.Selectors) { - if (selector.ActionConstraints == null) - { - continue; - } + if (selector.ActionConstraints == null) continue; foreach (var actionConstraint in selector.ActionConstraints) { - if (!(actionConstraint is HttpMethodActionConstraint httpMethodActionConstraint)) - { - continue; - } + if (!(actionConstraint is HttpMethodActionConstraint httpMethodActionConstraint)) continue; if (httpMethodActionConstraint.HttpMethods.All(x => x.IsIn("GET", "DELETE", "TRACE", "HEAD"))) - { return false; - } } } diff --git a/Plus.AutoApi/AutoApiOptions.cs b/Plus.AutoApi/AutoApiOptions.cs index 4fca760..f266497 100644 --- a/Plus.AutoApi/AutoApiOptions.cs +++ b/Plus.AutoApi/AutoApiOptions.cs @@ -31,6 +31,8 @@ public AutoApiOptions() public Func GetRestFulActionName { get; set; } + public Func GetRestFulControllerName { get; set; } + public Dictionary AssemblyAutoApiOptions { get; } public void Valid() diff --git a/Plus.AutoApi/AutoApiServiceExtensions.cs b/Plus.AutoApi/AutoApiServiceExtensions.cs index bf14dbe..ac2fe5c 100644 --- a/Plus.AutoApi/AutoApiServiceExtensions.cs +++ b/Plus.AutoApi/AutoApiServiceExtensions.cs @@ -38,6 +38,7 @@ private static IServiceCollection AddAutoApi(this IServiceCollection services, A PlusConsts.ActionSuffixes = options.RemoveActionSuffixes; PlusConsts.FormBodyBindingIgnoredTypes = options.FormBodyBindingIgnoredTypes; PlusConsts.GetRestFulActionName = options.GetRestFulActionName; + PlusConsts.GetRestFulControllerName = options.GetRestFulControllerName; PlusConsts.AssemblyAutoApiOptions = options.AssemblyAutoApiOptions; var partManager = services.GetSingletonInstanceOrNull(); diff --git a/Plus.AutoApi/PlusConsts.cs b/Plus.AutoApi/PlusConsts.cs index 0b72984..908e23a 100644 --- a/Plus.AutoApi/PlusConsts.cs +++ b/Plus.AutoApi/PlusConsts.cs @@ -44,6 +44,8 @@ static PlusConsts() public static Func GetRestFulActionName { get; set; } + public static Func GetRestFulControllerName { get; set; } + public static Dictionary AssemblyAutoApiOptions { get; set; } } } \ No newline at end of file From 8487e85327717887f981795040a548cc33da9001 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8C=85=E5=BC=A0=E9=A9=B0?= Date: Mon, 25 Mar 2024 14:38:39 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E6=B7=BB=E5=8A=A0AutoApiAttribute.Inherite?= =?UTF-8?q?d?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Plus.AutoApi/Attributes/AutoApiAttribute.cs | 2 + Plus.AutoApi/AutoApiConvention.cs | 98 +++++++++++++++++---- 2 files changed, 85 insertions(+), 15 deletions(-) diff --git a/Plus.AutoApi/Attributes/AutoApiAttribute.cs b/Plus.AutoApi/Attributes/AutoApiAttribute.cs index 6be609f..8f75718 100644 --- a/Plus.AutoApi/Attributes/AutoApiAttribute.cs +++ b/Plus.AutoApi/Attributes/AutoApiAttribute.cs @@ -9,5 +9,7 @@ public class AutoApiAttribute : Attribute public string AreaName { get; set; } public bool Disabled { get; set; } = false; + + public bool Inherited { get; set; } = true; } } \ No newline at end of file diff --git a/Plus.AutoApi/AutoApiConvention.cs b/Plus.AutoApi/AutoApiConvention.cs index 9e8ec30..8684202 100644 --- a/Plus.AutoApi/AutoApiConvention.cs +++ b/Plus.AutoApi/AutoApiConvention.cs @@ -43,56 +43,89 @@ public void Apply(ApplicationModel application) private void ConfigureArea(ControllerModel controller, AutoApiAttribute attribute) { if (attribute == null) + { throw new ArgumentException(nameof(attribute)); + } if (!controller.RouteValues.ContainsKey("area")) { if (!string.IsNullOrEmpty(attribute.AreaName)) + { controller.RouteValues["area"] = attribute.AreaName; + } else if (!string.IsNullOrEmpty(PlusConsts.DefaultAreaName)) + { controller.RouteValues["area"] = PlusConsts.DefaultAreaName; + } } } private void ConfigureAutoApi(ControllerModel controller, AutoApiAttribute attribute) { - ConfigureApiExplorer(controller); + ConfigureApiExplorer(controller, attribute); ConfigureSelector(controller, attribute); ConfigureParameters(controller); } - private void ConfigureApiExplorer(ControllerModel controller) + private void ConfigureApiExplorer(ControllerModel controller, AutoApiAttribute attribute) { if (string.IsNullOrEmpty(controller.ApiExplorer.GroupName)) + { controller.ApiExplorer.GroupName = controller.ControllerName; + } - if (controller.ApiExplorer.IsVisible == null) controller.ApiExplorer.IsVisible = true; + controller.ApiExplorer.IsVisible ??= true; - foreach (var action in controller.Actions) ConfigureApiExplorer(action); + foreach (var action in controller.Actions) + { + ConfigureApiExplorer(action, attribute); + } } - private void ConfigureApiExplorer(ActionModel action) + private void ConfigureApiExplorer(ActionModel action, AutoApiAttribute attribute) { - if (action.ApiExplorer.IsVisible == null) action.ApiExplorer.IsVisible = true; + if (!attribute.Inherited) + { + if (action.ActionMethod.DeclaringType != action.Controller.ControllerType) + { + action.ApiExplorer.IsVisible = false; + return; + } + } + + action.ApiExplorer.IsVisible ??= true; } private void ConfigureSelector(ControllerModel controller, AutoApiAttribute attribute) { - if (controller.Selectors.Any(selector => selector.AttributeRouteModel != null)) return; + if (controller.Selectors.Any(selector => selector.AttributeRouteModel != null)) + { + return; + } var areaName = string.Empty; - if (attribute != null) areaName = attribute.AreaName; + if (attribute != null) + { + areaName = attribute.AreaName; + } - foreach (var action in controller.Actions) ConfigureSelector(areaName, controller.ControllerName, action); + foreach (var action in controller.Actions) + { + ConfigureSelector(areaName, controller.ControllerName, action); + } } private void ConfigureSelector(string areaName, string controllerName, ActionModel action) { if (!action.Selectors.Any() || action.Selectors.Any(x => !x.ActionConstraints.Any())) + { AddApplicationServiceSelector(areaName, controllerName, action); + } else + { NormalizeSelectorRoutes(areaName, controllerName, action); + } } private void AddApplicationServiceSelector(string areaName, string controllerName, ActionModel action) @@ -104,7 +137,9 @@ private void AddApplicationServiceSelector(string areaName, string controllerNam var appServiceSelectorModel = action.Selectors[0]; if (appServiceSelectorModel.AttributeRouteModel == null) + { appServiceSelectorModel.AttributeRouteModel = CreateActionRouteModel(areaName, controllerName, action); + } if (!appServiceSelectorModel.ActionConstraints.Any()) { @@ -134,10 +169,12 @@ private void NormalizeSelectorRoutes(string areaName, string controllerName, Act action.ActionName = GetRestFulActionName(action.ActionName); foreach (var selector in action.Selectors) + { selector.AttributeRouteModel = selector.AttributeRouteModel == null ? CreateActionRouteModel(areaName, controllerName, action) : AttributeRouteModel.CombineAttributeRouteModel( CreateActionRouteModel(areaName, controllerName, action), selector.AttributeRouteModel); + } } private static string GetHttpVerb(ActionModel action) @@ -147,7 +184,9 @@ private static string GetHttpVerb(ActionModel action) out var assemblyAutoApiOptions); if (getValueSuccess && !string.IsNullOrWhiteSpace(assemblyAutoApiOptions?.HttpVerb)) + { return assemblyAutoApiOptions.HttpVerb; + } var verbKey = action.ActionName.GetPascalOrCamelCaseFirstWord().ToLower(); @@ -160,7 +199,10 @@ private string GetRestFulControllerName(string controllerName) { controllerName = controllerName.RemoveSuffix(PlusConsts.ControllerSuffixes.ToArray()); var name = PlusConsts.GetRestFulControllerName?.Invoke(controllerName); - if (!string.IsNullOrWhiteSpace(name)) return name; + if (!string.IsNullOrWhiteSpace(name)) + { + return name; + } return controllerName; } @@ -169,13 +211,19 @@ private string GetRestFulActionName(string actionName) { actionName = actionName.RemoveSuffix(PlusConsts.ActionSuffixes.ToArray()); var name = PlusConsts.GetRestFulActionName?.Invoke(actionName); - if (name != null) return name; + if (name != null) + { + return name; + } var verbKey = actionName.GetPascalOrCamelCaseFirstWord().ToLower(); if (PlusConsts.HttpVerbs.ContainsKey(verbKey)) { if (actionName.Length == verbKey.Length) + { return ""; + } + return actionName.Substring(verbKey.Length); } @@ -197,7 +245,9 @@ private static string GetApiPreFix(ActionModel action) out var assemblyAutoApiOptions); if (getValueSuccess && !string.IsNullOrWhiteSpace(assemblyAutoApiOptions?.ApiPrefix)) + { return assemblyAutoApiOptions.ApiPrefix; + } return PlusConsts.DefaultApiPreFix; } @@ -207,29 +257,47 @@ private void ConfigureParameters(ControllerModel controller) foreach (var action in controller.Actions) foreach (var para in action.Parameters) { - if (para.BindingInfo != null) continue; + if (para.BindingInfo != null) + { + continue; + } if (!TypeHelper.IsPrimitiveExtendedIncludingNullable(para.ParameterInfo.ParameterType)) + { if (CanUseFormBodyBinding(action, para)) + { para.BindingInfo = BindingInfo.GetBindingInfo(new[] { new FromBodyAttribute() }); + } + } } } private bool CanUseFormBodyBinding(ActionModel action, ParameterModel parameter) { if (PlusConsts.FormBodyBindingIgnoredTypes.Any(t => - t.IsAssignableFrom(parameter.ParameterInfo.ParameterType))) return false; + t.IsAssignableFrom(parameter.ParameterInfo.ParameterType))) + { + return false; + } foreach (var selector in action.Selectors) { - if (selector.ActionConstraints == null) continue; + if (selector.ActionConstraints == null) + { + continue; + } foreach (var actionConstraint in selector.ActionConstraints) { - if (!(actionConstraint is HttpMethodActionConstraint httpMethodActionConstraint)) continue; + if (!(actionConstraint is HttpMethodActionConstraint httpMethodActionConstraint)) + { + continue; + } if (httpMethodActionConstraint.HttpMethods.All(x => x.IsIn("GET", "DELETE", "TRACE", "HEAD"))) + { return false; + } } } From 20d227ea877d37d1a514836d9c47fb83213f6f02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8C=85=E5=BC=A0=E9=A9=B0?= Date: Fri, 12 Apr 2024 18:33:34 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E7=94=9F=E6=88=90=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../IAutoApi.cs | 2 +- Plus.AutoApi.Core/Plus.AutoApi.Core.csproj | 7 ++ .../AutoApiControllerFeatureProvider.cs | 1 + Plus.AutoApi/AutoApiConvention.cs | 1 + Plus.AutoApi/Plus.AutoApi.csproj | 46 +++++++------ Plus.AutoApi/Properties/launchSettings.json | 12 ++++ .../Plus.AutoApiGenerator.csproj | 17 +++++ Plus.AutoApiGenerator/ServiceGenerator.cs | 65 +++++++++++++++++++ 8 files changed, 131 insertions(+), 20 deletions(-) rename {Plus.AutoApi => Plus.AutoApi.Core}/IAutoApi.cs (59%) create mode 100644 Plus.AutoApi.Core/Plus.AutoApi.Core.csproj create mode 100644 Plus.AutoApi/Properties/launchSettings.json create mode 100644 Plus.AutoApiGenerator/Plus.AutoApiGenerator.csproj create mode 100644 Plus.AutoApiGenerator/ServiceGenerator.cs diff --git a/Plus.AutoApi/IAutoApi.cs b/Plus.AutoApi.Core/IAutoApi.cs similarity index 59% rename from Plus.AutoApi/IAutoApi.cs rename to Plus.AutoApi.Core/IAutoApi.cs index 42300b0..47ddc45 100644 --- a/Plus.AutoApi/IAutoApi.cs +++ b/Plus.AutoApi.Core/IAutoApi.cs @@ -1,4 +1,4 @@ -namespace Plus.AutoApi +namespace Plus.AutoApi.Core { public interface IAutoApi { diff --git a/Plus.AutoApi.Core/Plus.AutoApi.Core.csproj b/Plus.AutoApi.Core/Plus.AutoApi.Core.csproj new file mode 100644 index 0000000..dbdcea4 --- /dev/null +++ b/Plus.AutoApi.Core/Plus.AutoApi.Core.csproj @@ -0,0 +1,7 @@ + + + + netstandard2.0 + + + diff --git a/Plus.AutoApi/AutoApiControllerFeatureProvider.cs b/Plus.AutoApi/AutoApiControllerFeatureProvider.cs index 43d5be7..b553790 100644 --- a/Plus.AutoApi/AutoApiControllerFeatureProvider.cs +++ b/Plus.AutoApi/AutoApiControllerFeatureProvider.cs @@ -2,6 +2,7 @@ using Plus.AutoApi.Attributes; using Plus.AutoApi.Helpers; using System.Reflection; +using Plus.AutoApi.Core; namespace Plus.AutoApi { diff --git a/Plus.AutoApi/AutoApiConvention.cs b/Plus.AutoApi/AutoApiConvention.cs index 0ec9170..0de1dcb 100644 --- a/Plus.AutoApi/AutoApiConvention.cs +++ b/Plus.AutoApi/AutoApiConvention.cs @@ -8,6 +8,7 @@ using System; using System.Linq; using System.Reflection; +using Plus.AutoApi.Core; namespace Plus.AutoApi { diff --git a/Plus.AutoApi/Plus.AutoApi.csproj b/Plus.AutoApi/Plus.AutoApi.csproj index 6e1f5fc..cc9feb4 100644 --- a/Plus.AutoApi/Plus.AutoApi.csproj +++ b/Plus.AutoApi/Plus.AutoApi.csproj @@ -1,24 +1,32 @@  - - netcoreapp3.1 - Plus.AutoApi - 阿星Plus - https://meowv.com - Plus.AutoApi 是一个可以用来动态生成 WebApi 不用写 Controller 的组件 - MIT - https://meowv.com - https://github.com/Meowv/Plus.AutoApi - https://avatars2.githubusercontent.com/u/13010050 - https://github.com/Meowv/Plus.AutoApi - git - plus;autoapi;plus.autoapi; - .NET Core 开发工具包 - 0.1.0 - + + netcoreapp3.1 + Plus.AutoApi + 阿星Plus + https://meowv.com + Plus.AutoApi 是一个可以用来动态生成 WebApi 不用写 Controller 的组件 + MIT + https://meowv.com + https://github.com/Meowv/Plus.AutoApi + https://avatars2.githubusercontent.com/u/13010050 + https://github.com/Meowv/Plus.AutoApi + git + plus;autoapi;plus.autoapi; + .NET Core 开发工具包 + 0.1.0 + - - - + + + + + + + + + + + \ No newline at end of file diff --git a/Plus.AutoApi/Properties/launchSettings.json b/Plus.AutoApi/Properties/launchSettings.json new file mode 100644 index 0000000..ac9bf13 --- /dev/null +++ b/Plus.AutoApi/Properties/launchSettings.json @@ -0,0 +1,12 @@ +{ + "profiles": { + "Plus.AutoApi": { + "commandName": "Project", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "applicationUrl": "http://localhost:64869" + } + } +} \ No newline at end of file diff --git a/Plus.AutoApiGenerator/Plus.AutoApiGenerator.csproj b/Plus.AutoApiGenerator/Plus.AutoApiGenerator.csproj new file mode 100644 index 0000000..9d0704d --- /dev/null +++ b/Plus.AutoApiGenerator/Plus.AutoApiGenerator.csproj @@ -0,0 +1,17 @@ + + + + netstandard2.0 + false + false + true + + + + + + + + + + diff --git a/Plus.AutoApiGenerator/ServiceGenerator.cs b/Plus.AutoApiGenerator/ServiceGenerator.cs new file mode 100644 index 0000000..449bf45 --- /dev/null +++ b/Plus.AutoApiGenerator/ServiceGenerator.cs @@ -0,0 +1,65 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.Text; +using Plus.AutoApi; +using Plus.AutoApi.Core; + +namespace Plus.AutoApiGenerator +{ + [Generator] + public class ServiceGenerator : ISourceGenerator + { + private const string NATIVE_SERVICES_TXT_ADDITIONAL_FILE_NAME = "Services.txt"; + private static readonly char[] ZeroWhiteSpace = new char[] + { + '\uFEFF', // ZERO WIDTH NO-BREAK SPACE (U+FEFF) + '\u200B', // ZERO WIDTH SPACE (U+200B) + }; + public void Initialize(GeneratorInitializationContext context) + { + + } + + public void Execute(GeneratorExecutionContext context) + { + Debugger.Launch(); + var nativeMethodsTxtFiles = context.AdditionalFiles + .Where(af => string.Equals(Path.GetFileName(af.Path), NATIVE_SERVICES_TXT_ADDITIONAL_FILE_NAME, StringComparison.OrdinalIgnoreCase)).ToList(); + if (!nativeMethodsTxtFiles.Any()) + { + return; + } + + var parseOptions = (CSharpParseOptions)context.ParseOptions; + + foreach (AdditionalText nativeMethodsTxtFile in nativeMethodsTxtFiles) + { + var nativeMethodsTxt = nativeMethodsTxtFile.GetText(context.CancellationToken); + if (nativeMethodsTxt is null) + { + return; + } + + foreach (TextLine line in nativeMethodsTxt.Lines) + { + context.CancellationToken.ThrowIfCancellationRequested(); + string name = line.ToString(); + if (string.IsNullOrWhiteSpace(name) || name.StartsWith("//", StringComparison.InvariantCulture)) + { + continue; + } + + name = name.Trim().Trim(ZeroWhiteSpace); + var location = Location.Create(nativeMethodsTxtFile.Path, line.Span, nativeMethodsTxt.Lines.GetLinePositionSpan(line.Span)); + + context.AddSource(name, $"public class {name}{{}}"); + } + } + } + } +}