Browse Source

Implemented `IParameterTypeComparer` to be used in `ApiDescriptionFinder`

The `CrossPlatformParameterTypeComparer` handles type differences in .net-core and .net-framework by replacing the assembly names with placeholders.
This implementation works in all environments because the `CrossPlatformParameterTypeComparer` inherits the default behavior and (once) checks the current framework.
pull/2867/head
Necati Meral 7 years ago
parent
commit
75bb5d6453
  1. 10
      framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/ApiDescriptionFinder.cs
  2. 43
      framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/CrossPlatformParameterTypeComparer.cs
  3. 44
      framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/EnvironmentHelper.cs
  4. 19
      framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/IParameterTypeComparer.cs
  5. 16
      framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/ParameterTypeComparer.cs

10
framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/ApiDescriptionFinder.cs

@ -18,17 +18,21 @@ namespace Volo.Abp.Http.Client.DynamicProxying
protected IApiDescriptionCache Cache { get; } protected IApiDescriptionCache Cache { get; }
protected IParameterTypeComparer ParameterTypeComparer { get; }
private static readonly JsonSerializerSettings SharedJsonSerializerSettings = new JsonSerializerSettings private static readonly JsonSerializerSettings SharedJsonSerializerSettings = new JsonSerializerSettings
{ {
ContractResolver = new CamelCasePropertyNamesContractResolver() ContractResolver = new CamelCasePropertyNamesContractResolver()
}; };
public ApiDescriptionFinder( public ApiDescriptionFinder(
IApiDescriptionCache cache, IApiDescriptionCache cache,
IDynamicProxyHttpClientFactory httpClientFactory) IDynamicProxyHttpClientFactory httpClientFactory,
IParameterTypeComparer parameterTypeComparer)
{ {
Cache = cache; Cache = cache;
HttpClientFactory = httpClientFactory; HttpClientFactory = httpClientFactory;
ParameterTypeComparer = parameterTypeComparer;
CancellationTokenProvider = NullCancellationTokenProvider.Instance; CancellationTokenProvider = NullCancellationTokenProvider.Instance;
} }
@ -57,7 +61,7 @@ namespace Volo.Abp.Http.Client.DynamicProxying
for (int i = 0; i < methodParameters.Length; i++) for (int i = 0; i < methodParameters.Length; i++)
{ {
if (action.ParametersOnMethod[i].TypeAsString != methodParameters[i].ParameterType.GetFullNameWithAssemblyName()) if (!ParameterTypeComparer.TypeMatches(action.ParametersOnMethod[i], methodParameters[i]))
{ {
found = false; found = false;
break; break;

43
framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/CrossPlatformParameterTypeComparer.cs

@ -0,0 +1,43 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Http.Modeling;
namespace Volo.Abp.Http.Client.DynamicProxying
{
/// <summary>
/// Compares the server-side parameter-type with the local parameter-type considering differences between
/// the .net-core and the traditional .net-framework.
/// Inspired by 'https://github.com/akkadotnet/akka.net/pull/2947/files'
/// </summary>
public class CrossPlatformParameterTypeComparer : ParameterTypeComparer, ITransientDependency
{
const string Placeholder = "%COREFX%";
const string NetCoreLib = "System.Private.CoreLib";
const string NetFxLib = "mscorlib";
static readonly bool runsOnNetFx;
static CrossPlatformParameterTypeComparer()
{
runsOnNetFx = string.IsNullOrEmpty(EnvironmentHelper.RuntimeNetCoreVersion);
}
public override bool TypeMatches(MethodParameterApiDescriptionModel actionParameter, ParameterInfo methodParameter)
{
if (runsOnNetFx)
{
// Compare the server's DotnetCore type relative to the current, traditional framework type
// by replacing framework assemblies with an placeholder string.
return actionParameter.TypeAsString.Replace(NetCoreLib, Placeholder)
== methodParameter.ParameterType.GetFullNameWithAssemblyName().Replace(NetFxLib, Placeholder);
}
else
{
return base.TypeMatches(actionParameter, methodParameter);
}
}
}
}

44
framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/EnvironmentHelper.cs

@ -0,0 +1,44 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
namespace Volo.Abp.Http.Client.DynamicProxying
{
/// <summary>
/// Provide helpers to check the environment where the current ABP app is currently running
/// </summary>
static class EnvironmentHelper
{
/// <summary>
/// Initializes the <see cref="EnvironmentHelper"/> class.
/// </summary>
static EnvironmentHelper()
{
RuntimeNetCoreVersion = GetNetCoreVersion();
}
/// <summary>
/// Gets the runtime net core version.
/// </summary>
/// <remarks>
/// If the <see cref="RuntimeNetCoreVersion"/> is null the app is running on a .net Classic environment
/// </remarks>
public static string RuntimeNetCoreVersion { get; }
/// <summary>
/// Gets the net core version.
/// </summary>
static string GetNetCoreVersion()
{
var assembly = typeof(System.Runtime.GCSettings).GetTypeInfo().Assembly;
var assemblyPath = assembly.CodeBase.Split(new[] { '/', '\\' }, StringSplitOptions.RemoveEmptyEntries);
int netCoreAppIndex = Array.IndexOf(assemblyPath, "Microsoft.NETCore.App");
if (netCoreAppIndex > 0 && netCoreAppIndex < assemblyPath.Length - 2)
{
return assemblyPath[netCoreAppIndex + 1];
}
return null;
}
}
}

19
framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/IParameterTypeComparer.cs

@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
using Volo.Abp.Http.Modeling;
namespace Volo.Abp.Http.Client.DynamicProxying
{
public interface IParameterTypeComparer
{
/// <summary>
/// Compares the given parameters.
/// </summary>
/// <param name="actionParameter">The parameter description retreived from the server (depends on the server's runtime)</param>
/// <param name="methodParameter">The local parameter info (depends on the client's runtime)</param>
/// <returns></returns>
public bool TypeMatches(MethodParameterApiDescriptionModel actionParameter, ParameterInfo methodParameter);
}
}

16
framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/ParameterTypeComparer.cs

@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
using Volo.Abp.Http.Modeling;
namespace Volo.Abp.Http.Client.DynamicProxying
{
public class ParameterTypeComparer : IParameterTypeComparer
{
public virtual bool TypeMatches(MethodParameterApiDescriptionModel actionParameter, ParameterInfo methodParameter)
{
return actionParameter.TypeAsString == methodParameter.ParameterType.GetFullNameWithAssemblyName();
}
}
}
Loading…
Cancel
Save