Browse Source

Improved

pull/9905/head
liangshiwei 5 years ago
parent
commit
22f24c7730
  1. 2
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/ProxyCommandBase.cs
  2. 41
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ServiceProxy/CSharp/CSharpServiceProxyGenerator.cs
  3. 90
      framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/ClientProxyBase.cs
  4. 6
      templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.Client/MyCompanyName.MyProjectName.HttpApi.Client.csproj
  5. 6
      templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.Client/MyProjectNameHttpApiClientModule.cs

2
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/ProxyCommandBase.cs

@ -68,7 +68,7 @@ namespace Volo.Abp.Cli.Commands
var workDirectory = commandLineArgs.Options.GetOrNull(Options.WorkDirectory.Short, Options.WorkDirectory.Long) ?? Directory.GetCurrentDirectory();
var folder = commandLineArgs.Options.GetOrNull(Options.Folder.Long);
return new GenerateProxyArgs(CommandName, workDirectory, module.ToLower(), url, output, target, apiName, source, folder, commandLineArgs.Options);
return new GenerateProxyArgs(CommandName, workDirectory, module, url, output, target, apiName, source, folder, commandLineArgs.Options);
}
public virtual string GetUsageInfo()

41
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ServiceProxy/CSharp/CSharpServiceProxyGenerator.cs

