mirror of
https://github.com/nsnail/ns-ext.git
synced 2025-04-18 23:22:51 +08:00
feat: * 泛型特性本地化资源描述 * 添加测试项目
This commit is contained in:
parent
f846b7bdbf
commit
1f17375915
@ -1,6 +1,6 @@
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<CodeAnalysisRuleSet>../StyleCopAnalyzers.ruleset</CodeAnalysisRuleSet>
|
||||
<CodeAnalysisRuleSet>../../StyleCopAnalyzers.ruleset</CodeAnalysisRuleSet>
|
||||
<CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>
|
||||
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
|
||||
<MSBuildTreatWarningsAsErrors>true</MSBuildTreatWarningsAsErrors>
|
||||
|
@ -1,35 +1,13 @@
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<AssemblyOriginatorKeyFile>../key.snk</AssemblyOriginatorKeyFile>
|
||||
<!-- $(XXX) 定义有顺序 排序请注意-->
|
||||
<SolutionDir>$(MSBuildThisFileDirectory)</SolutionDir>
|
||||
<Authors>nsnail</Authors>
|
||||
<BaseIntermediateOutputPath>../dist</BaseIntermediateOutputPath>
|
||||
<BaseOutputPath>../dist</BaseOutputPath>
|
||||
<BaseIntermediateOutputPath>$(SolutionDir)/dist/$(MSBuildProjectName)/obj</BaseIntermediateOutputPath>
|
||||
<BaseOutputPath>$(SolutionDir)/dist/$(MSBuildProjectName)/bin</BaseOutputPath>
|
||||
<Copyright>© 2006-2023 nsnail</Copyright>
|
||||
<DelaySign>false</DelaySign>
|
||||
<Description>A .NET extension function library</Description>
|
||||
<EmbedAllSources>true</EmbedAllSources>
|
||||
<EmbedUntrackedSource>true</EmbedUntrackedSource>
|
||||
<EnableBaseIntermediateOutputPathMismatchWarning>false</EnableBaseIntermediateOutputPathMismatchWarning>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<IncludeSymbols>true</IncludeSymbols>
|
||||
<IntermediateOutputPath>$(BaseIntermediateOutputPath)/$(MSBuildProjectName)/obj</IntermediateOutputPath>
|
||||
<IsPackable>true</IsPackable>
|
||||
<MSBuildProjectExtensionsPath>$(BaseIntermediateOutputPath)/$(MSBuildProjectName)/obj</MSBuildProjectExtensionsPath>
|
||||
<OutputPath>$(BaseOutputPath)/$(MSBuildProjectName)/bin</OutputPath>
|
||||
<PackageIcon>logo.png</PackageIcon>
|
||||
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
||||
<PackageProjectUrl>https://github.com/nsnail/ns-ext.git</PackageProjectUrl>
|
||||
<PackageTags>extensions</PackageTags>
|
||||
<Product>NSExt</Product>
|
||||
<PublishRepositoryUrl>true</PublishRepositoryUrl>
|
||||
<RepositoryType>git</RepositoryType>
|
||||
<RepositoryUrl>https://github.com/nsnail/ns-ext.git</RepositoryUrl>
|
||||
<SignAssembly>true</SignAssembly>
|
||||
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<Title>$(AssemblyName)</Title>
|
||||
</PropertyGroup>
|
||||
</Project>
|
18
NSExt.sln
18
NSExt.sln
@ -3,8 +3,6 @@ Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.0.31903.59
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NSExt", "src\NSExt.csproj", "{70DD1C27-7ACB-4BE0-A9CD-D781E4050DE5}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "meta", "meta", "{85E669CB-FC0A-4C1D-92DE-38D0662C257D}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
.editorconfig = .editorconfig
|
||||
@ -30,6 +28,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "meta", "meta", "{85E669CB-F
|
||||
StyleCopAnalyzers.ruleset = StyleCopAnalyzers.ruleset
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NSExt.Tests", "src\NSExt.Tests\NSExt.Tests.csproj", "{557FBEF6-E6D5-4531-86DF-D772A10E2261}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NSExt", "src\NSExt\NSExt.csproj", "{BA0982BE-6E57-4AAF-9778-F9B2EB46F505}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@ -39,9 +41,13 @@ Global
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{70DD1C27-7ACB-4BE0-A9CD-D781E4050DE5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{70DD1C27-7ACB-4BE0-A9CD-D781E4050DE5}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{70DD1C27-7ACB-4BE0-A9CD-D781E4050DE5}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{70DD1C27-7ACB-4BE0-A9CD-D781E4050DE5}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{557FBEF6-E6D5-4531-86DF-D772A10E2261}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{557FBEF6-E6D5-4531-86DF-D772A10E2261}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{557FBEF6-E6D5-4531-86DF-D772A10E2261}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{557FBEF6-E6D5-4531-86DF-D772A10E2261}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{BA0982BE-6E57-4AAF-9778-F9B2EB46F505}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{BA0982BE-6E57-4AAF-9778-F9B2EB46F505}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{BA0982BE-6E57-4AAF-9778-F9B2EB46F505}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{BA0982BE-6E57-4AAF-9778-F9B2EB46F505}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
EndGlobal
|
@ -1,29 +0,0 @@
|
||||
using System.Reflection;
|
||||
using NSExt.Attributes;
|
||||
|
||||
namespace NSExt.Extensions;
|
||||
|
||||
/// <summary>
|
||||
/// EnumExtensions
|
||||
/// </summary>
|
||||
public static class EnumExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取枚举的description属性
|
||||
/// </summary>
|
||||
/// <param name="e">枚举对象</param>
|
||||
/// <returns>description属性</returns>
|
||||
public static string Desc(this Enum e)
|
||||
{
|
||||
var t = e.GetType();
|
||||
var fi = t.GetField(Enum.GetName(t, e)!);
|
||||
var descAttr = fi!.GetCustomAttribute<DescriptionAttribute>(true);
|
||||
if (descAttr is null) {
|
||||
return Enum.GetName(t, e);
|
||||
}
|
||||
|
||||
var str = descAttr.Description;
|
||||
var locAttr = fi!.GetCustomAttribute<LocalizationAttribute>(true);
|
||||
return locAttr is null ? str : locAttr.ResourceClass.GetProperty(str)?.GetValue(default) as string ?? str;
|
||||
}
|
||||
}
|
9
src/NSExt.Tests/NSExt.Tests.csproj
Normal file
9
src/NSExt.Tests/NSExt.Tests.csproj
Normal file
@ -0,0 +1,9 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.5.0-preview-20221221-03" />
|
||||
<PackageReference Include="xunit" Version="2.4.2" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\NSExt\NSExt.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
41
src/NSExt.Tests/TestCase.cs
Normal file
41
src/NSExt.Tests/TestCase.cs
Normal file
@ -0,0 +1,41 @@
|
||||
using NSExt.Attributes;
|
||||
using NSExt.Extensions;
|
||||
using Xunit;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace NSExt.Tests;
|
||||
|
||||
/// <summary>
|
||||
/// 测试用例
|
||||
/// </summary>
|
||||
public class TestCase
|
||||
{
|
||||
private readonly ITestOutputHelper _testOutputHelper;
|
||||
|
||||
public TestCase(ITestOutputHelper testOutputHelper)
|
||||
{
|
||||
_testOutputHelper = testOutputHelper;
|
||||
}
|
||||
|
||||
public enum MyEnum
|
||||
{
|
||||
[ResourceDescription<TestCase>(nameof(Description))]
|
||||
Online = 1
|
||||
|
||||
, Offline = 2
|
||||
}
|
||||
|
||||
public static string Description { get; set; } = "123";
|
||||
|
||||
/// <summary>
|
||||
/// Case1
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void Case1()
|
||||
{
|
||||
var test = MyEnum.Online.ResDesc<TestCase>();
|
||||
|
||||
_testOutputHelper.WriteLine(test);
|
||||
Assert.True(test is not null);
|
||||
}
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Import Project="../CodeQuality.props"/>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="7.0.0"/>
|
||||
<PackageReference Include="MinVer" Version="4.3.0-beta.1">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="../logo.png" Pack="true" PackagePath=""/>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
26
src/NSExt/Attributes/ResourceDescriptionAttribute.cs
Normal file
26
src/NSExt/Attributes/ResourceDescriptionAttribute.cs
Normal file
@ -0,0 +1,26 @@
|
||||
namespace NSExt.Attributes;
|
||||
|
||||
/// <summary>
|
||||
/// 本地化资源描述特性
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class | AttributeTargets.Field)]
|
||||
public class ResourceDescriptionAttribute<T> : Attribute
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ResourceDescriptionAttribute{T}" /> class.
|
||||
/// </summary>
|
||||
public ResourceDescriptionAttribute(string resourceName)
|
||||
{
|
||||
ResourceName = resourceName;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 资源名称
|
||||
/// </summary>
|
||||
public string ResourceName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 资源对象
|
||||
/// </summary>
|
||||
public T ResourceObject { get; set; }
|
||||
}
|
42
src/NSExt/Extensions/EnumExtensions.cs
Normal file
42
src/NSExt/Extensions/EnumExtensions.cs
Normal file
@ -0,0 +1,42 @@
|
||||
using System.Reflection;
|
||||
using NSExt.Attributes;
|
||||
|
||||
namespace NSExt.Extensions;
|
||||
|
||||
/// <summary>
|
||||
/// EnumExtensions
|
||||
/// </summary>
|
||||
public static class EnumExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取枚举的description属性
|
||||
/// </summary>
|
||||
/// <param name="e">枚举对象</param>
|
||||
/// <returns>description属性</returns>
|
||||
public static string Desc(this Enum e)
|
||||
{
|
||||
var typeOfEnum = e.GetType();
|
||||
var typeOfField = typeOfEnum.GetField(Enum.GetName(typeOfEnum, e)!);
|
||||
var descAttr = typeOfField!.GetCustomAttribute<DescriptionAttribute>(true);
|
||||
if (descAttr is null) {
|
||||
return Enum.GetName(typeOfEnum, e);
|
||||
}
|
||||
|
||||
var str = descAttr.Description;
|
||||
var locAttr = typeOfField!.GetCustomAttribute<LocalizationAttribute>(true);
|
||||
return locAttr is null ? str : locAttr.ResourceClass.GetProperty(str)?.GetValue(default) as string ?? str;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取枚举的本地化资源描述
|
||||
/// </summary>
|
||||
public static string ResDesc<T>(this Enum e)
|
||||
{
|
||||
var typeOfEnum = e.GetType();
|
||||
var typeOfField = typeOfEnum.GetField(Enum.GetName(typeOfEnum, e)!);
|
||||
var resDescAttr = typeOfField!.GetCustomAttribute<ResourceDescriptionAttribute<T>>(true);
|
||||
return resDescAttr is null
|
||||
? Enum.GetName(typeOfEnum, e)
|
||||
: typeof(T).GetProperty(resDescAttr.ResourceName)?.GetValue(default) as string;
|
||||
}
|
||||
}
|
35
src/NSExt/NSExt.csproj
Normal file
35
src/NSExt/NSExt.csproj
Normal file
@ -0,0 +1,35 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Import Project="../../CodeQuality.props" />
|
||||
<PropertyGroup>
|
||||
<AssemblyOriginatorKeyFile>../../key.snk</AssemblyOriginatorKeyFile>
|
||||
<DelaySign>false</DelaySign>
|
||||
<Description>A .NET extension function library</Description>
|
||||
<EmbedAllSources>true</EmbedAllSources>
|
||||
<EmbedUntrackedSource>true</EmbedUntrackedSource>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
<IncludeSymbols>true</IncludeSymbols>
|
||||
<IsPackable>true</IsPackable>
|
||||
<PackageIcon>logo.png</PackageIcon>
|
||||
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
||||
<PackageProjectUrl>https://github.com/nsnail/ns-ext.git</PackageProjectUrl>
|
||||
<PackageTags>extensions</PackageTags>
|
||||
<Product>NSExt</Product>
|
||||
<PublishRepositoryUrl>true</PublishRepositoryUrl>
|
||||
<RepositoryType>git</RepositoryType>
|
||||
<RepositoryUrl>https://github.com/nsnail/ns-ext.git</RepositoryUrl>
|
||||
<SignAssembly>true</SignAssembly>
|
||||
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
|
||||
<Title>$(AssemblyName)</Title>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="7.0.0" />
|
||||
<PackageReference Include="MinVer" Version="4.3.0-beta.1">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="../../logo.png" Pack="true" PackagePath="" />
|
||||
</ItemGroup>
|
||||
</Project>
|
Loading…
x
Reference in New Issue
Block a user