|
|
|
@ -6,6 +6,7 @@ using System.Reflection; |
|
|
|
using System.Text; |
|
|
|
using System.Threading.Tasks; |
|
|
|
using System.Xml; |
|
|
|
using Volo.Abp.Cli.Commands; |
|
|
|
using Volo.Abp.Cli.Http; |
|
|
|
using Volo.Abp.DependencyInjection; |
|
|
|
using Volo.Abp.Http.Modeling; |
|
|
|
@ -17,24 +18,31 @@ namespace Volo.Abp.Cli.ServiceProxy.CSharp |
|
|
|
public class CSharpServiceProxyGenerator : ServiceProxyGeneratorBase, ITransientDependency |
|
|
|
{ |
|
|
|
public const string Name = "CSHARP"; |
|
|
|
public const string UsingPlaceholder = "<using placeholder>"; |
|
|
|
public const string MethodPlaceholder = "<method placeholder>"; |
|
|
|
public const string ClassName = "<className>"; |
|
|
|
public const string ServiceInterface = "<serviceInterface>"; |
|
|
|
public const string ServicePostfix = "APPSERVICE"; |
|
|
|
public const string DefaultNamespace = "ClientProxies"; |
|
|
|
public const string Namespace = "<namespace>"; |
|
|
|
|
|
|
|
public readonly string ClientProxyTemplate = "<using placeholder>" + |
|
|
|
$"{Environment.NewLine}" + |
|
|
|
$"{Environment.NewLine}namespace <namespace>" + |
|
|
|
$"{Environment.NewLine}{{" + |
|
|
|
$"{Environment.NewLine} public class <className> : ClientProxyBase<<serviceInterface>>, <serviceInterface>" + |
|
|
|
$"{Environment.NewLine} {{" + |
|
|
|
$"{Environment.NewLine} <method placeholder>" + |
|
|
|
$"{Environment.NewLine} }}" + |
|
|
|
$"{Environment.NewLine}}}"; |
|
|
|
|
|
|
|
private const string UsingPlaceholder = "<using placeholder>"; |
|
|
|
private const string MethodPlaceholder = "<method placeholder>"; |
|
|
|
private const string ClassName = "<className>"; |
|
|
|
private const string ServiceInterface = "<serviceInterface>"; |
|
|
|
private const string ServicePostfix = "APPSERVICE"; |
|
|
|
private const string DefaultNamespace = "ClientProxies"; |
|
|
|
private const string Namespace = "<namespace>"; |
|
|
|
private readonly string _clientProxyTemplate = "// This file is automatically generated by ABP framework to use MVC Controllers from CSharp" + |
|
|
|
$"{Environment.NewLine}<using placeholder>" + |
|
|
|
$"{Environment.NewLine}" + |
|
|
|
$"{Environment.NewLine}namespace <namespace>" + |
|
|
|
$"{Environment.NewLine}{{" + |
|
|
|
$"{Environment.NewLine} public partial class <className> : ClientProxyBase<<serviceInterface>>, <serviceInterface>" + |
|
|
|
$"{Environment.NewLine} {{" + |
|
|
|
$"{Environment.NewLine} <method placeholder>" + |
|
|
|
$"{Environment.NewLine} }}" + |
|
|
|
$"{Environment.NewLine}}}"; |
|
|
|
private readonly string _clientProxyPartialTemplate = "// This file is part of <className>, you can customize it here" + |
|
|
|
$"{Environment.NewLine}namespace <namespace>" + |
|
|
|
$"{Environment.NewLine}{{" + |
|
|
|
$"{Environment.NewLine} public partial class <className>" + |
|
|
|
$"{Environment.NewLine} {{" + |
|
|
|
$"{Environment.NewLine} }}" + |
|
|
|
$"{Environment.NewLine}}}"; |
|
|
|
private readonly List<string> _usingNamespaceList = new() |
|
|
|
{ |
|
|
|
"using System;", |
|
|
|
@ -54,6 +62,13 @@ namespace Volo.Abp.Cli.ServiceProxy.CSharp |
|
|
|
public override async Task GenerateProxyAsync(GenerateProxyArgs args) |
|
|
|
{ |
|
|
|
var projectFilePath = CheckWorkDirectory(args.WorkDirectory); |
|
|
|
|
|
|
|
if (args.CommandName == RemoveProxyCommand.Name) |
|
|
|
{ |
|
|
|
RemoveClientProxyFile(args); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
var projectName = Path.GetFileNameWithoutExtension(projectFilePath); |
|
|
|
var assemblyFilePath = Path.Combine(args.WorkDirectory, "bin", "Debug", GetTargetFrameworkVersion(projectFilePath), $"{projectName}.dll"); |
|
|
|
var startupModule = GetStartupModule(assemblyFilePath); |
|
|
|
@ -68,34 +83,46 @@ namespace Volo.Abp.Cli.ServiceProxy.CSharp |
|
|
|
{ |
|
|
|
if (ShouldGenerateProxy(controller.Value)) |
|
|
|
{ |
|
|
|
await GenerateClientProxyFile(args, controller.Value, appServiceTypes, startupModule.Namespace); |
|
|
|
await GenerateClientProxyFileAsync(args, controller.Value, appServiceTypes, startupModule.Namespace); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
protected virtual async Task GenerateClientProxyFile(GenerateProxyArgs args, ControllerApiDescriptionModel controllerApiDescription, List<Type> appServiceTypes, string rootNamespace) |
|
|
|
private void RemoveClientProxyFile(GenerateProxyArgs args) |
|
|
|
{ |
|
|
|
var appServiceType = appServiceTypes.FirstOrDefault(x => x.FullName == controllerApiDescription.Interfaces.Last().Type); |
|
|
|
var folder = args.Folder.IsNullOrWhiteSpace()? DefaultNamespace : args.Folder; |
|
|
|
var folderPath = Path.Combine(args.WorkDirectory, folder); |
|
|
|
|
|
|
|
if (appServiceType == null) |
|
|
|
if (Directory.Exists(folderPath)) |
|
|
|
{ |
|
|
|
return; |
|
|
|
Directory.Delete(folderPath, true); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
var folder = DefaultNamespace; |
|
|
|
if (args.ExtraProperties.ContainsKey("--folder")) |
|
|
|
private async Task GenerateClientProxyFileAsync( |
|
|
|
GenerateProxyArgs args, |
|
|
|
ControllerApiDescriptionModel controllerApiDescription, |
|
|
|
List<Type> appServiceTypes, |
|
|
|
string rootNamespace) |
|
|
|
{ |
|
|
|
var appServiceType = appServiceTypes.FirstOrDefault(x => x.FullName == controllerApiDescription.Interfaces.Last().Type); |
|
|
|
|
|
|
|
if (appServiceType == null) |
|
|
|
{ |
|
|
|
folder = args.ExtraProperties["--folder"]; |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
var folder = args.Folder.IsNullOrWhiteSpace()? DefaultNamespace : args.Folder; |
|
|
|
var usingNamespaceList = new List<string>(_usingNamespaceList); |
|
|
|
|
|
|
|
var clientProxyName = $"{controllerApiDescription.ControllerName}ClientProxy"; |
|
|
|
var clientProxyBuilder = new StringBuilder(ClientProxyTemplate); |
|
|
|
var clientProxyBuilder = new StringBuilder(_clientProxyTemplate); |
|
|
|
var fileNamespace = $"{rootNamespace}.{folder.Replace('/', '.')}"; |
|
|
|
usingNamespaceList.Add($"using {appServiceType.Namespace};"); |
|
|
|
|
|
|
|
clientProxyBuilder.Replace(ClassName, clientProxyName); |
|
|
|
clientProxyBuilder.Replace(Namespace, $"{rootNamespace}.{folder.Replace('/','.')}"); |
|
|
|
clientProxyBuilder.Replace(Namespace, fileNamespace); |
|
|
|
clientProxyBuilder.Replace(ServiceInterface, appServiceType.Name); |
|
|
|
usingNamespaceList.Add($"using {appServiceType.Namespace};"); |
|
|
|
|
|
|
|
var methods = appServiceType.GetInterfaces().SelectMany(x => x.GetMethods()).ToList(); |
|
|
|
methods.AddRange(appServiceType.GetMethods()); |
|
|
|
@ -125,9 +152,28 @@ namespace Volo.Abp.Cli.ServiceProxy.CSharp |
|
|
|
{ |
|
|
|
await writer.WriteAsync(clientProxyBuilder.ToString()); |
|
|
|
} |
|
|
|
|
|
|
|
await GenerateClientProxyPartialFileAsync(clientProxyName, fileNamespace, filePath); |
|
|
|
} |
|
|
|
|
|
|
|
private async Task GenerateClientProxyPartialFileAsync(string clientProxyName, string fileNamespace, string filePath) |
|
|
|
{ |
|
|
|
var clientProxyBuilder = new StringBuilder(_clientProxyPartialTemplate); |
|
|
|
clientProxyBuilder.Replace(ClassName, clientProxyName); |
|
|
|
clientProxyBuilder.Replace(Namespace, fileNamespace); |
|
|
|
|
|
|
|
filePath = filePath.Replace(".cs", ".partial.cs"); |
|
|
|
using (var writer = new StreamWriter(filePath)) |
|
|
|
{ |
|
|
|
await writer.WriteAsync(clientProxyBuilder.ToString()); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
protected virtual void GenerateMethod(ActionApiDescriptionModel actionApiDescription, MethodInfo method, StringBuilder clientProxyBuilder, List<string> usingNamespaceList) |
|
|
|
private void GenerateMethod( |
|
|
|
ActionApiDescriptionModel actionApiDescription, |
|
|
|
MethodInfo method, |
|
|
|
StringBuilder clientProxyBuilder, |
|
|
|
List<string> usingNamespaceList) |
|
|
|
{ |
|
|
|
var methodBuilder = new StringBuilder(); |
|
|
|
|
|
|
|
@ -162,7 +208,12 @@ namespace Volo.Abp.Cli.ServiceProxy.CSharp |
|
|
|
methodBuilder.AppendLine(" }"); |
|
|
|
} |
|
|
|
|
|
|
|
private void GenerateAsynchronousMethod(ActionApiDescriptionModel actionApiDescription, MethodInfo method, string returnTypeName, StringBuilder methodBuilder, List<string> usingNamespaceList) |
|
|
|
private void GenerateAsynchronousMethod( |
|
|
|
ActionApiDescriptionModel actionApiDescription, |
|
|
|
MethodInfo method, |
|
|
|
string returnTypeName, |
|
|
|
StringBuilder methodBuilder, |
|
|
|
List<string> usingNamespaceList) |
|
|
|
{ |
|
|
|
methodBuilder.AppendLine($"public async {returnTypeName} {method.Name}(<args>)"); |
|
|
|
|
|
|
|
@ -202,7 +253,7 @@ namespace Volo.Abp.Cli.ServiceProxy.CSharp |
|
|
|
methodBuilder.AppendLine(" }"); |
|
|
|
} |
|
|
|
|
|
|
|
protected virtual bool ShouldGenerateProxy(ControllerApiDescriptionModel controllerApiDescription) |
|
|
|
private bool ShouldGenerateProxy(ControllerApiDescriptionModel controllerApiDescription) |
|
|
|
{ |
|
|
|
if (!controllerApiDescription.Interfaces.Any()) |
|
|
|
{ |
|
|
|
|