@ -33,7 +33,7 @@ namespace Volo.Abp.Cli.ServiceProxy.CSharp
$"{Environment.NewLine}" +
$"{Environment.NewLine}namespace <namespace>" +
$"{Environment.NewLine}{{" +
$"{Environment.NewLine} public partial class <className> : ClientProxyBase<<serviceInterface>>, <serviceInterface>" +
$"{Environment.NewLine} public partial class <className> : ClientProxyBase, <serviceInterface>" +
$"{Environment.NewLine} {{" +
$"{Environment.NewLine} <method placeholder>" +
$"{Environment.NewLine} }}" +
@ -65,6 +65,7 @@ namespace Volo.Abp.Cli.ServiceProxy.CSharp
public override async Task GenerateProxyAsync(GenerateProxyArgs args)
{
CheckFolder(args.Folder);
var projectFilePath = CheckWorkDirectory(args.WorkDirectory);
if (args.CommandName == RemoveProxyCommand.Name)
@ -90,6 +91,19 @@ namespace Volo.Abp.Cli.ServiceProxy.CSharp
await GenerateClientProxyFileAsync(args, controller.Value, appServiceTypes, startupModule.Namespace);
}
}
await CreateGenerateProxyJsonFile(args, applicationApiDescriptionModel);
}
private async Task CreateGenerateProxyJsonFile(GenerateProxyArgs args, ApplicationApiDescriptionModel applicationApiDescriptionModel)
{
var folder = args.Folder.IsNullOrWhiteSpace()? DefaultNamespace : args.Folder;
var filePath = Path.Combine(args.WorkDirectory, folder, $"{args.Module}-generate-proxy.json");
using (var writer = new StreamWriter(filePath))
{
await writer.WriteAsync(JsonSerializer.Serialize(applicationApiDescriptionModel, indented: true));
}
}
private void RemoveClientProxyFile(GenerateProxyArgs args)
@ -140,7 +154,7 @@ namespace Volo.Abp.Cli.ServiceProxy.CSharp
continue;
}
GenerateMethod(actionApiDescription, method, clientProxyBuilder, usingNamespaceList);
GenerateMethod(actionApiDescription, appServiceType.Name, method, clientProxyBuilder, usingNamespaceList);
}
foreach (var usingNamespace in usingNamespaceList)
@ -184,6 +198,7 @@ namespace Volo.Abp.Cli.ServiceProxy.CSharp
private void GenerateMethod(
ActionApiDescriptionModel actionApiDescription,
string serviceName,
MethodInfo method,
StringBuilder clientProxyBuilder,
List<string> usingNamespaceList)
@ -199,7 +214,7 @@ namespace Volo.Abp.Cli.ServiceProxy.CSharp
return;
}
GenerateAsynchronousMethod(actionApiDescription, method, returnTypeName, methodBuilder, usingNamespaceList);
GenerateAsynchronousMethod(actionApiDescription, serviceName ,method, returnTypeName, methodBuilder, usingNamespaceList);
clientProxyBuilder.Replace(MethodPlaceholder, $"{methodBuilder} {Environment.NewLine} {MethodPlaceholder}");
}
@ -223,6 +238,7 @@ namespace Volo.Abp.Cli.ServiceProxy.CSharp
private void GenerateAsynchronousMethod(
ActionApiDescriptionModel actionApiDescription,
string serviceName,
MethodInfo method,
string returnTypeName,
StringBuilder methodBuilder,
@ -239,20 +255,14 @@ namespace Volo.Abp.Cli.ServiceProxy.CSharp
methodBuilder.Replace(", )", ")");
methodBuilder.AppendLine(" {");
methodBuilder.AppendLine(" #region ActionApiDescriptionModel JSON");
methodBuilder.AppendLine($" var actionApiDescription = \"{JsonSerializer.Serialize(actionApiDescription).Replace("\"","\\\"")}\";");
methodBuilder.AppendLine(" #endregion");
methodBuilder.AppendLine("");
methodBuilder.AppendLine(" var action = JsonSerializer.Deserialize<ActionApiDescriptionModel>(actionApiDescription);");
methodBuilder.AppendLine("");
if (method.ReturnType.GenericTypeArguments.IsNullOrEmpty())
{
methodBuilder.AppendLine(" await MakeRequestAsync(action, <args>);");
methodBuilder.AppendLine($" await MakeRequestAsync<{serviceName}>(\"{method.Name}\", <args>);");
}
else
{
methodBuilder.AppendLine($" return await MakeRequestAsync<{returnTypeName.Replace("Task<", string.Empty)}(action, <args>);");
methodBuilder.AppendLine($" return await MakeRequestAsync<{serviceName}, {returnTypeName.Replace("Task<", string.Empty)}(\"{method.Name}\", <args>);");
}
foreach (var parameter in method.GetParameters())
@ -262,7 +272,6 @@ namespace Volo.Abp.Cli.ServiceProxy.CSharp
methodBuilder.Replace(", <args>", string.Empty);
methodBuilder.Replace(", )", ")");
methodBuilder.AppendLine("");
methodBuilder.AppendLine(" }");
}
@ -371,6 +380,14 @@ namespace Volo.Abp.Cli.ServiceProxy.CSharp
return projectFiles.First();
}
private static void CheckFolder(string folder)
{
if (!folder.IsNullOrWhiteSpace() && Path.HasExtension(folder))
{
throw new CliUsageException("Option folder should be a directory.");
}
}
private Type GetStartupModule(string assemblyPath)
{
return Assembly

90
framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/ClientProxyBase.cs

@ -1,27 +1,61 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.FileProviders;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Http.Client.DynamicProxying;
using Volo.Abp.Http.Modeling;
using Volo.Abp.Json;
using Volo.Abp.VirtualFileSystem;
namespace Volo.Abp.Http.Client
{
public class ClientProxyBase<TService> : ITransientDependency
public class ClientProxyBase : ITransientDependency
{
public const string ApiDescriptionCacheKey = "client-proxy";
public IAbpLazyServiceProvider LazyServiceProvider { get; set; }
protected IHttpProxyExecuter HttpProxyExecuter => LazyServiceProvider.LazyGetRequiredService<IHttpProxyExecuter>();
protected IJsonSerializer JsonSerializer => LazyServiceProvider.LazyGetRequiredService<IJsonSerializer>();
protected IApiDescriptionCache ApiDescriptionCache => LazyServiceProvider.LazyGetRequiredService<ApiDescriptionCache>();
protected IVirtualFileProvider VirtualFileProvider => LazyServiceProvider.LazyGetRequiredService<VirtualFileProvider>();
protected virtual async Task MakeRequestAsync(ActionApiDescriptionModel action, params object[] arguments)
protected static readonly Dictionary<string, ActionApiDescriptionModel> ActionApiDescriptionModels = new Dictionary<string, ActionApiDescriptionModel>();
protected virtual async Task MakeRequestAsync<TService>(string methodName, params object[] arguments)
{
await HttpProxyExecuter.MakeRequestAsync(new HttpProxyExecuterContext(action, BuildArguments(action, arguments), typeof(TService)));
await HttpProxyExecuter.MakeRequestAsync(await BuildHttpProxyExecuterContext<TService>(methodName, arguments));
}
protected virtual async Task<T> MakeRequestAsync<T>(ActionApiDescriptionModel action, params object[] arguments)
protected virtual async Task<T> MakeRequestAsync<TService,T>(string methodName, params object[] arguments)
{
return await HttpProxyExecuter.MakeRequestAndGetResultAsync<T>(new HttpProxyExecuterContext(action, BuildArguments(action, arguments), typeof(TService)));
return await HttpProxyExecuter.MakeRequestAndGetResultAsync<T>(await BuildHttpProxyExecuterContext<TService>(methodName, arguments));
}
protected virtual async Task<HttpProxyExecuterContext> BuildHttpProxyExecuterContext<TService>(string methodName, params object[] arguments)
{
var actionDescriptionKey = $"{typeof(TService).Name}.{methodName}";
if (!ActionApiDescriptionModels.ContainsKey(actionDescriptionKey))
{
var apiDescription = await ApiDescriptionCache.GetAsync(ApiDescriptionCacheKey, GetApplicationApiDescriptionModel);
var controllers = apiDescription.Modules.Select(x=>x.Value).SelectMany(x => x.Controllers.Values).ToList();
foreach (var controller in controllers.Where(x => x.Interfaces.Any()))
{
var appServiceType = controller.Interfaces.Last().Type.Split('.').Last();
foreach (var actionItem in controller.Actions.Values)
{
ActionApiDescriptionModels.Add($"{appServiceType}.{actionItem.Name}", actionItem);
}
}
}
var action = ActionApiDescriptionModels[actionDescriptionKey];
return new HttpProxyExecuterContext(action, BuildArguments(action, arguments), typeof(TService));
}
protected virtual Dictionary<string, object> BuildArguments(ActionApiDescriptionModel action, object[] arguments)
@ -36,5 +70,51 @@ namespace Volo.Abp.Http.Client
return dict;
}
protected virtual async Task<ApplicationApiDescriptionModel> GetApplicationApiDescriptionModel()
{
var applicationApiDescription = ApplicationApiDescriptionModel.Create();
var fileInfoList = new List<IFileInfo>();
GetGenerateProxyFileInfos(fileInfoList);
foreach (var fileInfo in fileInfoList)
{
using (var streamReader = new StreamReader(fileInfo.CreateReadStream()))
{
var content = await streamReader.ReadToEndAsync();
var subApplicationApiDescription = JsonSerializer.Deserialize<ApplicationApiDescriptionModel>(content);
foreach (var module in subApplicationApiDescription.Modules)
{
if (!applicationApiDescription.Modules.ContainsKey(module.Key))
{
applicationApiDescription.AddModule(module.Value);
}
}
}
}
return applicationApiDescription;
}
private void GetGenerateProxyFileInfos(List<IFileInfo> fileInfoList, string path = "")
{
foreach (var directoryContent in VirtualFileProvider.GetDirectoryContents(path))
{
if (directoryContent.IsDirectory)
{
GetGenerateProxyFileInfos(fileInfoList, directoryContent.PhysicalPath);
}
else
{
if (directoryContent.Name.EndsWith("generate-proxy.json"))
{
fileInfoList.Add(VirtualFileProvider.GetFileInfo(directoryContent.GetVirtualOrPhysicalPathOrNull()));
}
}
}
}
}
}

