更新Linux截图

HttpClient 统一到 HttpClientFactory
This commit is contained in:
Aigio Liu
2021-02-23 12:05:22 +08:00
parent a0226c8d3a
commit a85f977ccf
24 changed files with 349 additions and 107 deletions
+120
View File
@@ -0,0 +1,120 @@
using System.Collections.Generic;
using System.Linq;
namespace System
{
/// <summary>
/// CPU 构架,例如 x86、arm 等
/// 例如不同的 Android 设备使用不同的 CPU,而不同的 CPU 支持不同的指令集。
/// <para>CPU 与指令集的每种组合都有专属的应用二进制接口 (ABI)。</para>
/// <para>https://developer.android.google.cn/ndk/guides/abis.html</para>
/// <para>在比较版本支持的值与设备支持的值中的交集中,值越大的,优先选取。</para>
/// </summary>
public static class CPUABI
{
/// <inheritdoc cref="CPUABI"/>
[Flags]
public enum Value
{
[Obsolete("Deprecated")]
ARM = 4,
[Obsolete("Deprecated")]
MIPS = 8,
/// <summary>
/// https://developer.android.google.cn/ndk/guides/abis.html#x86
/// </summary>
X86 = 16,
/// <summary>
/// https://developer.android.google.cn/ndk/guides/abis.html#v7a
/// </summary>
ARM32 = 32,
[Obsolete("Deprecated")]
MIPS64 = 64,
/// <summary>
/// https://developer.android.google.cn/ndk/guides/abis.html#86-64
/// </summary>
X64 = 128,
/// <summary>
/// https://developer.android.google.cn/ndk/guides/abis.html#arm64-v8a
/// </summary>
ARM64 = 256,
}
static readonly IReadOnlyDictionary<string, Value> mapping = new Dictionary<string, Value>
{
{ "armeabi-v7a", Value.ARM32 },
{ "arm64-v8a", Value.ARM64 },
{ "x86", Value.X86 },
{ "x86_64", Value.X64 },
#pragma warning disable CS0618 // 类型或成员已过时
{ "armeabi", Value.ARM },
{ "mips", Value.MIPS },
{ "mips64", Value.MIPS64 },
#pragma warning restore CS0618 // 类型或成员已过时
};
static readonly Lazy<IReadOnlyDictionary<Value, string>> mapping_reverse
= new Lazy<IReadOnlyDictionary<Value, string>>(() => mapping.ReverseKeyValue());
/// <summary>
/// 将多个 AndroidABI 字符串 转换为 枚举
/// </summary>
/// <param name="abis"></param>
/// <returns></returns>
public static Value Convert(IEnumerable<string>? abis)
{
Value value = 0;
if (abis != null)
{
foreach (var abi in abis)
{
if (!string.IsNullOrWhiteSpace(abi) && mapping.ContainsKey(abi))
{
value |= mapping[abi];
}
}
}
return value;
}
/// <summary>
/// 将多个 AndroidABI 字符串 转换为 枚举
/// </summary>
/// <param name="abis"></param>
/// <returns></returns>
public static Value Convert(params string[] abis) => Convert(abis.AsEnumerable());
/// <summary>
/// 将 AndroidABI 枚举(单值) 转换为字符串
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public static string ToStringSingle(this Value value)
{
var pairs = mapping_reverse.Value;
if (pairs.ContainsKey(value)) return pairs[value];
return value.ToString();
}
/// <summary>
/// 将 AndroidABI 枚举(多值) 转换为字符串
/// </summary>
/// <param name="value"></param>
/// <param name="separator"></param>
/// <returns></returns>
public static string ToStringMultiple(this Value value, string separator = ", ")
{
var enumType = typeof(Value);
if (Enum.IsDefined(enumType, value)) return ToStringSingle(value);
var all_values = (Value[])Enum.GetValues(enumType);
var values = from x in all_values let has = value.HasFlag(x) where has select ToStringSingle(x);
return string.Join(separator, value);
}
}
}
+6 -5
View File
@@ -6,6 +6,7 @@ namespace System
/// <summary>
/// 设备种类,例如手机,平板,电视,手表
/// </summary>
[Flags]
public enum DeviceIdiom
{
/// <summary>
@@ -16,27 +17,27 @@ namespace System
/// <summary>
/// 手机
/// </summary>
Phone,
Phone = 4,
/// <summary>
/// 平板
/// </summary>
Tablet,
Tablet = 8,
/// <summary>
/// 桌面端
/// </summary>
Desktop,
Desktop = 16,
/// <summary>
/// 电视
/// </summary>
TV,
TV = 32,
/// <summary>
/// 手表
/// </summary>
Watch,
Watch = 64,
}
/// <summary>
+12 -1
View File
@@ -1,4 +1,6 @@
using System.Linq.Expressions;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
namespace System
{
@@ -11,6 +13,15 @@ namespace System
/// <returns></returns>
public static TEnum[] GetAll<TEnum>() where TEnum : Enum => (TEnum[])Enum.GetValues(typeof(TEnum));
/// <summary>
/// 将 Flags 枚举进行拆分
/// </summary>
/// <typeparam name="TEnum"></typeparam>
/// <param name="resultant"></param>
/// <returns></returns>
public static IEnumerable<TEnum> FlagsSplit<TEnum>(TEnum resultant) where TEnum : Enum
=> GetAll<TEnum>().Where(x => resultant.HasFlag(x)).ToArray();
internal static TEnum ConvertToEnum<TEnum, TStruct>(this TStruct value)
{
var parameter = Expression.Parameter(typeof(TStruct));
@@ -0,0 +1,14 @@
using System.IO;
namespace System.Net.Http
{
/// <inheritdoc cref="IHttpPlatformHelper"/>
public class HttpPlatformHelper : IHttpPlatformHelper
{
const string DefaultUserAgent = "Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Microsoft; Lumia 950) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2486.0 Mobile Safari/537.36 Edge/14.14263";
public virtual string UserAgent => DefaultUserAgent;
public (string filePath, string mime)? TryHandleUploadFile(Stream fileStream) => null;
}
}
@@ -0,0 +1,40 @@
using Microsoft.Extensions.Logging;
namespace System.Net.Http
{
public abstract class HttpService
{
protected readonly ILogger logger;
readonly IHttpClientFactory _clientFactory;
public HttpService(
ILogger logger,
IHttpClientFactory clientFactory)
{
this.logger = logger;
_clientFactory = clientFactory;
}
/// <summary>
/// 用于 <see cref="IHttpClientFactory.CreateClient(string)"/> 中传递的 name
/// <para>如果为 <see langword="null"/> 则调用 <see cref="HttpClientFactoryExtensions.CreateClient(IHttpClientFactory)"/></para>
/// <para>默认值为 <see langword="null"/></para>
/// </summary>
protected virtual string? ClientName { get; }
protected virtual HttpClient CreateClient()
{
#if DEBUG
logger.LogDebug("CreateClient, name: {0}", ClientName);
#endif
if (ClientName == null)
{
return _clientFactory.CreateClient();
}
else
{
return _clientFactory.CreateClient(ClientName);
}
}
}
}
@@ -0,0 +1,26 @@
using System.IO;
namespace System.Net.Http
{
/// <summary>
/// 由平台实现的HTTP工具助手
/// </summary>
public interface IHttpPlatformHelper
{
/// <summary>
/// 用户代理
/// <para>https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/User-Agent</para>
/// <para>通常可以从平台的WebView控件中调用js获取</para>
/// </summary>
string UserAgent { get; }
/// <summary>
/// 尝试将需要上传的文件流[处理]后保存到临时路径中并返回信息
/// <para>[处理]由客户端平台原生实现</para>
/// <para>例如:文件压缩、格式转换(heic)</para>
/// </summary>
/// <param name="fileStream"></param>
/// <returns></returns>
(string filePath, string mime)? TryHandleUploadFile(Stream fileStream);
}
}
+5 -4
View File
@@ -6,6 +6,7 @@ namespace System
/// <summary>
/// 平台
/// </summary>
[Flags]
public enum Platform
{
/// <summary>
@@ -16,22 +17,22 @@ namespace System
/// <summary>
/// Microsoft Windows / UWP(Universal Windows Platform)
/// </summary>
Windows,
Windows = 4,
/// <summary>
/// Ubuntu / Debian / CentOS / Tizen
/// </summary>
Linux,
Linux = 8,
/// <summary>
/// Android Phone / Android Pad / WearOS(Android Wear) / Android TV
/// </summary>
Android,
Android = 16,
/// <summary>
/// iOS / iPadOS / watchOS / tvOS / macOS
/// </summary>
Apple,
Apple = 32,
}
/// <summary>
@@ -1,6 +1,7 @@
using Microsoft.Extensions.DependencyInjection.Extensions;
using System.Application.Services;
using System.Application.Services.Implementation;
using System.Net.Http;
// ReSharper disable once CheckNamespace
namespace Microsoft.Extensions.DependencyInjection
@@ -17,5 +18,24 @@ namespace Microsoft.Extensions.DependencyInjection
services.TryAddSingleton<IModelValidator, ModelValidator>();
return services;
}
/// <summary>
/// 尝试添加 <see cref="IHttpPlatformHelper"/>
/// </summary>
/// <param name="services"></param>
/// <returns></returns>
public static IServiceCollection TryAddHttpPlatformHelper(this IServiceCollection services)
{
services.TryAddSingleton<IHttpPlatformHelper, HttpPlatformHelper>();
return services;
}
//public static IServiceCollection AddHttpService(this IServiceCollection services, string name)
//{
// // 此函数为添加HTTP服务模板
// // https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/http-requests?view=aspnetcore-5.0
// services.AddHttpClient(name);
// services.AddSingleton<IXXHttpService, XXHttpService>();
//}
}
}
@@ -7,6 +7,7 @@
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="5.0.1" />
<PackageReference Include="Microsoft.Extensions.Http" Version="5.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="5.0.0" />
<PackageReference Include="Nito.Comparers" Version="6.1.0" />
<PackageReference Include="Xamarin.Essentials" Version="1.6.1" />