6
templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.Client/MyCompanyName.MyProjectName.HttpApi.Client.csproj

@ -5,12 +5,18 @@
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<RootNamespace>MyCompanyName.MyProjectName</RootNamespace>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\MyCompanyName.MyProjectName.Application.Contracts\MyCompanyName.MyProjectName.Application.Contracts.csproj" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="**\*generate-proxy.json" />
<Content Remove="**\*generate-proxy.json" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\..\modules\account\src\Volo.Abp.Account.HttpApi.Client\Volo.Abp.Account.HttpApi.Client.csproj" />
<ProjectReference Include="..\..\..\..\..\modules\identity\src\Volo.Abp.Identity.HttpApi.Client\Volo.Abp.Identity.HttpApi.Client.csproj" />

6
templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.Client/MyProjectNameHttpApiClientModule.cs

@ -6,6 +6,7 @@ using Volo.Abp.Modularity;
using Volo.Abp.PermissionManagement;
using Volo.Abp.TenantManagement;
using Volo.Abp.SettingManagement;
using Volo.Abp.VirtualFileSystem;
namespace MyCompanyName.MyProjectName
{
@ -28,6 +29,11 @@ namespace MyCompanyName.MyProjectName
typeof(MyProjectNameApplicationContractsModule).Assembly,
RemoteServiceName
);
Configure<AbpVirtualFileSystemOptions>(options =>
{
options.FileSets.AddEmbedded<MyProjectNameHttpApiClientModule>();
});
}
}
}

Loading…
Cancel
Save