1479 changed files with 94862 additions and 58673 deletions
@ -1,20 +0,0 @@ |
|||||
@ECHO off |
|
||||
cls |
|
||||
|
|
||||
ECHO Deleting all BIN and OBJ folders... |
|
||||
ECHO. |
|
||||
|
|
||||
FOR /d /r . %%d in (bin,obj) DO ( |
|
||||
IF EXIST "%%d" ( |
|
||||
ECHO %%d | FIND /I "\node_modules\" > Nul && ( |
|
||||
ECHO.Skipping: %%d |
|
||||
) || ( |
|
||||
ECHO.Deleting: %%d |
|
||||
rd /s/q "%%d" |
|
||||
) |
|
||||
) |
|
||||
) |
|
||||
|
|
||||
ECHO. |
|
||||
ECHO.BIN and OBJ folders have been successfully deleted. Press any key to exit. |
|
||||
pause > nul |
|
||||
@ -1,382 +0,0 @@ |
|||||
|
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00 |
|
||||
# Visual Studio Version 17 |
|
||||
VisualStudioVersion = 17.0.31410.414 |
|
||||
MinimumVisualStudioVersion = 10.0.40219.1 |
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompanyName.ProjectName.Domain", "services\src\CompanyName.ProjectName.Domain\CompanyName.ProjectName.Domain.csproj", "{554AD327-6DBA-4F8F-96F8-81CE7A0C863F}" |
|
||||
EndProject |
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompanyName.ProjectName.Application", "services\src\CompanyName.ProjectName.Application\CompanyName.ProjectName.Application.csproj", "{1A94A50E-06DC-43C1-80B5-B662820EC3EB}" |
|
||||
EndProject |
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompanyName.ProjectName.EntityFrameworkCore", "services\src\CompanyName.ProjectName.EntityFrameworkCore\CompanyName.ProjectName.EntityFrameworkCore.csproj", "{C956DD76-69C8-4A9C-83EA-D17DF83340FD}" |
|
||||
EndProject |
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{CA9AC87F-097E-4F15-8393-4BC07735A5B0}" |
|
||||
EndProject |
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{04DBDB01-70F4-4E06-B468-8F87850B22BE}" |
|
||||
EndProject |
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompanyName.ProjectName.Application.Tests", "services\test\CompanyName.ProjectName.Application.Tests\CompanyName.ProjectName.Application.Tests.csproj", "{50B2631D-129C-47B3-A587-029CCD6099BC}" |
|
||||
EndProject |
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompanyName.ProjectName.Domain.Shared", "services\src\CompanyName.ProjectName.Domain.Shared\CompanyName.ProjectName.Domain.Shared.csproj", "{42F719ED-8413-4895-B5B4-5AB56079BC66}" |
|
||||
EndProject |
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompanyName.ProjectName.Application.Contracts", "services\src\CompanyName.ProjectName.Application.Contracts\CompanyName.ProjectName.Application.Contracts.csproj", "{520659C8-C734-4298-A3DA-B539DB9DFC0B}" |
|
||||
EndProject |
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompanyName.ProjectName.HttpApi", "services\src\CompanyName.ProjectName.HttpApi\CompanyName.ProjectName.HttpApi.csproj", "{4164BDF7-F527-4E85-9CE6-E3C2D7426A27}" |
|
||||
EndProject |
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompanyName.ProjectName.HttpApi.Client", "services\src\CompanyName.ProjectName.HttpApi.Client\CompanyName.ProjectName.HttpApi.Client.csproj", "{3B5A0094-670D-4BB1-BFDD-61B88A8773DC}" |
|
||||
EndProject |
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompanyName.ProjectName.EntityFrameworkCore.Tests", "services\test\CompanyName.ProjectName.EntityFrameworkCore.Tests\CompanyName.ProjectName.EntityFrameworkCore.Tests.csproj", "{1FE30EB9-74A9-47F5-A9F6-7B1FAB672D81}" |
|
||||
EndProject |
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompanyName.ProjectName.TestBase", "services\test\CompanyName.ProjectName.TestBase\CompanyName.ProjectName.TestBase.csproj", "{91853F21-9CD9-4132-BC29-A7D5D84FFFE7}" |
|
||||
EndProject |
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompanyName.ProjectName.Domain.Tests", "services\test\CompanyName.ProjectName.Domain.Tests\CompanyName.ProjectName.Domain.Tests.csproj", "{E512F4D9-9375-480F-A2F6-A46509F9D824}" |
|
||||
EndProject |
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompanyName.ProjectName.HttpApi.Client.ConsoleTestApp", "services\test\CompanyName.ProjectName.HttpApi.Client.ConsoleTestApp\CompanyName.ProjectName.HttpApi.Client.ConsoleTestApp.csproj", "{EF480016-9127-4916-8735-D2466BDBC582}" |
|
||||
EndProject |
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompanyName.ProjectName.DbMigrator", "services\src\CompanyName.ProjectName.DbMigrator\CompanyName.ProjectName.DbMigrator.csproj", "{AA94D832-1CCC-4715-95A9-A483F23A1A5D}" |
|
||||
EndProject |
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "services", "services", "{2C861ADD-76E9-4B3B-8A3C-638EBB67D683}" |
|
||||
EndProject |
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "0.Solution Items", "0.Solution Items", "{2C4A6DB8-8D9E-42E6-B7C3-1EDB7B3DE22E}" |
|
||||
ProjectSection(SolutionItems) = preProject |
|
||||
common.props = common.props |
|
||||
Directory.Build.props = Directory.Build.props |
|
||||
global.json = global.json |
|
||||
NuGet.Config = NuGet.Config |
|
||||
EndProjectSection |
|
||||
EndProject |
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "modules", "modules", "{F8A8EB2A-2D4B-464F-9A13-F8F7B6A8FAA3}" |
|
||||
EndProject |
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "frameworks", "frameworks", "{CC2EBB07-A070-4158-AB37-A0C0BBAEA9F5}" |
|
||||
EndProject |
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Extensions", "Extensions", "{9F5676A3-00DC-48B7-93D1-341C39E19BB9}" |
|
||||
EndProject |
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{C4AC9352-C9F5-4096-8D73-13638232CFB9}" |
|
||||
EndProject |
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "NotificationManagement", "NotificationManagement", "{EB2B8705-18E7-49E1-A565-93A6DE5570D5}" |
|
||||
EndProject |
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{E28AECBD-2904-477C-9817-C67312330A41}" |
|
||||
EndProject |
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{120FE15B-3E5C-4BFF-B874-F09235C9E1ED}" |
|
||||
EndProject |
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompanyName.ProjectName.NotificationManagement.Domain.Shared", "modules\NotificationManagement\src\CompanyName.ProjectName.NotificationManagement.Domain.Shared\CompanyName.ProjectName.NotificationManagement.Domain.Shared.csproj", "{3E69D96A-F923-4AC4-8430-9AAB84B6A3FE}" |
|
||||
EndProject |
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompanyName.ProjectName.NotificationManagement.Domain", "modules\NotificationManagement\src\CompanyName.ProjectName.NotificationManagement.Domain\CompanyName.ProjectName.NotificationManagement.Domain.csproj", "{F475DD35-9F27-43FF-9D96-365661ADC3C6}" |
|
||||
EndProject |
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompanyName.ProjectName.NotificationManagement.Application.Contracts", "modules\NotificationManagement\src\CompanyName.ProjectName.NotificationManagement.Application.Contracts\CompanyName.ProjectName.NotificationManagement.Application.Contracts.csproj", "{34B5BCF2-95C0-4136-AC9E-FC80D8ACBD1C}" |
|
||||
EndProject |
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompanyName.ProjectName.NotificationManagement.Application", "modules\NotificationManagement\src\CompanyName.ProjectName.NotificationManagement.Application\CompanyName.ProjectName.NotificationManagement.Application.csproj", "{4ADEEE7D-7886-4F85-BAA2-CCEE6E30EBFD}" |
|
||||
EndProject |
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompanyName.ProjectName.NotificationManagement.EntityFrameworkCore", "modules\NotificationManagement\src\CompanyName.ProjectName.NotificationManagement.EntityFrameworkCore\CompanyName.ProjectName.NotificationManagement.EntityFrameworkCore.csproj", "{10DF0925-A1EE-4B1C-AAF6-249C6D02424C}" |
|
||||
EndProject |
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompanyName.ProjectName.NotificationManagement.HttpApi", "modules\NotificationManagement\src\CompanyName.ProjectName.NotificationManagement.HttpApi\CompanyName.ProjectName.NotificationManagement.HttpApi.csproj", "{0880AA9C-0E45-43B3-B02A-093736CDD961}" |
|
||||
EndProject |
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompanyName.ProjectName.NotificationManagement.HttpApi.Client", "modules\NotificationManagement\src\CompanyName.ProjectName.NotificationManagement.HttpApi.Client\CompanyName.ProjectName.NotificationManagement.HttpApi.Client.csproj", "{B3554E2E-7150-482F-A08F-DCB8BD166FED}" |
|
||||
EndProject |
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompanyName.ProjectName.NotificationManagement.Application.Tests", "modules\NotificationManagement\test\CompanyName.ProjectName.NotificationManagement.Application.Tests\CompanyName.ProjectName.NotificationManagement.Application.Tests.csproj", "{22A3A359-C6F4-4540-A61F-C8E94A73C95E}" |
|
||||
EndProject |
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompanyName.ProjectName.NotificationManagement.Domain.Tests", "modules\NotificationManagement\test\CompanyName.ProjectName.NotificationManagement.Domain.Tests\CompanyName.ProjectName.NotificationManagement.Domain.Tests.csproj", "{FCE5BD62-F7C7-45EA-80DE-B4880C4A84C6}" |
|
||||
EndProject |
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompanyName.ProjectName.NotificationManagement.EntityFrameworkCore.Tests", "modules\NotificationManagement\test\CompanyName.ProjectName.NotificationManagement.EntityFrameworkCore.Tests\CompanyName.ProjectName.NotificationManagement.EntityFrameworkCore.Tests.csproj", "{19A921F2-1587-4E94-A023-B81956874DAB}" |
|
||||
EndProject |
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompanyName.ProjectName.NotificationManagement.TestBase", "modules\NotificationManagement\test\CompanyName.ProjectName.NotificationManagement.TestBase\CompanyName.ProjectName.NotificationManagement.TestBase.csproj", "{91A3257D-0D1A-479D-8F3C-DBB1944802FE}" |
|
||||
EndProject |
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DataDictionaryManagement", "DataDictionaryManagement", "{9C53260A-6F4B-4106-98B0-EDCC10BB3E1A}" |
|
||||
EndProject |
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{D1CFD035-1562-42CF-A96A-0E2EA8D92E80}" |
|
||||
EndProject |
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{E76E35FC-B62E-48D5-A7AF-79375CFD20BD}" |
|
||||
EndProject |
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompanyName.ProjectName.DataDictionaryManagement.Application", "modules\DataDictionaryManagement\src\CompanyName.ProjectName.DataDictionaryManagement.Application\CompanyName.ProjectName.DataDictionaryManagement.Application.csproj", "{5E6550EA-D878-455C-8EF7-5382661C1D52}" |
|
||||
EndProject |
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompanyName.ProjectName.DataDictionaryManagement.Application.Contracts", "modules\DataDictionaryManagement\src\CompanyName.ProjectName.DataDictionaryManagement.Application.Contracts\CompanyName.ProjectName.DataDictionaryManagement.Application.Contracts.csproj", "{14CDCC5A-006A-41EC-8B48-F3EFAC842432}" |
|
||||
EndProject |
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompanyName.ProjectName.DataDictionaryManagement.Domain", "modules\DataDictionaryManagement\src\CompanyName.ProjectName.DataDictionaryManagement.Domain\CompanyName.ProjectName.DataDictionaryManagement.Domain.csproj", "{11C6A285-8BC0-44C9-9FAB-F93462C75ABC}" |
|
||||
EndProject |
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompanyName.ProjectName.DataDictionaryManagement.Domain.Shared", "modules\DataDictionaryManagement\src\CompanyName.ProjectName.DataDictionaryManagement.Domain.Shared\CompanyName.ProjectName.DataDictionaryManagement.Domain.Shared.csproj", "{C7EB7304-CADD-4F09-84AC-43123406B28F}" |
|
||||
EndProject |
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompanyName.ProjectName.DataDictionaryManagement.EntityFrameworkCore", "modules\DataDictionaryManagement\src\CompanyName.ProjectName.DataDictionaryManagement.EntityFrameworkCore\CompanyName.ProjectName.DataDictionaryManagement.EntityFrameworkCore.csproj", "{DE15C716-E1C3-4FC3-B976-7EA06EBF23F5}" |
|
||||
EndProject |
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompanyName.ProjectName.DataDictionaryManagement.HttpApi", "modules\DataDictionaryManagement\src\CompanyName.ProjectName.DataDictionaryManagement.HttpApi\CompanyName.ProjectName.DataDictionaryManagement.HttpApi.csproj", "{430D3AF9-DCCF-4B6F-BFAF-1ECC2F0594A2}" |
|
||||
EndProject |
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompanyName.ProjectName.DataDictionaryManagement.HttpApi.Client", "modules\DataDictionaryManagement\src\CompanyName.ProjectName.DataDictionaryManagement.HttpApi.Client\CompanyName.ProjectName.DataDictionaryManagement.HttpApi.Client.csproj", "{CC104C76-0CC6-453E-A49D-C4995B6EB72B}" |
|
||||
EndProject |
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompanyName.ProjectName.DataDictionaryManagement.Application.Tests", "modules\DataDictionaryManagement\test\CompanyName.ProjectName.DataDictionaryManagement.Application.Tests\CompanyName.ProjectName.DataDictionaryManagement.Application.Tests.csproj", "{13AF64F3-8962-4568-A0E1-833CCA1922D5}" |
|
||||
EndProject |
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompanyName.ProjectName.DataDictionaryManagement.Domain.Tests", "modules\DataDictionaryManagement\test\CompanyName.ProjectName.DataDictionaryManagement.Domain.Tests\CompanyName.ProjectName.DataDictionaryManagement.Domain.Tests.csproj", "{F9FADD90-8634-4B03-AC44-9F6C80B30E73}" |
|
||||
EndProject |
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompanyName.ProjectName.DataDictionaryManagement.EntityFrameworkCore.Tests", "modules\DataDictionaryManagement\test\CompanyName.ProjectName.DataDictionaryManagement.EntityFrameworkCore.Tests\CompanyName.ProjectName.DataDictionaryManagement.EntityFrameworkCore.Tests.csproj", "{8BC28722-20CC-41BD-B183-4E33E94CA2A7}" |
|
||||
EndProject |
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompanyName.ProjectName.DataDictionaryManagement.TestBase", "modules\DataDictionaryManagement\test\CompanyName.ProjectName.DataDictionaryManagement.TestBase\CompanyName.ProjectName.DataDictionaryManagement.TestBase.csproj", "{6A398750-D7D8-43DC-8DF8-AA65C5766154}" |
|
||||
EndProject |
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "host", "host", "{5AACD0EE-F2B2-49F6-868F-8FE08D7243C0}" |
|
||||
EndProject |
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompanyName.ProjectName.DataDictionaryManagement.HttpApi.Host", "modules\DataDictionaryManagement\host\CompanyName.ProjectName.DataDictionaryManagement.HttpApi.Host\CompanyName.ProjectName.DataDictionaryManagement.HttpApi.Host.csproj", "{8D196E3D-6F95-4793-B948-79669AF09017}" |
|
||||
EndProject |
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "host", "host", "{8C1B8C6C-C518-4290-B070-622CCA6004DA}" |
|
||||
EndProject |
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "CAP", "CAP", "{2C09EED0-5AF6-4F1E-B05A-FB3272EDF6E8}" |
|
||||
EndProject |
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{11ED8435-B5AE-4BF3-9D4B-51FA1E4A18A6}" |
|
||||
EndProject |
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompanyName.ProjectName.HttpApi.Host", "services\host\CompanyName.ProjectName.HttpApi.Host\CompanyName.ProjectName.HttpApi.Host.csproj", "{FB20372D-6C96-4733-9AAC-12522F15CAA6}" |
|
||||
EndProject |
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompanyName.ProjectName.IdentityServer", "services\host\CompanyName.ProjectName.IdentityServer\CompanyName.ProjectName.IdentityServer.csproj", "{FB1C29FF-5467-4CF0-995D-5B3F931AB135}" |
|
||||
EndProject |
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "shared", "shared", "{6434E3F2-B352-4B30-839A-88C2BA166D96}" |
|
||||
EndProject |
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompanyName.ProjectName.Shared.Hosting.Microservices", "shared\CompanyName.ProjectName.Shared.Hosting.Microservices\CompanyName.ProjectName.Shared.Hosting.Microservices.csproj", "{A091AE9B-3A1E-49AC-9AD5-D29310512A3D}" |
|
||||
EndProject |
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompanyName.ProjectName.Shared.Hosting.Gateways", "shared\CompanyName.ProjectName.Shared.Hosting.Gateways\CompanyName.ProjectName.Shared.Hosting.Gateways.csproj", "{C018EFF9-579E-43B3-9181-543BE95E2E03}" |
|
||||
EndProject |
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "gateways", "gateways", "{5C304CBC-F30D-413C-A0AF-8B6814A2D4A3}" |
|
||||
EndProject |
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompanyName.ProjectName.WebGateway", "gateways\CompanyName.ProjectName.WebGateway\CompanyName.ProjectName.WebGateway.csproj", "{D9108313-8D05-4F5F-9AA0-B443EC3374B6}" |
|
||||
EndProject |
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompanyName.ProjectName.Extension", "frameworks\Extensions\src\CompanyName.ProjectName.Extension\CompanyName.ProjectName.Extension.csproj", "{4C65690E-2C17-46A1-BB35-A51BAB2EA3B7}" |
|
||||
EndProject |
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompanyName.ProjectName.CAP", "frameworks\CAP\src\CompanyName.ProjectName.CAP\CompanyName.ProjectName.CAP.csproj", "{3C3FF821-E43D-4D58-8B3C-1E97F4518EF7}" |
|
||||
EndProject |
|
||||
Global |
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution |
|
||||
Debug|Any CPU = Debug|Any CPU |
|
||||
Release|Any CPU = Release|Any CPU |
|
||||
EndGlobalSection |
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution |
|
||||
{554AD327-6DBA-4F8F-96F8-81CE7A0C863F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|
||||
{554AD327-6DBA-4F8F-96F8-81CE7A0C863F}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|
||||
{554AD327-6DBA-4F8F-96F8-81CE7A0C863F}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|
||||
{554AD327-6DBA-4F8F-96F8-81CE7A0C863F}.Release|Any CPU.Build.0 = Release|Any CPU |
|
||||
{1A94A50E-06DC-43C1-80B5-B662820EC3EB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|
||||
{1A94A50E-06DC-43C1-80B5-B662820EC3EB}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|
||||
{1A94A50E-06DC-43C1-80B5-B662820EC3EB}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|
||||
{1A94A50E-06DC-43C1-80B5-B662820EC3EB}.Release|Any CPU.Build.0 = Release|Any CPU |
|
||||
{C956DD76-69C8-4A9C-83EA-D17DF83340FD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|
||||
{C956DD76-69C8-4A9C-83EA-D17DF83340FD}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|
||||
{C956DD76-69C8-4A9C-83EA-D17DF83340FD}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|
||||
{C956DD76-69C8-4A9C-83EA-D17DF83340FD}.Release|Any CPU.Build.0 = Release|Any CPU |
|
||||
{50B2631D-129C-47B3-A587-029CCD6099BC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|
||||
{50B2631D-129C-47B3-A587-029CCD6099BC}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|
||||
{50B2631D-129C-47B3-A587-029CCD6099BC}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|
||||
{50B2631D-129C-47B3-A587-029CCD6099BC}.Release|Any CPU.Build.0 = Release|Any CPU |
|
||||
{42F719ED-8413-4895-B5B4-5AB56079BC66}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|
||||
{42F719ED-8413-4895-B5B4-5AB56079BC66}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|
||||
{42F719ED-8413-4895-B5B4-5AB56079BC66}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|
||||
{42F719ED-8413-4895-B5B4-5AB56079BC66}.Release|Any CPU.Build.0 = Release|Any CPU |
|
||||
{520659C8-C734-4298-A3DA-B539DB9DFC0B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|
||||
{520659C8-C734-4298-A3DA-B539DB9DFC0B}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|
||||
{520659C8-C734-4298-A3DA-B539DB9DFC0B}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|
||||
{520659C8-C734-4298-A3DA-B539DB9DFC0B}.Release|Any CPU.Build.0 = Release|Any CPU |
|
||||
{4164BDF7-F527-4E85-9CE6-E3C2D7426A27}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|
||||
{4164BDF7-F527-4E85-9CE6-E3C2D7426A27}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|
||||
{4164BDF7-F527-4E85-9CE6-E3C2D7426A27}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|
||||
{4164BDF7-F527-4E85-9CE6-E3C2D7426A27}.Release|Any CPU.Build.0 = Release|Any CPU |
|
||||
{3B5A0094-670D-4BB1-BFDD-61B88A8773DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|
||||
{3B5A0094-670D-4BB1-BFDD-61B88A8773DC}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|
||||
{3B5A0094-670D-4BB1-BFDD-61B88A8773DC}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|
||||
{3B5A0094-670D-4BB1-BFDD-61B88A8773DC}.Release|Any CPU.Build.0 = Release|Any CPU |
|
||||
{1FE30EB9-74A9-47F5-A9F6-7B1FAB672D81}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|
||||
{1FE30EB9-74A9-47F5-A9F6-7B1FAB672D81}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|
||||
{1FE30EB9-74A9-47F5-A9F6-7B1FAB672D81}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|
||||
{1FE30EB9-74A9-47F5-A9F6-7B1FAB672D81}.Release|Any CPU.Build.0 = Release|Any CPU |
|
||||
{91853F21-9CD9-4132-BC29-A7D5D84FFFE7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|
||||
{91853F21-9CD9-4132-BC29-A7D5D84FFFE7}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|
||||
{91853F21-9CD9-4132-BC29-A7D5D84FFFE7}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|
||||
{91853F21-9CD9-4132-BC29-A7D5D84FFFE7}.Release|Any CPU.Build.0 = Release|Any CPU |
|
||||
{E512F4D9-9375-480F-A2F6-A46509F9D824}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|
||||
{E512F4D9-9375-480F-A2F6-A46509F9D824}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|
||||
{E512F4D9-9375-480F-A2F6-A46509F9D824}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|
||||
{E512F4D9-9375-480F-A2F6-A46509F9D824}.Release|Any CPU.Build.0 = Release|Any CPU |
|
||||
{EF480016-9127-4916-8735-D2466BDBC582}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|
||||
{EF480016-9127-4916-8735-D2466BDBC582}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|
||||
{EF480016-9127-4916-8735-D2466BDBC582}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|
||||
{EF480016-9127-4916-8735-D2466BDBC582}.Release|Any CPU.Build.0 = Release|Any CPU |
|
||||
{AA94D832-1CCC-4715-95A9-A483F23A1A5D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|
||||
{AA94D832-1CCC-4715-95A9-A483F23A1A5D}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|
||||
{AA94D832-1CCC-4715-95A9-A483F23A1A5D}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|
||||
{AA94D832-1CCC-4715-95A9-A483F23A1A5D}.Release|Any CPU.Build.0 = Release|Any CPU |
|
||||
{3E69D96A-F923-4AC4-8430-9AAB84B6A3FE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|
||||
{3E69D96A-F923-4AC4-8430-9AAB84B6A3FE}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|
||||
{3E69D96A-F923-4AC4-8430-9AAB84B6A3FE}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|
||||
{3E69D96A-F923-4AC4-8430-9AAB84B6A3FE}.Release|Any CPU.Build.0 = Release|Any CPU |
|
||||
{F475DD35-9F27-43FF-9D96-365661ADC3C6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|
||||
{F475DD35-9F27-43FF-9D96-365661ADC3C6}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|
||||
{F475DD35-9F27-43FF-9D96-365661ADC3C6}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|
||||
{F475DD35-9F27-43FF-9D96-365661ADC3C6}.Release|Any CPU.Build.0 = Release|Any CPU |
|
||||
{34B5BCF2-95C0-4136-AC9E-FC80D8ACBD1C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|
||||
{34B5BCF2-95C0-4136-AC9E-FC80D8ACBD1C}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|
||||
{34B5BCF2-95C0-4136-AC9E-FC80D8ACBD1C}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|
||||
{34B5BCF2-95C0-4136-AC9E-FC80D8ACBD1C}.Release|Any CPU.Build.0 = Release|Any CPU |
|
||||
{4ADEEE7D-7886-4F85-BAA2-CCEE6E30EBFD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|
||||
{4ADEEE7D-7886-4F85-BAA2-CCEE6E30EBFD}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|
||||
{4ADEEE7D-7886-4F85-BAA2-CCEE6E30EBFD}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|
||||
{4ADEEE7D-7886-4F85-BAA2-CCEE6E30EBFD}.Release|Any CPU.Build.0 = Release|Any CPU |
|
||||
{10DF0925-A1EE-4B1C-AAF6-249C6D02424C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|
||||
{10DF0925-A1EE-4B1C-AAF6-249C6D02424C}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|
||||
{10DF0925-A1EE-4B1C-AAF6-249C6D02424C}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|
||||
{10DF0925-A1EE-4B1C-AAF6-249C6D02424C}.Release|Any CPU.Build.0 = Release|Any CPU |
|
||||
{0880AA9C-0E45-43B3-B02A-093736CDD961}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|
||||
{0880AA9C-0E45-43B3-B02A-093736CDD961}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|
||||
{0880AA9C-0E45-43B3-B02A-093736CDD961}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|
||||
{0880AA9C-0E45-43B3-B02A-093736CDD961}.Release|Any CPU.Build.0 = Release|Any CPU |
|
||||
{B3554E2E-7150-482F-A08F-DCB8BD166FED}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|
||||
{B3554E2E-7150-482F-A08F-DCB8BD166FED}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|
||||
{B3554E2E-7150-482F-A08F-DCB8BD166FED}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|
||||
{B3554E2E-7150-482F-A08F-DCB8BD166FED}.Release|Any CPU.Build.0 = Release|Any CPU |
|
||||
{22A3A359-C6F4-4540-A61F-C8E94A73C95E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|
||||
{22A3A359-C6F4-4540-A61F-C8E94A73C95E}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|
||||
{22A3A359-C6F4-4540-A61F-C8E94A73C95E}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|
||||
{22A3A359-C6F4-4540-A61F-C8E94A73C95E}.Release|Any CPU.Build.0 = Release|Any CPU |
|
||||
{FCE5BD62-F7C7-45EA-80DE-B4880C4A84C6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|
||||
{FCE5BD62-F7C7-45EA-80DE-B4880C4A84C6}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|
||||
{FCE5BD62-F7C7-45EA-80DE-B4880C4A84C6}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|
||||
{FCE5BD62-F7C7-45EA-80DE-B4880C4A84C6}.Release|Any CPU.Build.0 = Release|Any CPU |
|
||||
{19A921F2-1587-4E94-A023-B81956874DAB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|
||||
{19A921F2-1587-4E94-A023-B81956874DAB}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|
||||
{19A921F2-1587-4E94-A023-B81956874DAB}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|
||||
{19A921F2-1587-4E94-A023-B81956874DAB}.Release|Any CPU.Build.0 = Release|Any CPU |
|
||||
{91A3257D-0D1A-479D-8F3C-DBB1944802FE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|
||||
{91A3257D-0D1A-479D-8F3C-DBB1944802FE}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|
||||
{91A3257D-0D1A-479D-8F3C-DBB1944802FE}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|
||||
{91A3257D-0D1A-479D-8F3C-DBB1944802FE}.Release|Any CPU.Build.0 = Release|Any CPU |
|
||||
{5E6550EA-D878-455C-8EF7-5382661C1D52}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|
||||
{5E6550EA-D878-455C-8EF7-5382661C1D52}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|
||||
{5E6550EA-D878-455C-8EF7-5382661C1D52}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|
||||
{5E6550EA-D878-455C-8EF7-5382661C1D52}.Release|Any CPU.Build.0 = Release|Any CPU |
|
||||
{14CDCC5A-006A-41EC-8B48-F3EFAC842432}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|
||||
{14CDCC5A-006A-41EC-8B48-F3EFAC842432}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|
||||
{14CDCC5A-006A-41EC-8B48-F3EFAC842432}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|
||||
{14CDCC5A-006A-41EC-8B48-F3EFAC842432}.Release|Any CPU.Build.0 = Release|Any CPU |
|
||||
{11C6A285-8BC0-44C9-9FAB-F93462C75ABC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|
||||
{11C6A285-8BC0-44C9-9FAB-F93462C75ABC}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|
||||
{11C6A285-8BC0-44C9-9FAB-F93462C75ABC}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|
||||
{11C6A285-8BC0-44C9-9FAB-F93462C75ABC}.Release|Any CPU.Build.0 = Release|Any CPU |
|
||||
{C7EB7304-CADD-4F09-84AC-43123406B28F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|
||||
{C7EB7304-CADD-4F09-84AC-43123406B28F}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|
||||
{C7EB7304-CADD-4F09-84AC-43123406B28F}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|
||||
{C7EB7304-CADD-4F09-84AC-43123406B28F}.Release|Any CPU.Build.0 = Release|Any CPU |
|
||||
{DE15C716-E1C3-4FC3-B976-7EA06EBF23F5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|
||||
{DE15C716-E1C3-4FC3-B976-7EA06EBF23F5}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|
||||
{DE15C716-E1C3-4FC3-B976-7EA06EBF23F5}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|
||||
{DE15C716-E1C3-4FC3-B976-7EA06EBF23F5}.Release|Any CPU.Build.0 = Release|Any CPU |
|
||||
{430D3AF9-DCCF-4B6F-BFAF-1ECC2F0594A2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|
||||
{430D3AF9-DCCF-4B6F-BFAF-1ECC2F0594A2}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|
||||
{430D3AF9-DCCF-4B6F-BFAF-1ECC2F0594A2}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|
||||
{430D3AF9-DCCF-4B6F-BFAF-1ECC2F0594A2}.Release|Any CPU.Build.0 = Release|Any CPU |
|
||||
{CC104C76-0CC6-453E-A49D-C4995B6EB72B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|
||||
{CC104C76-0CC6-453E-A49D-C4995B6EB72B}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|
||||
{CC104C76-0CC6-453E-A49D-C4995B6EB72B}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|
||||
{CC104C76-0CC6-453E-A49D-C4995B6EB72B}.Release|Any CPU.Build.0 = Release|Any CPU |
|
||||
{13AF64F3-8962-4568-A0E1-833CCA1922D5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|
||||
{13AF64F3-8962-4568-A0E1-833CCA1922D5}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|
||||
{13AF64F3-8962-4568-A0E1-833CCA1922D5}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|
||||
{13AF64F3-8962-4568-A0E1-833CCA1922D5}.Release|Any CPU.Build.0 = Release|Any CPU |
|
||||
{F9FADD90-8634-4B03-AC44-9F6C80B30E73}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|
||||
{F9FADD90-8634-4B03-AC44-9F6C80B30E73}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|
||||
{F9FADD90-8634-4B03-AC44-9F6C80B30E73}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|
||||
{F9FADD90-8634-4B03-AC44-9F6C80B30E73}.Release|Any CPU.Build.0 = Release|Any CPU |
|
||||
{8BC28722-20CC-41BD-B183-4E33E94CA2A7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|
||||
{8BC28722-20CC-41BD-B183-4E33E94CA2A7}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|
||||
{8BC28722-20CC-41BD-B183-4E33E94CA2A7}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|
||||
{8BC28722-20CC-41BD-B183-4E33E94CA2A7}.Release|Any CPU.Build.0 = Release|Any CPU |
|
||||
{6A398750-D7D8-43DC-8DF8-AA65C5766154}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|
||||
{6A398750-D7D8-43DC-8DF8-AA65C5766154}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|
||||
{6A398750-D7D8-43DC-8DF8-AA65C5766154}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|
||||
{6A398750-D7D8-43DC-8DF8-AA65C5766154}.Release|Any CPU.Build.0 = Release|Any CPU |
|
||||
{8D196E3D-6F95-4793-B948-79669AF09017}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|
||||
{8D196E3D-6F95-4793-B948-79669AF09017}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|
||||
{8D196E3D-6F95-4793-B948-79669AF09017}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|
||||
{8D196E3D-6F95-4793-B948-79669AF09017}.Release|Any CPU.Build.0 = Release|Any CPU |
|
||||
{FB20372D-6C96-4733-9AAC-12522F15CAA6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|
||||
{FB20372D-6C96-4733-9AAC-12522F15CAA6}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|
||||
{FB20372D-6C96-4733-9AAC-12522F15CAA6}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|
||||
{FB20372D-6C96-4733-9AAC-12522F15CAA6}.Release|Any CPU.Build.0 = Release|Any CPU |
|
||||
{FB1C29FF-5467-4CF0-995D-5B3F931AB135}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|
||||
{FB1C29FF-5467-4CF0-995D-5B3F931AB135}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|
||||
{FB1C29FF-5467-4CF0-995D-5B3F931AB135}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|
||||
{FB1C29FF-5467-4CF0-995D-5B3F931AB135}.Release|Any CPU.Build.0 = Release|Any CPU |
|
||||
{A091AE9B-3A1E-49AC-9AD5-D29310512A3D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|
||||
{A091AE9B-3A1E-49AC-9AD5-D29310512A3D}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|
||||
{A091AE9B-3A1E-49AC-9AD5-D29310512A3D}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|
||||
{A091AE9B-3A1E-49AC-9AD5-D29310512A3D}.Release|Any CPU.Build.0 = Release|Any CPU |
|
||||
{C018EFF9-579E-43B3-9181-543BE95E2E03}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|
||||
{C018EFF9-579E-43B3-9181-543BE95E2E03}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|
||||
{C018EFF9-579E-43B3-9181-543BE95E2E03}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|
||||
{C018EFF9-579E-43B3-9181-543BE95E2E03}.Release|Any CPU.Build.0 = Release|Any CPU |
|
||||
{D9108313-8D05-4F5F-9AA0-B443EC3374B6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|
||||
{D9108313-8D05-4F5F-9AA0-B443EC3374B6}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|
||||
{D9108313-8D05-4F5F-9AA0-B443EC3374B6}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|
||||
{D9108313-8D05-4F5F-9AA0-B443EC3374B6}.Release|Any CPU.Build.0 = Release|Any CPU |
|
||||
{4C65690E-2C17-46A1-BB35-A51BAB2EA3B7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|
||||
{4C65690E-2C17-46A1-BB35-A51BAB2EA3B7}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|
||||
{4C65690E-2C17-46A1-BB35-A51BAB2EA3B7}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|
||||
{4C65690E-2C17-46A1-BB35-A51BAB2EA3B7}.Release|Any CPU.Build.0 = Release|Any CPU |
|
||||
{3C3FF821-E43D-4D58-8B3C-1E97F4518EF7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|
||||
{3C3FF821-E43D-4D58-8B3C-1E97F4518EF7}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|
||||
{3C3FF821-E43D-4D58-8B3C-1E97F4518EF7}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|
||||
{3C3FF821-E43D-4D58-8B3C-1E97F4518EF7}.Release|Any CPU.Build.0 = Release|Any CPU |
|
||||
EndGlobalSection |
|
||||
GlobalSection(SolutionProperties) = preSolution |
|
||||
HideSolutionNode = FALSE |
|
||||
EndGlobalSection |
|
||||
GlobalSection(NestedProjects) = preSolution |
|
||||
{554AD327-6DBA-4F8F-96F8-81CE7A0C863F} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0} |
|
||||
{1A94A50E-06DC-43C1-80B5-B662820EC3EB} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0} |
|
||||
{C956DD76-69C8-4A9C-83EA-D17DF83340FD} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0} |
|
||||
{CA9AC87F-097E-4F15-8393-4BC07735A5B0} = {2C861ADD-76E9-4B3B-8A3C-638EBB67D683} |
|
||||
{04DBDB01-70F4-4E06-B468-8F87850B22BE} = {2C861ADD-76E9-4B3B-8A3C-638EBB67D683} |
|
||||
{50B2631D-129C-47B3-A587-029CCD6099BC} = {04DBDB01-70F4-4E06-B468-8F87850B22BE} |
|
||||
{42F719ED-8413-4895-B5B4-5AB56079BC66} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0} |
|
||||
{520659C8-C734-4298-A3DA-B539DB9DFC0B} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0} |
|
||||
{4164BDF7-F527-4E85-9CE6-E3C2D7426A27} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0} |
|
||||
{3B5A0094-670D-4BB1-BFDD-61B88A8773DC} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0} |
|
||||
{1FE30EB9-74A9-47F5-A9F6-7B1FAB672D81} = {04DBDB01-70F4-4E06-B468-8F87850B22BE} |
|
||||
{91853F21-9CD9-4132-BC29-A7D5D84FFFE7} = {04DBDB01-70F4-4E06-B468-8F87850B22BE} |
|
||||
{E512F4D9-9375-480F-A2F6-A46509F9D824} = {04DBDB01-70F4-4E06-B468-8F87850B22BE} |
|
||||
{EF480016-9127-4916-8735-D2466BDBC582} = {04DBDB01-70F4-4E06-B468-8F87850B22BE} |
|
||||
{AA94D832-1CCC-4715-95A9-A483F23A1A5D} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0} |
|
||||
{9F5676A3-00DC-48B7-93D1-341C39E19BB9} = {CC2EBB07-A070-4158-AB37-A0C0BBAEA9F5} |
|
||||
{C4AC9352-C9F5-4096-8D73-13638232CFB9} = {9F5676A3-00DC-48B7-93D1-341C39E19BB9} |
|
||||
{EB2B8705-18E7-49E1-A565-93A6DE5570D5} = {F8A8EB2A-2D4B-464F-9A13-F8F7B6A8FAA3} |
|
||||
{E28AECBD-2904-477C-9817-C67312330A41} = {EB2B8705-18E7-49E1-A565-93A6DE5570D5} |
|
||||
{120FE15B-3E5C-4BFF-B874-F09235C9E1ED} = {EB2B8705-18E7-49E1-A565-93A6DE5570D5} |
|
||||
{3E69D96A-F923-4AC4-8430-9AAB84B6A3FE} = {E28AECBD-2904-477C-9817-C67312330A41} |
|
||||
{F475DD35-9F27-43FF-9D96-365661ADC3C6} = {E28AECBD-2904-477C-9817-C67312330A41} |
|
||||
{34B5BCF2-95C0-4136-AC9E-FC80D8ACBD1C} = {E28AECBD-2904-477C-9817-C67312330A41} |
|
||||
{4ADEEE7D-7886-4F85-BAA2-CCEE6E30EBFD} = {E28AECBD-2904-477C-9817-C67312330A41} |
|
||||
{10DF0925-A1EE-4B1C-AAF6-249C6D02424C} = {E28AECBD-2904-477C-9817-C67312330A41} |
|
||||
{0880AA9C-0E45-43B3-B02A-093736CDD961} = {E28AECBD-2904-477C-9817-C67312330A41} |
|
||||
{B3554E2E-7150-482F-A08F-DCB8BD166FED} = {E28AECBD-2904-477C-9817-C67312330A41} |
|
||||
{22A3A359-C6F4-4540-A61F-C8E94A73C95E} = {120FE15B-3E5C-4BFF-B874-F09235C9E1ED} |
|
||||
{FCE5BD62-F7C7-45EA-80DE-B4880C4A84C6} = {120FE15B-3E5C-4BFF-B874-F09235C9E1ED} |
|
||||
{19A921F2-1587-4E94-A023-B81956874DAB} = {120FE15B-3E5C-4BFF-B874-F09235C9E1ED} |
|
||||
{91A3257D-0D1A-479D-8F3C-DBB1944802FE} = {120FE15B-3E5C-4BFF-B874-F09235C9E1ED} |
|
||||
{9C53260A-6F4B-4106-98B0-EDCC10BB3E1A} = {F8A8EB2A-2D4B-464F-9A13-F8F7B6A8FAA3} |
|
||||
{D1CFD035-1562-42CF-A96A-0E2EA8D92E80} = {9C53260A-6F4B-4106-98B0-EDCC10BB3E1A} |
|
||||
{E76E35FC-B62E-48D5-A7AF-79375CFD20BD} = {9C53260A-6F4B-4106-98B0-EDCC10BB3E1A} |
|
||||
{5E6550EA-D878-455C-8EF7-5382661C1D52} = {D1CFD035-1562-42CF-A96A-0E2EA8D92E80} |
|
||||
{14CDCC5A-006A-41EC-8B48-F3EFAC842432} = {D1CFD035-1562-42CF-A96A-0E2EA8D92E80} |
|
||||
{11C6A285-8BC0-44C9-9FAB-F93462C75ABC} = {D1CFD035-1562-42CF-A96A-0E2EA8D92E80} |
|
||||
{C7EB7304-CADD-4F09-84AC-43123406B28F} = {D1CFD035-1562-42CF-A96A-0E2EA8D92E80} |
|
||||
{DE15C716-E1C3-4FC3-B976-7EA06EBF23F5} = {D1CFD035-1562-42CF-A96A-0E2EA8D92E80} |
|
||||
{430D3AF9-DCCF-4B6F-BFAF-1ECC2F0594A2} = {D1CFD035-1562-42CF-A96A-0E2EA8D92E80} |
|
||||
{CC104C76-0CC6-453E-A49D-C4995B6EB72B} = {D1CFD035-1562-42CF-A96A-0E2EA8D92E80} |
|
||||
{13AF64F3-8962-4568-A0E1-833CCA1922D5} = {E76E35FC-B62E-48D5-A7AF-79375CFD20BD} |
|
||||
{F9FADD90-8634-4B03-AC44-9F6C80B30E73} = {E76E35FC-B62E-48D5-A7AF-79375CFD20BD} |
|
||||
{8BC28722-20CC-41BD-B183-4E33E94CA2A7} = {E76E35FC-B62E-48D5-A7AF-79375CFD20BD} |
|
||||
{6A398750-D7D8-43DC-8DF8-AA65C5766154} = {E76E35FC-B62E-48D5-A7AF-79375CFD20BD} |
|
||||
{5AACD0EE-F2B2-49F6-868F-8FE08D7243C0} = {9C53260A-6F4B-4106-98B0-EDCC10BB3E1A} |
|
||||
{8D196E3D-6F95-4793-B948-79669AF09017} = {5AACD0EE-F2B2-49F6-868F-8FE08D7243C0} |
|
||||
{8C1B8C6C-C518-4290-B070-622CCA6004DA} = {2C861ADD-76E9-4B3B-8A3C-638EBB67D683} |
|
||||
{2C09EED0-5AF6-4F1E-B05A-FB3272EDF6E8} = {CC2EBB07-A070-4158-AB37-A0C0BBAEA9F5} |
|
||||
{11ED8435-B5AE-4BF3-9D4B-51FA1E4A18A6} = {2C09EED0-5AF6-4F1E-B05A-FB3272EDF6E8} |
|
||||
{FB20372D-6C96-4733-9AAC-12522F15CAA6} = {8C1B8C6C-C518-4290-B070-622CCA6004DA} |
|
||||
{FB1C29FF-5467-4CF0-995D-5B3F931AB135} = {8C1B8C6C-C518-4290-B070-622CCA6004DA} |
|
||||
{A091AE9B-3A1E-49AC-9AD5-D29310512A3D} = {6434E3F2-B352-4B30-839A-88C2BA166D96} |
|
||||
{C018EFF9-579E-43B3-9181-543BE95E2E03} = {6434E3F2-B352-4B30-839A-88C2BA166D96} |
|
||||
{D9108313-8D05-4F5F-9AA0-B443EC3374B6} = {5C304CBC-F30D-413C-A0AF-8B6814A2D4A3} |
|
||||
{4C65690E-2C17-46A1-BB35-A51BAB2EA3B7} = {C4AC9352-C9F5-4096-8D73-13638232CFB9} |
|
||||
{3C3FF821-E43D-4D58-8B3C-1E97F4518EF7} = {11ED8435-B5AE-4BF3-9D4B-51FA1E4A18A6} |
|
||||
EndGlobalSection |
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution |
|
||||
SolutionGuid = {28315BFD-90E7-4E14-A2EA-F3D23AF4126F} |
|
||||
EndGlobalSection |
|
||||
EndGlobal |
|
||||
@ -1,23 +0,0 @@ |
|||||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation"> |
|
||||
<s:Boolean x:Key="/Default/CodeEditing/Intellisense/CodeCompletion/IntelliSenseCompletingCharacters/CSharpCompletingCharacters/UpgradedFromVSSettings/@EntryValue">True</s:Boolean> |
|
||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=EnforceDoWhileStatementBraces/@EntryIndexedValue">WARNING</s:String> |
|
||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=EnforceFixedStatementBraces/@EntryIndexedValue">WARNING</s:String> |
|
||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=EnforceForeachStatementBraces/@EntryIndexedValue">WARNING</s:String> |
|
||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=EnforceForStatementBraces/@EntryIndexedValue">WARNING</s:String> |
|
||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=EnforceIfStatementBraces/@EntryIndexedValue">WARNING</s:String> |
|
||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=EnforceLockStatementBraces/@EntryIndexedValue">WARNING</s:String> |
|
||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=EnforceUsingStatementBraces/@EntryIndexedValue">WARNING</s:String> |
|
||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=EnforceWhileStatementBraces/@EntryIndexedValue">WARNING</s:String> |
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/BRACES_FOR_FOR/@EntryValue">Required</s:String> |
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/BRACES_FOR_FOREACH/@EntryValue">Required</s:String> |
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/BRACES_FOR_IFELSE/@EntryValue">Required</s:String> |
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/BRACES_FOR_WHILE/@EntryValue">Required</s:String> |
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/BRACES_REDUNDANT/@EntryValue">False</s:Boolean> |
|
||||
<s:Boolean x:Key="/Default/CodeStyle/Generate/=Implementations/@KeyIndexDefined">True</s:Boolean> |
|
||||
<s:String x:Key="/Default/CodeStyle/Generate/=Implementations/Options/=Async/@EntryIndexedValue">False</s:String> |
|
||||
<s:String x:Key="/Default/CodeStyle/Generate/=Implementations/Options/=Mutable/@EntryIndexedValue">False</s:String> |
|
||||
<s:Boolean x:Key="/Default/CodeStyle/Generate/=Overrides/@KeyIndexDefined">True</s:Boolean> |
|
||||
<s:String x:Key="/Default/CodeStyle/Generate/=Overrides/Options/=Async/@EntryIndexedValue">False</s:String> |
|
||||
<s:String x:Key="/Default/CodeStyle/Generate/=Overrides/Options/=Mutable/@EntryIndexedValue">False</s:String> |
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=SQL/@EntryIndexedValue">SQL</s:String> |
|
||||
</wpf:ResourceDictionary> |
|
||||
@ -1,7 +0,0 @@ |
|||||
FROM mcr.microsoft.com/dotnet/aspnet:5.0 |
|
||||
WORKDIR /app |
|
||||
EXPOSE 80 |
|
||||
COPY . . |
|
||||
ENTRYPOINT ["dotnet", "CompanyName.ProjectName.HttpApi.Host.dll"] |
|
||||
|
|
||||
|
|
||||
@ -0,0 +1,382 @@ |
|||||
|
|
||||
|
Microsoft Visual Studio Solution File, Format Version 12.00 |
||||
|
# Visual Studio Version 17 |
||||
|
VisualStudioVersion = 17.0.31410.414 |
||||
|
MinimumVisualStudioVersion = 10.0.40219.1 |
||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lion.AbpPro.Domain", "services\src\Lion.AbpPro.Domain\Lion.AbpPro.Domain.csproj", "{554AD327-6DBA-4F8F-96F8-81CE7A0C863F}" |
||||
|
EndProject |
||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lion.AbpPro.Application", "services\src\Lion.AbpPro.Application\Lion.AbpPro.Application.csproj", "{1A94A50E-06DC-43C1-80B5-B662820EC3EB}" |
||||
|
EndProject |
||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lion.AbpPro.EntityFrameworkCore", "services\src\Lion.AbpPro.EntityFrameworkCore\Lion.AbpPro.EntityFrameworkCore.csproj", "{C956DD76-69C8-4A9C-83EA-D17DF83340FD}" |
||||
|
EndProject |
||||
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{CA9AC87F-097E-4F15-8393-4BC07735A5B0}" |
||||
|
EndProject |
||||
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{04DBDB01-70F4-4E06-B468-8F87850B22BE}" |
||||
|
EndProject |
||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lion.AbpPro.Application.Tests", "services\test\Lion.AbpPro.Application.Tests\Lion.AbpPro.Application.Tests.csproj", "{50B2631D-129C-47B3-A587-029CCD6099BC}" |
||||
|
EndProject |
||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lion.AbpPro.Domain.Shared", "services\src\Lion.AbpPro.Domain.Shared\Lion.AbpPro.Domain.Shared.csproj", "{42F719ED-8413-4895-B5B4-5AB56079BC66}" |
||||
|
EndProject |
||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lion.AbpPro.Application.Contracts", "services\src\Lion.AbpPro.Application.Contracts\Lion.AbpPro.Application.Contracts.csproj", "{520659C8-C734-4298-A3DA-B539DB9DFC0B}" |
||||
|
EndProject |
||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lion.AbpPro.HttpApi", "services\src\Lion.AbpPro.HttpApi\Lion.AbpPro.HttpApi.csproj", "{4164BDF7-F527-4E85-9CE6-E3C2D7426A27}" |
||||
|
EndProject |
||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lion.AbpPro.HttpApi.Client", "services\src\Lion.AbpPro.HttpApi.Client\Lion.AbpPro.HttpApi.Client.csproj", "{3B5A0094-670D-4BB1-BFDD-61B88A8773DC}" |
||||
|
EndProject |
||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lion.AbpPro.EntityFrameworkCore.Tests", "services\test\Lion.AbpPro.EntityFrameworkCore.Tests\Lion.AbpPro.EntityFrameworkCore.Tests.csproj", "{1FE30EB9-74A9-47F5-A9F6-7B1FAB672D81}" |
||||
|
EndProject |
||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lion.AbpPro.TestBase", "services\test\Lion.AbpPro.TestBase\Lion.AbpPro.TestBase.csproj", "{91853F21-9CD9-4132-BC29-A7D5D84FFFE7}" |
||||
|
EndProject |
||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lion.AbpPro.Domain.Tests", "services\test\Lion.AbpPro.Domain.Tests\Lion.AbpPro.Domain.Tests.csproj", "{E512F4D9-9375-480F-A2F6-A46509F9D824}" |
||||
|
EndProject |
||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lion.AbpPro.HttpApi.Client.ConsoleTestApp", "services\test\Lion.AbpPro.HttpApi.Client.ConsoleTestApp\Lion.AbpPro.HttpApi.Client.ConsoleTestApp.csproj", "{EF480016-9127-4916-8735-D2466BDBC582}" |
||||
|
EndProject |
||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lion.AbpPro.DbMigrator", "services\src\Lion.AbpPro.DbMigrator\Lion.AbpPro.DbMigrator.csproj", "{AA94D832-1CCC-4715-95A9-A483F23A1A5D}" |
||||
|
EndProject |
||||
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "services", "services", "{2C861ADD-76E9-4B3B-8A3C-638EBB67D683}" |
||||
|
EndProject |
||||
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "0.Solution Items", "0.Solution Items", "{2C4A6DB8-8D9E-42E6-B7C3-1EDB7B3DE22E}" |
||||
|
ProjectSection(SolutionItems) = preProject |
||||
|
common.props = common.props |
||||
|
Directory.Build.props = Directory.Build.props |
||||
|
global.json = global.json |
||||
|
NuGet.Config = NuGet.Config |
||||
|
EndProjectSection |
||||
|
EndProject |
||||
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "modules", "modules", "{F8A8EB2A-2D4B-464F-9A13-F8F7B6A8FAA3}" |
||||
|
EndProject |
||||
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "frameworks", "frameworks", "{CC2EBB07-A070-4158-AB37-A0C0BBAEA9F5}" |
||||
|
EndProject |
||||
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Extensions", "Extensions", "{9F5676A3-00DC-48B7-93D1-341C39E19BB9}" |
||||
|
EndProject |
||||
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{C4AC9352-C9F5-4096-8D73-13638232CFB9}" |
||||
|
EndProject |
||||
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "NotificationManagement", "NotificationManagement", "{EB2B8705-18E7-49E1-A565-93A6DE5570D5}" |
||||
|
EndProject |
||||
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{E28AECBD-2904-477C-9817-C67312330A41}" |
||||
|
EndProject |
||||
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{120FE15B-3E5C-4BFF-B874-F09235C9E1ED}" |
||||
|
EndProject |
||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lion.AbpPro.NotificationManagement.Domain.Shared", "modules\NotificationManagement\src\Lion.AbpPro.NotificationManagement.Domain.Shared\Lion.AbpPro.NotificationManagement.Domain.Shared.csproj", "{3E69D96A-F923-4AC4-8430-9AAB84B6A3FE}" |
||||
|
EndProject |
||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lion.AbpPro.NotificationManagement.Domain", "modules\NotificationManagement\src\Lion.AbpPro.NotificationManagement.Domain\Lion.AbpPro.NotificationManagement.Domain.csproj", "{F475DD35-9F27-43FF-9D96-365661ADC3C6}" |
||||
|
EndProject |
||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lion.AbpPro.NotificationManagement.Application.Contracts", "modules\NotificationManagement\src\Lion.AbpPro.NotificationManagement.Application.Contracts\Lion.AbpPro.NotificationManagement.Application.Contracts.csproj", "{34B5BCF2-95C0-4136-AC9E-FC80D8ACBD1C}" |
||||
|
EndProject |
||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lion.AbpPro.NotificationManagement.Application", "modules\NotificationManagement\src\Lion.AbpPro.NotificationManagement.Application\Lion.AbpPro.NotificationManagement.Application.csproj", "{4ADEEE7D-7886-4F85-BAA2-CCEE6E30EBFD}" |
||||
|
EndProject |
||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lion.AbpPro.NotificationManagement.EntityFrameworkCore", "modules\NotificationManagement\src\Lion.AbpPro.NotificationManagement.EntityFrameworkCore\Lion.AbpPro.NotificationManagement.EntityFrameworkCore.csproj", "{10DF0925-A1EE-4B1C-AAF6-249C6D02424C}" |
||||
|
EndProject |
||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lion.AbpPro.NotificationManagement.HttpApi", "modules\NotificationManagement\src\Lion.AbpPro.NotificationManagement.HttpApi\Lion.AbpPro.NotificationManagement.HttpApi.csproj", "{0880AA9C-0E45-43B3-B02A-093736CDD961}" |
||||
|
EndProject |
||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lion.AbpPro.NotificationManagement.HttpApi.Client", "modules\NotificationManagement\src\Lion.AbpPro.NotificationManagement.HttpApi.Client\Lion.AbpPro.NotificationManagement.HttpApi.Client.csproj", "{B3554E2E-7150-482F-A08F-DCB8BD166FED}" |
||||
|
EndProject |
||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lion.AbpPro.NotificationManagement.Application.Tests", "modules\NotificationManagement\test\Lion.AbpPro.NotificationManagement.Application.Tests\Lion.AbpPro.NotificationManagement.Application.Tests.csproj", "{22A3A359-C6F4-4540-A61F-C8E94A73C95E}" |
||||
|
EndProject |
||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lion.AbpPro.NotificationManagement.Domain.Tests", "modules\NotificationManagement\test\Lion.AbpPro.NotificationManagement.Domain.Tests\Lion.AbpPro.NotificationManagement.Domain.Tests.csproj", "{FCE5BD62-F7C7-45EA-80DE-B4880C4A84C6}" |
||||
|
EndProject |
||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lion.AbpPro.NotificationManagement.EntityFrameworkCore.Tests", "modules\NotificationManagement\test\Lion.AbpPro.NotificationManagement.EntityFrameworkCore.Tests\Lion.AbpPro.NotificationManagement.EntityFrameworkCore.Tests.csproj", "{19A921F2-1587-4E94-A023-B81956874DAB}" |
||||
|
EndProject |
||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lion.AbpPro.NotificationManagement.TestBase", "modules\NotificationManagement\test\Lion.AbpPro.NotificationManagement.TestBase\Lion.AbpPro.NotificationManagement.TestBase.csproj", "{91A3257D-0D1A-479D-8F3C-DBB1944802FE}" |
||||
|
EndProject |
||||
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DataDictionaryManagement", "DataDictionaryManagement", "{9C53260A-6F4B-4106-98B0-EDCC10BB3E1A}" |
||||
|
EndProject |
||||
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{D1CFD035-1562-42CF-A96A-0E2EA8D92E80}" |
||||
|
EndProject |
||||
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{E76E35FC-B62E-48D5-A7AF-79375CFD20BD}" |
||||
|
EndProject |
||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lion.AbpPro.DataDictionaryManagement.Application", "modules\DataDictionaryManagement\src\Lion.AbpPro.DataDictionaryManagement.Application\Lion.AbpPro.DataDictionaryManagement.Application.csproj", "{5E6550EA-D878-455C-8EF7-5382661C1D52}" |
||||
|
EndProject |
||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lion.AbpPro.DataDictionaryManagement.Application.Contracts", "modules\DataDictionaryManagement\src\Lion.AbpPro.DataDictionaryManagement.Application.Contracts\Lion.AbpPro.DataDictionaryManagement.Application.Contracts.csproj", "{14CDCC5A-006A-41EC-8B48-F3EFAC842432}" |
||||
|
EndProject |
||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lion.AbpPro.DataDictionaryManagement.Domain", "modules\DataDictionaryManagement\src\Lion.AbpPro.DataDictionaryManagement.Domain\Lion.AbpPro.DataDictionaryManagement.Domain.csproj", "{11C6A285-8BC0-44C9-9FAB-F93462C75ABC}" |
||||
|
EndProject |
||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lion.AbpPro.DataDictionaryManagement.Domain.Shared", "modules\DataDictionaryManagement\src\Lion.AbpPro.DataDictionaryManagement.Domain.Shared\Lion.AbpPro.DataDictionaryManagement.Domain.Shared.csproj", "{C7EB7304-CADD-4F09-84AC-43123406B28F}" |
||||
|
EndProject |
||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lion.AbpPro.DataDictionaryManagement.EntityFrameworkCore", "modules\DataDictionaryManagement\src\Lion.AbpPro.DataDictionaryManagement.EntityFrameworkCore\Lion.AbpPro.DataDictionaryManagement.EntityFrameworkCore.csproj", "{DE15C716-E1C3-4FC3-B976-7EA06EBF23F5}" |
||||
|
EndProject |
||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lion.AbpPro.DataDictionaryManagement.HttpApi", "modules\DataDictionaryManagement\src\Lion.AbpPro.DataDictionaryManagement.HttpApi\Lion.AbpPro.DataDictionaryManagement.HttpApi.csproj", "{430D3AF9-DCCF-4B6F-BFAF-1ECC2F0594A2}" |
||||
|
EndProject |
||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lion.AbpPro.DataDictionaryManagement.HttpApi.Client", "modules\DataDictionaryManagement\src\Lion.AbpPro.DataDictionaryManagement.HttpApi.Client\Lion.AbpPro.DataDictionaryManagement.HttpApi.Client.csproj", "{CC104C76-0CC6-453E-A49D-C4995B6EB72B}" |
||||
|
EndProject |
||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lion.AbpPro.DataDictionaryManagement.Application.Tests", "modules\DataDictionaryManagement\test\Lion.AbpPro.DataDictionaryManagement.Application.Tests\Lion.AbpPro.DataDictionaryManagement.Application.Tests.csproj", "{13AF64F3-8962-4568-A0E1-833CCA1922D5}" |
||||
|
EndProject |
||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lion.AbpPro.DataDictionaryManagement.Domain.Tests", "modules\DataDictionaryManagement\test\Lion.AbpPro.DataDictionaryManagement.Domain.Tests\Lion.AbpPro.DataDictionaryManagement.Domain.Tests.csproj", "{F9FADD90-8634-4B03-AC44-9F6C80B30E73}" |
||||
|
EndProject |
||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lion.AbpPro.DataDictionaryManagement.EntityFrameworkCore.Tests", "modules\DataDictionaryManagement\test\Lion.AbpPro.DataDictionaryManagement.EntityFrameworkCore.Tests\Lion.AbpPro.DataDictionaryManagement.EntityFrameworkCore.Tests.csproj", "{8BC28722-20CC-41BD-B183-4E33E94CA2A7}" |
||||
|
EndProject |
||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lion.AbpPro.DataDictionaryManagement.TestBase", "modules\DataDictionaryManagement\test\Lion.AbpPro.DataDictionaryManagement.TestBase\Lion.AbpPro.DataDictionaryManagement.TestBase.csproj", "{6A398750-D7D8-43DC-8DF8-AA65C5766154}" |
||||
|
EndProject |
||||
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "host", "host", "{5AACD0EE-F2B2-49F6-868F-8FE08D7243C0}" |
||||
|
EndProject |
||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lion.AbpPro.DataDictionaryManagement.HttpApi.Host", "modules\DataDictionaryManagement\host\Lion.AbpPro.DataDictionaryManagement.HttpApi.Host\Lion.AbpPro.DataDictionaryManagement.HttpApi.Host.csproj", "{8D196E3D-6F95-4793-B948-79669AF09017}" |
||||
|
EndProject |
||||
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "host", "host", "{8C1B8C6C-C518-4290-B070-622CCA6004DA}" |
||||
|
EndProject |
||||
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "CAP", "CAP", "{2C09EED0-5AF6-4F1E-B05A-FB3272EDF6E8}" |
||||
|
EndProject |
||||
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{11ED8435-B5AE-4BF3-9D4B-51FA1E4A18A6}" |
||||
|
EndProject |
||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lion.AbpPro.HttpApi.Host", "services\host\Lion.AbpPro.HttpApi.Host\Lion.AbpPro.HttpApi.Host.csproj", "{FB20372D-6C96-4733-9AAC-12522F15CAA6}" |
||||
|
EndProject |
||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lion.AbpPro.IdentityServer", "services\host\Lion.AbpPro.IdentityServer\Lion.AbpPro.IdentityServer.csproj", "{FB1C29FF-5467-4CF0-995D-5B3F931AB135}" |
||||
|
EndProject |
||||
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "shared", "shared", "{6434E3F2-B352-4B30-839A-88C2BA166D96}" |
||||
|
EndProject |
||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lion.AbpPro.Shared.Hosting.Microservices", "shared\Lion.AbpPro.Shared.Hosting.Microservices\Lion.AbpPro.Shared.Hosting.Microservices.csproj", "{A091AE9B-3A1E-49AC-9AD5-D29310512A3D}" |
||||
|
EndProject |
||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lion.AbpPro.Shared.Hosting.Gateways", "shared\Lion.AbpPro.Shared.Hosting.Gateways\Lion.AbpPro.Shared.Hosting.Gateways.csproj", "{C018EFF9-579E-43B3-9181-543BE95E2E03}" |
||||
|
EndProject |
||||
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "gateways", "gateways", "{5C304CBC-F30D-413C-A0AF-8B6814A2D4A3}" |
||||
|
EndProject |
||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lion.AbpPro.WebGateway", "gateways\Lion.AbpPro.WebGateway\Lion.AbpPro.WebGateway.csproj", "{D9108313-8D05-4F5F-9AA0-B443EC3374B6}" |
||||
|
EndProject |
||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lion.AbpPro.Extension", "frameworks\Extensions\src\Lion.AbpPro.Extension\Lion.AbpPro.Extension.csproj", "{4C65690E-2C17-46A1-BB35-A51BAB2EA3B7}" |
||||
|
EndProject |
||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lion.AbpPro.CAP", "frameworks\CAP\src\Lion.AbpPro.CAP\Lion.AbpPro.CAP.csproj", "{3C3FF821-E43D-4D58-8B3C-1E97F4518EF7}" |
||||
|
EndProject |
||||
|
Global |
||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution |
||||
|
Debug|Any CPU = Debug|Any CPU |
||||
|
Release|Any CPU = Release|Any CPU |
||||
|
EndGlobalSection |
||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution |
||||
|
{554AD327-6DBA-4F8F-96F8-81CE7A0C863F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
||||
|
{554AD327-6DBA-4F8F-96F8-81CE7A0C863F}.Debug|Any CPU.Build.0 = Debug|Any CPU |
||||
|
{554AD327-6DBA-4F8F-96F8-81CE7A0C863F}.Release|Any CPU.ActiveCfg = Release|Any CPU |
||||
|
{554AD327-6DBA-4F8F-96F8-81CE7A0C863F}.Release|Any CPU.Build.0 = Release|Any CPU |
||||
|
{1A94A50E-06DC-43C1-80B5-B662820EC3EB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
||||
|
{1A94A50E-06DC-43C1-80B5-B662820EC3EB}.Debug|Any CPU.Build.0 = Debug|Any CPU |
||||
|
{1A94A50E-06DC-43C1-80B5-B662820EC3EB}.Release|Any CPU.ActiveCfg = Release|Any CPU |
||||
|
{1A94A50E-06DC-43C1-80B5-B662820EC3EB}.Release|Any CPU.Build.0 = Release|Any CPU |
||||
|
{C956DD76-69C8-4A9C-83EA-D17DF83340FD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
||||
|
{C956DD76-69C8-4A9C-83EA-D17DF83340FD}.Debug|Any CPU.Build.0 = Debug|Any CPU |
||||
|
{C956DD76-69C8-4A9C-83EA-D17DF83340FD}.Release|Any CPU.ActiveCfg = Release|Any CPU |
||||
|
{C956DD76-69C8-4A9C-83EA-D17DF83340FD}.Release|Any CPU.Build.0 = Release|Any CPU |
||||
|
{50B2631D-129C-47B3-A587-029CCD6099BC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
||||
|
{50B2631D-129C-47B3-A587-029CCD6099BC}.Debug|Any CPU.Build.0 = Debug|Any CPU |
||||
|
{50B2631D-129C-47B3-A587-029CCD6099BC}.Release|Any CPU.ActiveCfg = Release|Any CPU |
||||
|
{50B2631D-129C-47B3-A587-029CCD6099BC}.Release|Any CPU.Build.0 = Release|Any CPU |
||||
|
{42F719ED-8413-4895-B5B4-5AB56079BC66}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
||||
|
{42F719ED-8413-4895-B5B4-5AB56079BC66}.Debug|Any CPU.Build.0 = Debug|Any CPU |
||||
|
{42F719ED-8413-4895-B5B4-5AB56079BC66}.Release|Any CPU.ActiveCfg = Release|Any CPU |
||||
|
{42F719ED-8413-4895-B5B4-5AB56079BC66}.Release|Any CPU.Build.0 = Release|Any CPU |
||||
|
{520659C8-C734-4298-A3DA-B539DB9DFC0B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
||||
|
{520659C8-C734-4298-A3DA-B539DB9DFC0B}.Debug|Any CPU.Build.0 = Debug|Any CPU |
||||
|
{520659C8-C734-4298-A3DA-B539DB9DFC0B}.Release|Any CPU.ActiveCfg = Release|Any CPU |
||||
|
{520659C8-C734-4298-A3DA-B539DB9DFC0B}.Release|Any CPU.Build.0 = Release|Any CPU |
||||
|
{4164BDF7-F527-4E85-9CE6-E3C2D7426A27}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
||||
|
{4164BDF7-F527-4E85-9CE6-E3C2D7426A27}.Debug|Any CPU.Build.0 = Debug|Any CPU |
||||
|
{4164BDF7-F527-4E85-9CE6-E3C2D7426A27}.Release|Any CPU.ActiveCfg = Release|Any CPU |
||||
|
{4164BDF7-F527-4E85-9CE6-E3C2D7426A27}.Release|Any CPU.Build.0 = Release|Any CPU |
||||
|
{3B5A0094-670D-4BB1-BFDD-61B88A8773DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
||||
|
{3B5A0094-670D-4BB1-BFDD-61B88A8773DC}.Debug|Any CPU.Build.0 = Debug|Any CPU |
||||
|
{3B5A0094-670D-4BB1-BFDD-61B88A8773DC}.Release|Any CPU.ActiveCfg = Release|Any CPU |
||||
|
{3B5A0094-670D-4BB1-BFDD-61B88A8773DC}.Release|Any CPU.Build.0 = Release|Any CPU |
||||
|
{1FE30EB9-74A9-47F5-A9F6-7B1FAB672D81}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
||||
|
{1FE30EB9-74A9-47F5-A9F6-7B1FAB672D81}.Debug|Any CPU.Build.0 = Debug|Any CPU |
||||
|
{1FE30EB9-74A9-47F5-A9F6-7B1FAB672D81}.Release|Any CPU.ActiveCfg = Release|Any CPU |
||||
|
{1FE30EB9-74A9-47F5-A9F6-7B1FAB672D81}.Release|Any CPU.Build.0 = Release|Any CPU |
||||
|
{91853F21-9CD9-4132-BC29-A7D5D84FFFE7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
||||
|
{91853F21-9CD9-4132-BC29-A7D5D84FFFE7}.Debug|Any CPU.Build.0 = Debug|Any CPU |
||||
|
{91853F21-9CD9-4132-BC29-A7D5D84FFFE7}.Release|Any CPU.ActiveCfg = Release|Any CPU |
||||
|
{91853F21-9CD9-4132-BC29-A7D5D84FFFE7}.Release|Any CPU.Build.0 = Release|Any CPU |
||||
|
{E512F4D9-9375-480F-A2F6-A46509F9D824}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
||||
|
{E512F4D9-9375-480F-A2F6-A46509F9D824}.Debug|Any CPU.Build.0 = Debug|Any CPU |
||||
|
{E512F4D9-9375-480F-A2F6-A46509F9D824}.Release|Any CPU.ActiveCfg = Release|Any CPU |
||||
|
{E512F4D9-9375-480F-A2F6-A46509F9D824}.Release|Any CPU.Build.0 = Release|Any CPU |
||||
|
{EF480016-9127-4916-8735-D2466BDBC582}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
||||
|
{EF480016-9127-4916-8735-D2466BDBC582}.Debug|Any CPU.Build.0 = Debug|Any CPU |
||||
|
{EF480016-9127-4916-8735-D2466BDBC582}.Release|Any CPU.ActiveCfg = Release|Any CPU |
||||
|
{EF480016-9127-4916-8735-D2466BDBC582}.Release|Any CPU.Build.0 = Release|Any CPU |
||||
|
{AA94D832-1CCC-4715-95A9-A483F23A1A5D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
||||
|
{AA94D832-1CCC-4715-95A9-A483F23A1A5D}.Debug|Any CPU.Build.0 = Debug|Any CPU |
||||
|
{AA94D832-1CCC-4715-95A9-A483F23A1A5D}.Release|Any CPU.ActiveCfg = Release|Any CPU |
||||
|
{AA94D832-1CCC-4715-95A9-A483F23A1A5D}.Release|Any CPU.Build.0 = Release|Any CPU |
||||
|
{3E69D96A-F923-4AC4-8430-9AAB84B6A3FE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
||||
|
{3E69D96A-F923-4AC4-8430-9AAB84B6A3FE}.Debug|Any CPU.Build.0 = Debug|Any CPU |
||||
|
{3E69D96A-F923-4AC4-8430-9AAB84B6A3FE}.Release|Any CPU.ActiveCfg = Release|Any CPU |
||||
|
{3E69D96A-F923-4AC4-8430-9AAB84B6A3FE}.Release|Any CPU.Build.0 = Release|Any CPU |
||||
|
{F475DD35-9F27-43FF-9D96-365661ADC3C6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
||||
|
{F475DD35-9F27-43FF-9D96-365661ADC3C6}.Debug|Any CPU.Build.0 = Debug|Any CPU |
||||
|
{F475DD35-9F27-43FF-9D96-365661ADC3C6}.Release|Any CPU.ActiveCfg = Release|Any CPU |
||||
|
{F475DD35-9F27-43FF-9D96-365661ADC3C6}.Release|Any CPU.Build.0 = Release|Any CPU |
||||
|
{34B5BCF2-95C0-4136-AC9E-FC80D8ACBD1C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
||||
|
{34B5BCF2-95C0-4136-AC9E-FC80D8ACBD1C}.Debug|Any CPU.Build.0 = Debug|Any CPU |
||||
|
{34B5BCF2-95C0-4136-AC9E-FC80D8ACBD1C}.Release|Any CPU.ActiveCfg = Release|Any CPU |
||||
|
{34B5BCF2-95C0-4136-AC9E-FC80D8ACBD1C}.Release|Any CPU.Build.0 = Release|Any CPU |
||||
|
{4ADEEE7D-7886-4F85-BAA2-CCEE6E30EBFD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
||||
|
{4ADEEE7D-7886-4F85-BAA2-CCEE6E30EBFD}.Debug|Any CPU.Build.0 = Debug|Any CPU |
||||
|
{4ADEEE7D-7886-4F85-BAA2-CCEE6E30EBFD}.Release|Any CPU.ActiveCfg = Release|Any CPU |
||||
|
{4ADEEE7D-7886-4F85-BAA2-CCEE6E30EBFD}.Release|Any CPU.Build.0 = Release|Any CPU |
||||
|
{10DF0925-A1EE-4B1C-AAF6-249C6D02424C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
||||
|
{10DF0925-A1EE-4B1C-AAF6-249C6D02424C}.Debug|Any CPU.Build.0 = Debug|Any CPU |
||||
|
{10DF0925-A1EE-4B1C-AAF6-249C6D02424C}.Release|Any CPU.ActiveCfg = Release|Any CPU |
||||
|
{10DF0925-A1EE-4B1C-AAF6-249C6D02424C}.Release|Any CPU.Build.0 = Release|Any CPU |
||||
|
{0880AA9C-0E45-43B3-B02A-093736CDD961}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
||||
|
{0880AA9C-0E45-43B3-B02A-093736CDD961}.Debug|Any CPU.Build.0 = Debug|Any CPU |
||||
|
{0880AA9C-0E45-43B3-B02A-093736CDD961}.Release|Any CPU.ActiveCfg = Release|Any CPU |
||||
|
{0880AA9C-0E45-43B3-B02A-093736CDD961}.Release|Any CPU.Build.0 = Release|Any CPU |
||||
|
{B3554E2E-7150-482F-A08F-DCB8BD166FED}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
||||
|
{B3554E2E-7150-482F-A08F-DCB8BD166FED}.Debug|Any CPU.Build.0 = Debug|Any CPU |
||||
|
{B3554E2E-7150-482F-A08F-DCB8BD166FED}.Release|Any CPU.ActiveCfg = Release|Any CPU |
||||
|
{B3554E2E-7150-482F-A08F-DCB8BD166FED}.Release|Any CPU.Build.0 = Release|Any CPU |
||||
|
{22A3A359-C6F4-4540-A61F-C8E94A73C95E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
||||
|
{22A3A359-C6F4-4540-A61F-C8E94A73C95E}.Debug|Any CPU.Build.0 = Debug|Any CPU |
||||
|
{22A3A359-C6F4-4540-A61F-C8E94A73C95E}.Release|Any CPU.ActiveCfg = Release|Any CPU |
||||
|
{22A3A359-C6F4-4540-A61F-C8E94A73C95E}.Release|Any CPU.Build.0 = Release|Any CPU |
||||
|
{FCE5BD62-F7C7-45EA-80DE-B4880C4A84C6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
||||
|
{FCE5BD62-F7C7-45EA-80DE-B4880C4A84C6}.Debug|Any CPU.Build.0 = Debug|Any CPU |
||||
|
{FCE5BD62-F7C7-45EA-80DE-B4880C4A84C6}.Release|Any CPU.ActiveCfg = Release|Any CPU |
||||
|
{FCE5BD62-F7C7-45EA-80DE-B4880C4A84C6}.Release|Any CPU.Build.0 = Release|Any CPU |
||||
|
{19A921F2-1587-4E94-A023-B81956874DAB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
||||
|
{19A921F2-1587-4E94-A023-B81956874DAB}.Debug|Any CPU.Build.0 = Debug|Any CPU |
||||
|
{19A921F2-1587-4E94-A023-B81956874DAB}.Release|Any CPU.ActiveCfg = Release|Any CPU |
||||
|
{19A921F2-1587-4E94-A023-B81956874DAB}.Release|Any CPU.Build.0 = Release|Any CPU |
||||
|
{91A3257D-0D1A-479D-8F3C-DBB1944802FE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
||||
|
{91A3257D-0D1A-479D-8F3C-DBB1944802FE}.Debug|Any CPU.Build.0 = Debug|Any CPU |
||||
|
{91A3257D-0D1A-479D-8F3C-DBB1944802FE}.Release|Any CPU.ActiveCfg = Release|Any CPU |
||||
|
{91A3257D-0D1A-479D-8F3C-DBB1944802FE}.Release|Any CPU.Build.0 = Release|Any CPU |
||||
|
{5E6550EA-D878-455C-8EF7-5382661C1D52}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
||||
|
{5E6550EA-D878-455C-8EF7-5382661C1D52}.Debug|Any CPU.Build.0 = Debug|Any CPU |
||||
|
{5E6550EA-D878-455C-8EF7-5382661C1D52}.Release|Any CPU.ActiveCfg = Release|Any CPU |
||||
|
{5E6550EA-D878-455C-8EF7-5382661C1D52}.Release|Any CPU.Build.0 = Release|Any CPU |
||||
|
{14CDCC5A-006A-41EC-8B48-F3EFAC842432}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
||||
|
{14CDCC5A-006A-41EC-8B48-F3EFAC842432}.Debug|Any CPU.Build.0 = Debug|Any CPU |
||||
|
{14CDCC5A-006A-41EC-8B48-F3EFAC842432}.Release|Any CPU.ActiveCfg = Release|Any CPU |
||||
|
{14CDCC5A-006A-41EC-8B48-F3EFAC842432}.Release|Any CPU.Build.0 = Release|Any CPU |
||||
|
{11C6A285-8BC0-44C9-9FAB-F93462C75ABC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
||||
|
{11C6A285-8BC0-44C9-9FAB-F93462C75ABC}.Debug|Any CPU.Build.0 = Debug|Any CPU |
||||
|
{11C6A285-8BC0-44C9-9FAB-F93462C75ABC}.Release|Any CPU.ActiveCfg = Release|Any CPU |
||||
|
{11C6A285-8BC0-44C9-9FAB-F93462C75ABC}.Release|Any CPU.Build.0 = Release|Any CPU |
||||
|
{C7EB7304-CADD-4F09-84AC-43123406B28F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
||||
|
{C7EB7304-CADD-4F09-84AC-43123406B28F}.Debug|Any CPU.Build.0 = Debug|Any CPU |
||||
|
{C7EB7304-CADD-4F09-84AC-43123406B28F}.Release|Any CPU.ActiveCfg = Release|Any CPU |
||||
|
{C7EB7304-CADD-4F09-84AC-43123406B28F}.Release|Any CPU.Build.0 = Release|Any CPU |
||||
|
{DE15C716-E1C3-4FC3-B976-7EA06EBF23F5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
||||
|
{DE15C716-E1C3-4FC3-B976-7EA06EBF23F5}.Debug|Any CPU.Build.0 = Debug|Any CPU |
||||
|
{DE15C716-E1C3-4FC3-B976-7EA06EBF23F5}.Release|Any CPU.ActiveCfg = Release|Any CPU |
||||
|
{DE15C716-E1C3-4FC3-B976-7EA06EBF23F5}.Release|Any CPU.Build.0 = Release|Any CPU |
||||
|
{430D3AF9-DCCF-4B6F-BFAF-1ECC2F0594A2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
||||
|
{430D3AF9-DCCF-4B6F-BFAF-1ECC2F0594A2}.Debug|Any CPU.Build.0 = Debug|Any CPU |
||||
|
{430D3AF9-DCCF-4B6F-BFAF-1ECC2F0594A2}.Release|Any CPU.ActiveCfg = Release|Any CPU |
||||
|
{430D3AF9-DCCF-4B6F-BFAF-1ECC2F0594A2}.Release|Any CPU.Build.0 = Release|Any CPU |
||||
|
{CC104C76-0CC6-453E-A49D-C4995B6EB72B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
||||
|
{CC104C76-0CC6-453E-A49D-C4995B6EB72B}.Debug|Any CPU.Build.0 = Debug|Any CPU |
||||
|
{CC104C76-0CC6-453E-A49D-C4995B6EB72B}.Release|Any CPU.ActiveCfg = Release|Any CPU |
||||
|
{CC104C76-0CC6-453E-A49D-C4995B6EB72B}.Release|Any CPU.Build.0 = Release|Any CPU |
||||
|
{13AF64F3-8962-4568-A0E1-833CCA1922D5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
||||
|
{13AF64F3-8962-4568-A0E1-833CCA1922D5}.Debug|Any CPU.Build.0 = Debug|Any CPU |
||||
|
{13AF64F3-8962-4568-A0E1-833CCA1922D5}.Release|Any CPU.ActiveCfg = Release|Any CPU |
||||
|
{13AF64F3-8962-4568-A0E1-833CCA1922D5}.Release|Any CPU.Build.0 = Release|Any CPU |
||||
|
{F9FADD90-8634-4B03-AC44-9F6C80B30E73}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
||||
|
{F9FADD90-8634-4B03-AC44-9F6C80B30E73}.Debug|Any CPU.Build.0 = Debug|Any CPU |
||||
|
{F9FADD90-8634-4B03-AC44-9F6C80B30E73}.Release|Any CPU.ActiveCfg = Release|Any CPU |
||||
|
{F9FADD90-8634-4B03-AC44-9F6C80B30E73}.Release|Any CPU.Build.0 = Release|Any CPU |
||||
|
{8BC28722-20CC-41BD-B183-4E33E94CA2A7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
||||
|
{8BC28722-20CC-41BD-B183-4E33E94CA2A7}.Debug|Any CPU.Build.0 = Debug|Any CPU |
||||
|
{8BC28722-20CC-41BD-B183-4E33E94CA2A7}.Release|Any CPU.ActiveCfg = Release|Any CPU |
||||
|
{8BC28722-20CC-41BD-B183-4E33E94CA2A7}.Release|Any CPU.Build.0 = Release|Any CPU |
||||
|
{6A398750-D7D8-43DC-8DF8-AA65C5766154}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
||||
|
{6A398750-D7D8-43DC-8DF8-AA65C5766154}.Debug|Any CPU.Build.0 = Debug|Any CPU |
||||
|
{6A398750-D7D8-43DC-8DF8-AA65C5766154}.Release|Any CPU.ActiveCfg = Release|Any CPU |
||||
|
{6A398750-D7D8-43DC-8DF8-AA65C5766154}.Release|Any CPU.Build.0 = Release|Any CPU |
||||
|
{8D196E3D-6F95-4793-B948-79669AF09017}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
||||
|
{8D196E3D-6F95-4793-B948-79669AF09017}.Debug|Any CPU.Build.0 = Debug|Any CPU |
||||
|
{8D196E3D-6F95-4793-B948-79669AF09017}.Release|Any CPU.ActiveCfg = Release|Any CPU |
||||
|
{8D196E3D-6F95-4793-B948-79669AF09017}.Release|Any CPU.Build.0 = Release|Any CPU |
||||
|
{FB20372D-6C96-4733-9AAC-12522F15CAA6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
||||
|
{FB20372D-6C96-4733-9AAC-12522F15CAA6}.Debug|Any CPU.Build.0 = Debug|Any CPU |
||||
|
{FB20372D-6C96-4733-9AAC-12522F15CAA6}.Release|Any CPU.ActiveCfg = Release|Any CPU |
||||
|
{FB20372D-6C96-4733-9AAC-12522F15CAA6}.Release|Any CPU.Build.0 = Release|Any CPU |
||||
|
{FB1C29FF-5467-4CF0-995D-5B3F931AB135}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
||||
|
{FB1C29FF-5467-4CF0-995D-5B3F931AB135}.Debug|Any CPU.Build.0 = Debug|Any CPU |
||||
|
{FB1C29FF-5467-4CF0-995D-5B3F931AB135}.Release|Any CPU.ActiveCfg = Release|Any CPU |
||||
|
{FB1C29FF-5467-4CF0-995D-5B3F931AB135}.Release|Any CPU.Build.0 = Release|Any CPU |
||||
|
{A091AE9B-3A1E-49AC-9AD5-D29310512A3D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
||||
|
{A091AE9B-3A1E-49AC-9AD5-D29310512A3D}.Debug|Any CPU.Build.0 = Debug|Any CPU |
||||
|
{A091AE9B-3A1E-49AC-9AD5-D29310512A3D}.Release|Any CPU.ActiveCfg = Release|Any CPU |
||||
|
{A091AE9B-3A1E-49AC-9AD5-D29310512A3D}.Release|Any CPU.Build.0 = Release|Any CPU |
||||
|
{C018EFF9-579E-43B3-9181-543BE95E2E03}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
||||
|
{C018EFF9-579E-43B3-9181-543BE95E2E03}.Debug|Any CPU.Build.0 = Debug|Any CPU |
||||
|
{C018EFF9-579E-43B3-9181-543BE95E2E03}.Release|Any CPU.ActiveCfg = Release|Any CPU |
||||
|
{C018EFF9-579E-43B3-9181-543BE95E2E03}.Release|Any CPU.Build.0 = Release|Any CPU |
||||
|
{D9108313-8D05-4F5F-9AA0-B443EC3374B6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
||||
|
{D9108313-8D05-4F5F-9AA0-B443EC3374B6}.Debug|Any CPU.Build.0 = Debug|Any CPU |
||||
|
{D9108313-8D05-4F5F-9AA0-B443EC3374B6}.Release|Any CPU.ActiveCfg = Release|Any CPU |
||||
|
{D9108313-8D05-4F5F-9AA0-B443EC3374B6}.Release|Any CPU.Build.0 = Release|Any CPU |
||||
|
{4C65690E-2C17-46A1-BB35-A51BAB2EA3B7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
||||
|
{4C65690E-2C17-46A1-BB35-A51BAB2EA3B7}.Debug|Any CPU.Build.0 = Debug|Any CPU |
||||
|
{4C65690E-2C17-46A1-BB35-A51BAB2EA3B7}.Release|Any CPU.ActiveCfg = Release|Any CPU |
||||
|
{4C65690E-2C17-46A1-BB35-A51BAB2EA3B7}.Release|Any CPU.Build.0 = Release|Any CPU |
||||
|
{3C3FF821-E43D-4D58-8B3C-1E97F4518EF7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
||||
|
{3C3FF821-E43D-4D58-8B3C-1E97F4518EF7}.Debug|Any CPU.Build.0 = Debug|Any CPU |
||||
|
{3C3FF821-E43D-4D58-8B3C-1E97F4518EF7}.Release|Any CPU.ActiveCfg = Release|Any CPU |
||||
|
{3C3FF821-E43D-4D58-8B3C-1E97F4518EF7}.Release|Any CPU.Build.0 = Release|Any CPU |
||||
|
EndGlobalSection |
||||
|
GlobalSection(SolutionProperties) = preSolution |
||||
|
HideSolutionNode = FALSE |
||||
|
EndGlobalSection |
||||
|
GlobalSection(NestedProjects) = preSolution |
||||
|
{554AD327-6DBA-4F8F-96F8-81CE7A0C863F} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0} |
||||
|
{1A94A50E-06DC-43C1-80B5-B662820EC3EB} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0} |
||||
|
{C956DD76-69C8-4A9C-83EA-D17DF83340FD} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0} |
||||
|
{CA9AC87F-097E-4F15-8393-4BC07735A5B0} = {2C861ADD-76E9-4B3B-8A3C-638EBB67D683} |
||||
|
{04DBDB01-70F4-4E06-B468-8F87850B22BE} = {2C861ADD-76E9-4B3B-8A3C-638EBB67D683} |
||||
|
{50B2631D-129C-47B3-A587-029CCD6099BC} = {04DBDB01-70F4-4E06-B468-8F87850B22BE} |
||||
|
{42F719ED-8413-4895-B5B4-5AB56079BC66} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0} |
||||
|
{520659C8-C734-4298-A3DA-B539DB9DFC0B} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0} |
||||
|
{4164BDF7-F527-4E85-9CE6-E3C2D7426A27} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0} |
||||
|
{3B5A0094-670D-4BB1-BFDD-61B88A8773DC} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0} |
||||
|
{1FE30EB9-74A9-47F5-A9F6-7B1FAB672D81} = {04DBDB01-70F4-4E06-B468-8F87850B22BE} |
||||
|
{91853F21-9CD9-4132-BC29-A7D5D84FFFE7} = {04DBDB01-70F4-4E06-B468-8F87850B22BE} |
||||
|
{E512F4D9-9375-480F-A2F6-A46509F9D824} = {04DBDB01-70F4-4E06-B468-8F87850B22BE} |
||||
|
{EF480016-9127-4916-8735-D2466BDBC582} = {04DBDB01-70F4-4E06-B468-8F87850B22BE} |
||||
|
{AA94D832-1CCC-4715-95A9-A483F23A1A5D} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0} |
||||
|
{9F5676A3-00DC-48B7-93D1-341C39E19BB9} = {CC2EBB07-A070-4158-AB37-A0C0BBAEA9F5} |
||||
|
{C4AC9352-C9F5-4096-8D73-13638232CFB9} = {9F5676A3-00DC-48B7-93D1-341C39E19BB9} |
||||
|
{EB2B8705-18E7-49E1-A565-93A6DE5570D5} = {F8A8EB2A-2D4B-464F-9A13-F8F7B6A8FAA3} |
||||
|
{E28AECBD-2904-477C-9817-C67312330A41} = {EB2B8705-18E7-49E1-A565-93A6DE5570D5} |
||||
|
{120FE15B-3E5C-4BFF-B874-F09235C9E1ED} = {EB2B8705-18E7-49E1-A565-93A6DE5570D5} |
||||
|
{3E69D96A-F923-4AC4-8430-9AAB84B6A3FE} = {E28AECBD-2904-477C-9817-C67312330A41} |
||||
|
{F475DD35-9F27-43FF-9D96-365661ADC3C6} = {E28AECBD-2904-477C-9817-C67312330A41} |
||||
|
{34B5BCF2-95C0-4136-AC9E-FC80D8ACBD1C} = {E28AECBD-2904-477C-9817-C67312330A41} |
||||
|
{4ADEEE7D-7886-4F85-BAA2-CCEE6E30EBFD} = {E28AECBD-2904-477C-9817-C67312330A41} |
||||
|
{10DF0925-A1EE-4B1C-AAF6-249C6D02424C} = {E28AECBD-2904-477C-9817-C67312330A41} |
||||
|
{0880AA9C-0E45-43B3-B02A-093736CDD961} = {E28AECBD-2904-477C-9817-C67312330A41} |
||||
|
{B3554E2E-7150-482F-A08F-DCB8BD166FED} = {E28AECBD-2904-477C-9817-C67312330A41} |
||||
|
{22A3A359-C6F4-4540-A61F-C8E94A73C95E} = {120FE15B-3E5C-4BFF-B874-F09235C9E1ED} |
||||
|
{FCE5BD62-F7C7-45EA-80DE-B4880C4A84C6} = {120FE15B-3E5C-4BFF-B874-F09235C9E1ED} |
||||
|
{19A921F2-1587-4E94-A023-B81956874DAB} = {120FE15B-3E5C-4BFF-B874-F09235C9E1ED} |
||||
|
{91A3257D-0D1A-479D-8F3C-DBB1944802FE} = {120FE15B-3E5C-4BFF-B874-F09235C9E1ED} |
||||
|
{9C53260A-6F4B-4106-98B0-EDCC10BB3E1A} = {F8A8EB2A-2D4B-464F-9A13-F8F7B6A8FAA3} |
||||
|
{D1CFD035-1562-42CF-A96A-0E2EA8D92E80} = {9C53260A-6F4B-4106-98B0-EDCC10BB3E1A} |
||||
|
{E76E35FC-B62E-48D5-A7AF-79375CFD20BD} = {9C53260A-6F4B-4106-98B0-EDCC10BB3E1A} |
||||
|
{5E6550EA-D878-455C-8EF7-5382661C1D52} = {D1CFD035-1562-42CF-A96A-0E2EA8D92E80} |
||||
|
{14CDCC5A-006A-41EC-8B48-F3EFAC842432} = {D1CFD035-1562-42CF-A96A-0E2EA8D92E80} |
||||
|
{11C6A285-8BC0-44C9-9FAB-F93462C75ABC} = {D1CFD035-1562-42CF-A96A-0E2EA8D92E80} |
||||
|
{C7EB7304-CADD-4F09-84AC-43123406B28F} = {D1CFD035-1562-42CF-A96A-0E2EA8D92E80} |
||||
|
{DE15C716-E1C3-4FC3-B976-7EA06EBF23F5} = {D1CFD035-1562-42CF-A96A-0E2EA8D92E80} |
||||
|
{430D3AF9-DCCF-4B6F-BFAF-1ECC2F0594A2} = {D1CFD035-1562-42CF-A96A-0E2EA8D92E80} |
||||
|
{CC104C76-0CC6-453E-A49D-C4995B6EB72B} = {D1CFD035-1562-42CF-A96A-0E2EA8D92E80} |
||||
|
{13AF64F3-8962-4568-A0E1-833CCA1922D5} = {E76E35FC-B62E-48D5-A7AF-79375CFD20BD} |
||||
|
{F9FADD90-8634-4B03-AC44-9F6C80B30E73} = {E76E35FC-B62E-48D5-A7AF-79375CFD20BD} |
||||
|
{8BC28722-20CC-41BD-B183-4E33E94CA2A7} = {E76E35FC-B62E-48D5-A7AF-79375CFD20BD} |
||||
|
{6A398750-D7D8-43DC-8DF8-AA65C5766154} = {E76E35FC-B62E-48D5-A7AF-79375CFD20BD} |
||||
|
{5AACD0EE-F2B2-49F6-868F-8FE08D7243C0} = {9C53260A-6F4B-4106-98B0-EDCC10BB3E1A} |
||||
|
{8D196E3D-6F95-4793-B948-79669AF09017} = {5AACD0EE-F2B2-49F6-868F-8FE08D7243C0} |
||||
|
{8C1B8C6C-C518-4290-B070-622CCA6004DA} = {2C861ADD-76E9-4B3B-8A3C-638EBB67D683} |
||||
|
{2C09EED0-5AF6-4F1E-B05A-FB3272EDF6E8} = {CC2EBB07-A070-4158-AB37-A0C0BBAEA9F5} |
||||
|
{11ED8435-B5AE-4BF3-9D4B-51FA1E4A18A6} = {2C09EED0-5AF6-4F1E-B05A-FB3272EDF6E8} |
||||
|
{FB20372D-6C96-4733-9AAC-12522F15CAA6} = {8C1B8C6C-C518-4290-B070-622CCA6004DA} |
||||
|
{FB1C29FF-5467-4CF0-995D-5B3F931AB135} = {8C1B8C6C-C518-4290-B070-622CCA6004DA} |
||||
|
{A091AE9B-3A1E-49AC-9AD5-D29310512A3D} = {6434E3F2-B352-4B30-839A-88C2BA166D96} |
||||
|
{C018EFF9-579E-43B3-9181-543BE95E2E03} = {6434E3F2-B352-4B30-839A-88C2BA166D96} |
||||
|
{D9108313-8D05-4F5F-9AA0-B443EC3374B6} = {5C304CBC-F30D-413C-A0AF-8B6814A2D4A3} |
||||
|
{4C65690E-2C17-46A1-BB35-A51BAB2EA3B7} = {C4AC9352-C9F5-4096-8D73-13638232CFB9} |
||||
|
{3C3FF821-E43D-4D58-8B3C-1E97F4518EF7} = {11ED8435-B5AE-4BF3-9D4B-51FA1E4A18A6} |
||||
|
EndGlobalSection |
||||
|
GlobalSection(ExtensibilityGlobals) = postSolution |
||||
|
SolutionGuid = {28315BFD-90E7-4E14-A2EA-F3D23AF4126F} |
||||
|
EndGlobalSection |
||||
|
EndGlobal |
||||
@ -0,0 +1,23 @@ |
|||||
|
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation"> |
||||
|
<s:Boolean x:Key="/Default/CodeEditing/Intellisense/CodeCompletion/IntelliSenseCompletingCharacters/CSharpCompletingCharacters/UpgradedFromVSSettings/@EntryValue">True</s:Boolean> |
||||
|
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=EnforceDoWhileStatementBraces/@EntryIndexedValue">WARNING</s:String> |
||||
|
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=EnforceFixedStatementBraces/@EntryIndexedValue">WARNING</s:String> |
||||
|
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=EnforceForeachStatementBraces/@EntryIndexedValue">WARNING</s:String> |
||||
|
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=EnforceForStatementBraces/@EntryIndexedValue">WARNING</s:String> |
||||
|
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=EnforceIfStatementBraces/@EntryIndexedValue">WARNING</s:String> |
||||
|
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=EnforceLockStatementBraces/@EntryIndexedValue">WARNING</s:String> |
||||
|
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=EnforceUsingStatementBraces/@EntryIndexedValue">WARNING</s:String> |
||||
|
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=EnforceWhileStatementBraces/@EntryIndexedValue">WARNING</s:String> |
||||
|
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/BRACES_FOR_FOR/@EntryValue">Required</s:String> |
||||
|
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/BRACES_FOR_FOREACH/@EntryValue">Required</s:String> |
||||
|
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/BRACES_FOR_IFELSE/@EntryValue">Required</s:String> |
||||
|
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/BRACES_FOR_WHILE/@EntryValue">Required</s:String> |
||||
|
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/BRACES_REDUNDANT/@EntryValue">False</s:Boolean> |
||||
|
<s:Boolean x:Key="/Default/CodeStyle/Generate/=Implementations/@KeyIndexDefined">True</s:Boolean> |
||||
|
<s:String x:Key="/Default/CodeStyle/Generate/=Implementations/Options/=Async/@EntryIndexedValue">False</s:String> |
||||
|
<s:String x:Key="/Default/CodeStyle/Generate/=Implementations/Options/=Mutable/@EntryIndexedValue">False</s:String> |
||||
|
<s:Boolean x:Key="/Default/CodeStyle/Generate/=Overrides/@KeyIndexDefined">True</s:Boolean> |
||||
|
<s:String x:Key="/Default/CodeStyle/Generate/=Overrides/Options/=Async/@EntryIndexedValue">False</s:String> |
||||
|
<s:String x:Key="/Default/CodeStyle/Generate/=Overrides/Options/=Mutable/@EntryIndexedValue">False</s:String> |
||||
|
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=SQL/@EntryIndexedValue">SQL</s:String> |
||||
|
</wpf:ResourceDictionary> |
||||
@ -1,18 +0,0 @@ |
|||||
<Project Sdk="Microsoft.NET.Sdk"> |
|
||||
|
|
||||
<Import Project="..\..\..\..\common.props" /> |
|
||||
<PropertyGroup> |
|
||||
<TargetFramework>net5.0</TargetFramework> |
|
||||
</PropertyGroup> |
|
||||
<ItemGroup> |
|
||||
<PackageReference Include="Savorboard.CAP.InMemoryMessageQueue" Version="5.1.1" /> |
|
||||
<PackageReference Include="Volo.Abp.Core" Version="$(AbpPackageVersion)" /> |
|
||||
<PackageReference Include="Volo.Abp.EventBus" Version="$(AbpPackageVersion)" /> |
|
||||
<PackageReference Include="DotNetCore.CAP" Version="$(DotNetCoreCAPVersion)" /> |
|
||||
<PackageReference Include="DotNetCore.CAP.MySql" Version="$(DotNetCoreCAPVersion)" /> |
|
||||
<PackageReference Include="DotNetCore.CAP.RabbitMQ" Version="$(DotNetCoreCAPVersion)" /> |
|
||||
<PackageReference Include="DotNetCore.CAP.Dashboard" Version="$(DotNetCoreCAPVersion)" /> |
|
||||
<PackageReference Include="DotNetCore.CAP.InMemoryStorage" Version="$(DotNetCoreCAPVersion)" /> |
|
||||
</ItemGroup> |
|
||||
|
|
||||
</Project> |
|
||||
@ -1,129 +0,0 @@ |
|||||
using System; |
|
||||
using System.Collections.Generic; |
|
||||
using System.Linq; |
|
||||
using System.Reflection; |
|
||||
using DotNetCore.CAP; |
|
||||
using DotNetCore.CAP.Internal; |
|
||||
using Microsoft.Extensions.DependencyInjection; |
|
||||
using Microsoft.Extensions.Options; |
|
||||
using Volo.Abp.DependencyInjection; |
|
||||
using Volo.Abp.EventBus; |
|
||||
using Volo.Abp.EventBus.Distributed; |
|
||||
|
|
||||
namespace CompanyName.ProjectName.CAP |
|
||||
{ |
|
||||
[Dependency(ServiceLifetime.Singleton, ReplaceServices = true)] |
|
||||
[ExposeServices(typeof(IConsumerServiceSelector))] |
|
||||
public class ProjectNameAbpCapConsumerServiceSelector : ConsumerServiceSelector |
|
||||
{ |
|
||||
protected AbpDistributedEventBusOptions AbpDistributedEventBusOptions { get; } |
|
||||
protected IServiceProvider ServiceProvider { get; } |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Creates a new <see cref="T:DotNetCore.CAP.Internal.ConsumerServiceSelector" />.
|
|
||||
/// </summary>
|
|
||||
public ProjectNameAbpCapConsumerServiceSelector( |
|
||||
IServiceProvider serviceProvider, |
|
||||
IOptions<AbpDistributedEventBusOptions> distributedEventBusOptions) |
|
||||
: base(serviceProvider) |
|
||||
{ |
|
||||
ServiceProvider = serviceProvider; |
|
||||
AbpDistributedEventBusOptions = distributedEventBusOptions.Value; |
|
||||
} |
|
||||
|
|
||||
protected override IEnumerable<ConsumerExecutorDescriptor> FindConsumersFromInterfaceTypes(IServiceProvider provider) |
|
||||
{ |
|
||||
var executorDescriptorList = base.FindConsumersFromInterfaceTypes(provider).ToList(); |
|
||||
|
|
||||
//handlers
|
|
||||
var handlers = AbpDistributedEventBusOptions.Handlers; |
|
||||
|
|
||||
foreach (var handler in handlers) |
|
||||
{ |
|
||||
var interfaces = handler.GetInterfaces(); |
|
||||
foreach (var @interface in interfaces) |
|
||||
{ |
|
||||
if (!typeof(IEventHandler).GetTypeInfo().IsAssignableFrom(@interface)) |
|
||||
{ |
|
||||
continue; |
|
||||
} |
|
||||
var genericArgs = @interface.GetGenericArguments(); |
|
||||
|
|
||||
if (genericArgs.Length != 1) |
|
||||
{ |
|
||||
continue; |
|
||||
} |
|
||||
|
|
||||
var descriptors = GetHandlerDescription(genericArgs[0], handler); |
|
||||
|
|
||||
foreach (var descriptor in descriptors) |
|
||||
{ |
|
||||
var count = executorDescriptorList.Count(x => |
|
||||
x.Attribute.Name == descriptor.Attribute.Name); |
|
||||
|
|
||||
descriptor.Attribute.Group = descriptor.Attribute.Group.Insert( |
|
||||
descriptor.Attribute.Group.LastIndexOf(".", StringComparison.Ordinal), $".{count}"); |
|
||||
|
|
||||
executorDescriptorList.Add(descriptor); |
|
||||
} |
|
||||
|
|
||||
//Subscribe(genericArgs[0], new IocEventHandlerFactory(ServiceScopeFactory, handler));
|
|
||||
} |
|
||||
} |
|
||||
return executorDescriptorList; |
|
||||
} |
|
||||
|
|
||||
protected virtual IEnumerable<ConsumerExecutorDescriptor> GetHandlerDescription(Type eventType,Type typeInfo) |
|
||||
{ |
|
||||
var serviceTypeInfo = typeof(IDistributedEventHandler<>) |
|
||||
.MakeGenericType(eventType); |
|
||||
var method = typeInfo |
|
||||
.GetMethod( |
|
||||
nameof(IDistributedEventHandler<object>.HandleEventAsync), |
|
||||
new[] { eventType } |
|
||||
); |
|
||||
var eventName = EventNameAttribute.GetNameOrDefault(eventType); |
|
||||
var topicAttr = method.GetCustomAttributes<TopicAttribute>(true); |
|
||||
var topicAttributes = topicAttr.ToList(); |
|
||||
|
|
||||
if (topicAttributes.Count == 0) |
|
||||
{ |
|
||||
topicAttributes.Add(new CapSubscribeAttribute(eventName)); |
|
||||
} |
|
||||
|
|
||||
foreach (var attr in topicAttributes) |
|
||||
{ |
|
||||
SetSubscribeAttribute(attr); |
|
||||
|
|
||||
var parameters = method.GetParameters() |
|
||||
.Select(parameter => new ParameterDescriptor |
|
||||
{ |
|
||||
Name = parameter.Name, |
|
||||
ParameterType = parameter.ParameterType, |
|
||||
IsFromCap = parameter.GetCustomAttributes(typeof(FromCapAttribute)).Any() |
|
||||
}).ToList(); |
|
||||
|
|
||||
yield return InitDescriptor(attr, method, typeInfo.GetTypeInfo(), serviceTypeInfo.GetTypeInfo(), parameters); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
private static ConsumerExecutorDescriptor InitDescriptor( |
|
||||
TopicAttribute attr, |
|
||||
MethodInfo methodInfo, |
|
||||
TypeInfo implType, |
|
||||
TypeInfo serviceTypeInfo, |
|
||||
IList<ParameterDescriptor> parameters) |
|
||||
{ |
|
||||
var descriptor = new ConsumerExecutorDescriptor |
|
||||
{ |
|
||||
Attribute = attr, |
|
||||
MethodInfo = methodInfo, |
|
||||
ImplTypeInfo = implType, |
|
||||
ServiceTypeInfo = serviceTypeInfo, |
|
||||
Parameters = parameters |
|
||||
}; |
|
||||
|
|
||||
return descriptor; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,155 +0,0 @@ |
|||||
using System; |
|
||||
using System.Collections.Concurrent; |
|
||||
using System.Collections.Generic; |
|
||||
using System.Linq; |
|
||||
using System.Threading.Tasks; |
|
||||
using DotNetCore.CAP; |
|
||||
using Microsoft.Extensions.DependencyInjection; |
|
||||
using Microsoft.Extensions.Options; |
|
||||
using Volo.Abp; |
|
||||
using Volo.Abp.DependencyInjection; |
|
||||
using Volo.Abp.EventBus; |
|
||||
using Volo.Abp.EventBus.Distributed; |
|
||||
using Volo.Abp.MultiTenancy; |
|
||||
using Volo.Abp.Threading; |
|
||||
|
|
||||
namespace CompanyName.ProjectName.CAP |
|
||||
{ |
|
||||
public class ProjectNameAbpCapDistributedEventBus : |
|
||||
EventBusBase, |
|
||||
IDistributedEventBus, |
|
||||
ISingletonDependency |
|
||||
{ |
|
||||
protected AbpDistributedEventBusOptions AbpDistributedEventBusOptions { get; } |
|
||||
protected ConcurrentDictionary<Type, List<IEventHandlerFactory>> HandlerFactories { get; } |
|
||||
protected ConcurrentDictionary<string, Type> EventTypes { get; } |
|
||||
|
|
||||
protected readonly ICapPublisher CapPublisher; |
|
||||
|
|
||||
public ProjectNameAbpCapDistributedEventBus(IServiceScopeFactory serviceScopeFactory, |
|
||||
IOptions<AbpDistributedEventBusOptions> distributedEventBusOptions, |
|
||||
ICapPublisher capPublisher, |
|
||||
ICurrentTenant currentTenant, |
|
||||
IEventErrorHandler errorHandler) |
|
||||
: base(serviceScopeFactory, currentTenant, errorHandler) |
|
||||
{ |
|
||||
CapPublisher = capPublisher; |
|
||||
AbpDistributedEventBusOptions = distributedEventBusOptions.Value; |
|
||||
HandlerFactories = new ConcurrentDictionary<Type, List<IEventHandlerFactory>>(); |
|
||||
EventTypes = new ConcurrentDictionary<string, Type>(); |
|
||||
} |
|
||||
|
|
||||
public override IDisposable Subscribe(Type eventType, IEventHandlerFactory factory) |
|
||||
{ |
|
||||
//This is handled by CAP ConsumerServiceSelector
|
|
||||
throw new NotImplementedException(); |
|
||||
} |
|
||||
|
|
||||
public override void Unsubscribe<TEvent>(Func<TEvent, Task> action) |
|
||||
{ |
|
||||
Check.NotNull(action, nameof(action)); |
|
||||
|
|
||||
GetOrCreateHandlerFactories(typeof(TEvent)) |
|
||||
.Locking(factories => |
|
||||
{ |
|
||||
factories.RemoveAll( |
|
||||
factory => |
|
||||
{ |
|
||||
var singleInstanceFactory = factory as SingleInstanceHandlerFactory; |
|
||||
if (singleInstanceFactory == null) |
|
||||
{ |
|
||||
return false; |
|
||||
} |
|
||||
|
|
||||
var actionHandler = singleInstanceFactory.HandlerInstance as ActionEventHandler<TEvent>; |
|
||||
if (actionHandler == null) |
|
||||
{ |
|
||||
return false; |
|
||||
} |
|
||||
|
|
||||
return actionHandler.Action == action; |
|
||||
}); |
|
||||
}); |
|
||||
} |
|
||||
|
|
||||
public override void Unsubscribe(Type eventType, IEventHandler handler) |
|
||||
{ |
|
||||
GetOrCreateHandlerFactories(eventType) |
|
||||
.Locking(factories => |
|
||||
{ |
|
||||
factories.RemoveAll( |
|
||||
factory => |
|
||||
factory is SingleInstanceHandlerFactory && |
|
||||
(factory as SingleInstanceHandlerFactory).HandlerInstance == handler |
|
||||
); |
|
||||
}); |
|
||||
} |
|
||||
|
|
||||
public override void Unsubscribe(Type eventType, IEventHandlerFactory factory) |
|
||||
{ |
|
||||
GetOrCreateHandlerFactories(eventType).Locking(factories => factories.Remove(factory)); |
|
||||
} |
|
||||
|
|
||||
public override void UnsubscribeAll(Type eventType) |
|
||||
{ |
|
||||
GetOrCreateHandlerFactories(eventType).Locking(factories => factories.Clear()); |
|
||||
} |
|
||||
|
|
||||
public IDisposable Subscribe<TEvent>(IDistributedEventHandler<TEvent> handler) where TEvent : class |
|
||||
{ |
|
||||
return Subscribe(typeof(TEvent), handler); |
|
||||
} |
|
||||
|
|
||||
|
|
||||
public override async Task PublishAsync(Type eventType, object eventData) |
|
||||
{ |
|
||||
var eventName = EventNameAttribute.GetNameOrDefault(eventType); |
|
||||
await CapPublisher.PublishAsync(eventName, eventData); |
|
||||
} |
|
||||
|
|
||||
protected override IEnumerable<EventTypeWithEventHandlerFactories> GetHandlerFactories(Type eventType) |
|
||||
{ |
|
||||
var handlerFactoryList = new List<EventTypeWithEventHandlerFactories>(); |
|
||||
|
|
||||
foreach (var handlerFactory in |
|
||||
HandlerFactories.Where(hf => ShouldTriggerEventForHandler(eventType, hf.Key))) |
|
||||
{ |
|
||||
handlerFactoryList.Add( |
|
||||
new EventTypeWithEventHandlerFactories(handlerFactory.Key, handlerFactory.Value)); |
|
||||
} |
|
||||
|
|
||||
return handlerFactoryList.ToArray(); |
|
||||
} |
|
||||
|
|
||||
private List<IEventHandlerFactory> GetOrCreateHandlerFactories(Type eventType) |
|
||||
{ |
|
||||
return HandlerFactories.GetOrAdd( |
|
||||
eventType, |
|
||||
type => |
|
||||
{ |
|
||||
var eventName = EventNameAttribute.GetNameOrDefault(type); |
|
||||
EventTypes[eventName] = type; |
|
||||
return new List<IEventHandlerFactory>(); |
|
||||
} |
|
||||
); |
|
||||
} |
|
||||
|
|
||||
private static bool ShouldTriggerEventForHandler(Type targetEventType, Type handlerEventType) |
|
||||
{ |
|
||||
//Should trigger same type
|
|
||||
if (handlerEventType == targetEventType) |
|
||||
{ |
|
||||
return true; |
|
||||
} |
|
||||
|
|
||||
//TODO: Support inheritance? But it does not support on subscription to RabbitMq!
|
|
||||
//Should trigger for inherited types
|
|
||||
if (handlerEventType.IsAssignableFrom(targetEventType)) |
|
||||
{ |
|
||||
return true; |
|
||||
} |
|
||||
|
|
||||
return false; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,10 +0,0 @@ |
|||||
using Volo.Abp.EventBus; |
|
||||
using Volo.Abp.Modularity; |
|
||||
|
|
||||
namespace CompanyName.ProjectName.CAP |
|
||||
{ |
|
||||
[DependsOn(typeof(AbpEventBusModule))] |
|
||||
public class ProjectNameAbpCapModule : AbpModule |
|
||||
{ |
|
||||
} |
|
||||
} |
|
||||
@ -1,22 +0,0 @@ |
|||||
using System; |
|
||||
using DotNetCore.CAP; |
|
||||
using DotNetCore.CAP.Internal; |
|
||||
using Microsoft.Extensions.DependencyInjection; |
|
||||
using Volo.Abp.EventBus.Distributed; |
|
||||
using Volo.Abp.Modularity; |
|
||||
|
|
||||
namespace CompanyName.ProjectName.CAP |
|
||||
{ |
|
||||
public static class ProjectNameAbpCapServiceCollectionExtensions |
|
||||
{ |
|
||||
public static ServiceConfigurationContext AddAbpCap( |
|
||||
this ServiceConfigurationContext context, |
|
||||
Action<CapOptions> capAction) |
|
||||
{ |
|
||||
context.Services.AddCap(capAction); |
|
||||
context.Services.AddSingleton<IConsumerServiceSelector, ProjectNameAbpCapConsumerServiceSelector>(); |
|
||||
context.Services.AddSingleton<IDistributedEventBus, ProjectNameAbpCapDistributedEventBus>(); |
|
||||
return context; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,129 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using System.Reflection; |
||||
|
using DotNetCore.CAP; |
||||
|
using DotNetCore.CAP.Internal; |
||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
using Microsoft.Extensions.Options; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
using Volo.Abp.EventBus; |
||||
|
using Volo.Abp.EventBus.Distributed; |
||||
|
|
||||
|
namespace Lion.AbpPro.CAP |
||||
|
{ |
||||
|
[Dependency(ServiceLifetime.Singleton, ReplaceServices = true)] |
||||
|
[ExposeServices(typeof(IConsumerServiceSelector))] |
||||
|
public class AbpProAbpCapConsumerServiceSelector : ConsumerServiceSelector |
||||
|
{ |
||||
|
protected AbpDistributedEventBusOptions AbpDistributedEventBusOptions { get; } |
||||
|
protected IServiceProvider ServiceProvider { get; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Creates a new <see cref="T:DotNetCore.CAP.Internal.ConsumerServiceSelector" />.
|
||||
|
/// </summary>
|
||||
|
public AbpProAbpCapConsumerServiceSelector( |
||||
|
IServiceProvider serviceProvider, |
||||
|
IOptions<AbpDistributedEventBusOptions> distributedEventBusOptions) |
||||
|
: base(serviceProvider) |
||||
|
{ |
||||
|
ServiceProvider = serviceProvider; |
||||
|
AbpDistributedEventBusOptions = distributedEventBusOptions.Value; |
||||
|
} |
||||
|
|
||||
|
protected override IEnumerable<ConsumerExecutorDescriptor> FindConsumersFromInterfaceTypes(IServiceProvider provider) |
||||
|
{ |
||||
|
var executorDescriptorList = base.FindConsumersFromInterfaceTypes(provider).ToList(); |
||||
|
|
||||
|
//handlers
|
||||
|
var handlers = AbpDistributedEventBusOptions.Handlers; |
||||
|
|
||||
|
foreach (var handler in handlers) |
||||
|
{ |
||||
|
var interfaces = handler.GetInterfaces(); |
||||
|
foreach (var @interface in interfaces) |
||||
|
{ |
||||
|
if (!typeof(IEventHandler).GetTypeInfo().IsAssignableFrom(@interface)) |
||||
|
{ |
||||
|
continue; |
||||
|
} |
||||
|
var genericArgs = @interface.GetGenericArguments(); |
||||
|
|
||||
|
if (genericArgs.Length != 1) |
||||
|
{ |
||||
|
continue; |
||||
|
} |
||||
|
|
||||
|
var descriptors = GetHandlerDescription(genericArgs[0], handler); |
||||
|
|
||||
|
foreach (var descriptor in descriptors) |
||||
|
{ |
||||
|
var count = executorDescriptorList.Count(x => |
||||
|
x.Attribute.Name == descriptor.Attribute.Name); |
||||
|
|
||||
|
descriptor.Attribute.Group = descriptor.Attribute.Group.Insert( |
||||
|
descriptor.Attribute.Group.LastIndexOf(".", StringComparison.Ordinal), $".{count}"); |
||||
|
|
||||
|
executorDescriptorList.Add(descriptor); |
||||
|
} |
||||
|
|
||||
|
//Subscribe(genericArgs[0], new IocEventHandlerFactory(ServiceScopeFactory, handler));
|
||||
|
} |
||||
|
} |
||||
|
return executorDescriptorList; |
||||
|
} |
||||
|
|
||||
|
protected virtual IEnumerable<ConsumerExecutorDescriptor> GetHandlerDescription(Type eventType,Type typeInfo) |
||||
|
{ |
||||
|
var serviceTypeInfo = typeof(IDistributedEventHandler<>) |
||||
|
.MakeGenericType(eventType); |
||||
|
var method = typeInfo |
||||
|
.GetMethod( |
||||
|
nameof(IDistributedEventHandler<object>.HandleEventAsync), |
||||
|
new[] { eventType } |
||||
|
); |
||||
|
var eventName = EventNameAttribute.GetNameOrDefault(eventType); |
||||
|
var topicAttr = method.GetCustomAttributes<TopicAttribute>(true); |
||||
|
var topicAttributes = topicAttr.ToList(); |
||||
|
|
||||
|
if (topicAttributes.Count == 0) |
||||
|
{ |
||||
|
topicAttributes.Add(new CapSubscribeAttribute(eventName)); |
||||
|
} |
||||
|
|
||||
|
foreach (var attr in topicAttributes) |
||||
|
{ |
||||
|
SetSubscribeAttribute(attr); |
||||
|
|
||||
|
var parameters = method.GetParameters() |
||||
|
.Select(parameter => new ParameterDescriptor |
||||
|
{ |
||||
|
Name = parameter.Name, |
||||
|
ParameterType = parameter.ParameterType, |
||||
|
IsFromCap = parameter.GetCustomAttributes(typeof(FromCapAttribute)).Any() |
||||
|
}).ToList(); |
||||
|
|
||||
|
yield return InitDescriptor(attr, method, typeInfo.GetTypeInfo(), serviceTypeInfo.GetTypeInfo(), parameters); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private static ConsumerExecutorDescriptor InitDescriptor( |
||||
|
TopicAttribute attr, |
||||
|
MethodInfo methodInfo, |
||||
|
TypeInfo implType, |
||||
|
TypeInfo serviceTypeInfo, |
||||
|
IList<ParameterDescriptor> parameters) |
||||
|
{ |
||||
|
var descriptor = new ConsumerExecutorDescriptor |
||||
|
{ |
||||
|
Attribute = attr, |
||||
|
MethodInfo = methodInfo, |
||||
|
ImplTypeInfo = implType, |
||||
|
ServiceTypeInfo = serviceTypeInfo, |
||||
|
Parameters = parameters |
||||
|
}; |
||||
|
|
||||
|
return descriptor; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,177 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Concurrent; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using System.Threading.Tasks; |
||||
|
using DotNetCore.CAP; |
||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
using Microsoft.Extensions.Options; |
||||
|
using Volo.Abp; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
using Volo.Abp.EventBus; |
||||
|
using Volo.Abp.EventBus.Distributed; |
||||
|
using Volo.Abp.MultiTenancy; |
||||
|
using Volo.Abp.Threading; |
||||
|
using Volo.Abp.Uow; |
||||
|
|
||||
|
namespace Lion.AbpPro.CAP |
||||
|
{ |
||||
|
public class AbpProAbpCapDistributedEventBus : |
||||
|
EventBusBase, |
||||
|
IDistributedEventBus, |
||||
|
ISingletonDependency |
||||
|
{ |
||||
|
private AbpDistributedEventBusOptions AbpDistributedEventBusOptions { get; } |
||||
|
private ConcurrentDictionary<Type, List<IEventHandlerFactory>> HandlerFactories { get; } |
||||
|
private ConcurrentDictionary<string, Type> EventTypes { get; } |
||||
|
|
||||
|
private readonly ICapPublisher CapPublisher; |
||||
|
|
||||
|
private readonly UnitOfWorkManager _unitOfWorkManager; |
||||
|
|
||||
|
public AbpProAbpCapDistributedEventBus(IServiceScopeFactory serviceScopeFactory, |
||||
|
IOptions<AbpDistributedEventBusOptions> distributedEventBusOptions, |
||||
|
ICapPublisher capPublisher, |
||||
|
ICurrentTenant currentTenant, UnitOfWorkManager unitOfWorkManager) |
||||
|
: base(serviceScopeFactory, currentTenant,unitOfWorkManager) |
||||
|
{ |
||||
|
CapPublisher = capPublisher; |
||||
|
_unitOfWorkManager = unitOfWorkManager; |
||||
|
AbpDistributedEventBusOptions = distributedEventBusOptions.Value; |
||||
|
HandlerFactories = new ConcurrentDictionary<Type, List<IEventHandlerFactory>>(); |
||||
|
EventTypes = new ConcurrentDictionary<string, Type>(); |
||||
|
} |
||||
|
|
||||
|
public override IDisposable Subscribe(Type eventType, IEventHandlerFactory factory) |
||||
|
{ |
||||
|
//This is handled by CAP ConsumerServiceSelector
|
||||
|
throw new NotImplementedException(); |
||||
|
} |
||||
|
|
||||
|
public override void Unsubscribe<TEvent>(Func<TEvent, Task> action) |
||||
|
{ |
||||
|
Check.NotNull(action, nameof(action)); |
||||
|
|
||||
|
GetOrCreateHandlerFactories(typeof(TEvent)) |
||||
|
.Locking(factories => |
||||
|
{ |
||||
|
factories.RemoveAll( |
||||
|
factory => |
||||
|
{ |
||||
|
var singleInstanceFactory = factory as SingleInstanceHandlerFactory; |
||||
|
if (singleInstanceFactory == null) |
||||
|
{ |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
var actionHandler = singleInstanceFactory.HandlerInstance as ActionEventHandler<TEvent>; |
||||
|
if (actionHandler == null) |
||||
|
{ |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
return actionHandler.Action == action; |
||||
|
}); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
public override void Unsubscribe(Type eventType, IEventHandler handler) |
||||
|
{ |
||||
|
GetOrCreateHandlerFactories(eventType) |
||||
|
.Locking(factories => |
||||
|
{ |
||||
|
factories.RemoveAll( |
||||
|
factory => |
||||
|
factory is SingleInstanceHandlerFactory && |
||||
|
(factory as SingleInstanceHandlerFactory).HandlerInstance == handler |
||||
|
); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
public override void Unsubscribe(Type eventType, IEventHandlerFactory factory) |
||||
|
{ |
||||
|
GetOrCreateHandlerFactories(eventType).Locking(factories => factories.Remove(factory)); |
||||
|
} |
||||
|
|
||||
|
public override void UnsubscribeAll(Type eventType) |
||||
|
{ |
||||
|
GetOrCreateHandlerFactories(eventType).Locking(factories => factories.Clear()); |
||||
|
} |
||||
|
|
||||
|
protected override Task PublishToEventBusAsync(Type eventType, object eventData) |
||||
|
{ |
||||
|
throw new NotImplementedException(); |
||||
|
} |
||||
|
|
||||
|
protected override void AddToUnitOfWork(IUnitOfWork unitOfWork, UnitOfWorkEventRecord eventRecord) |
||||
|
{ |
||||
|
throw new NotImplementedException(); |
||||
|
} |
||||
|
|
||||
|
public IDisposable Subscribe<TEvent>(IDistributedEventHandler<TEvent> handler) where TEvent : class |
||||
|
{ |
||||
|
return Subscribe(typeof(TEvent), handler); |
||||
|
} |
||||
|
|
||||
|
public async Task PublishAsync<TEvent>(TEvent eventData, bool onUnitOfWorkComplete = true, |
||||
|
bool useOutbox = true) where TEvent : class |
||||
|
{ |
||||
|
var eventName = EventNameAttribute.GetNameOrDefault(typeof(TEvent)); |
||||
|
await CapPublisher.PublishAsync(eventName, eventData); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
public async Task PublishAsync(Type eventType, object eventData, bool onUnitOfWorkComplete = true, |
||||
|
bool useOutbox = true) |
||||
|
{ |
||||
|
var eventName = EventNameAttribute.GetNameOrDefault(eventType); |
||||
|
await CapPublisher.PublishAsync(eventName, eventData); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
protected override IEnumerable<EventTypeWithEventHandlerFactories> GetHandlerFactories(Type eventType) |
||||
|
{ |
||||
|
var handlerFactoryList = new List<EventTypeWithEventHandlerFactories>(); |
||||
|
|
||||
|
foreach (var handlerFactory in |
||||
|
HandlerFactories.Where(hf => ShouldTriggerEventForHandler(eventType, hf.Key))) |
||||
|
{ |
||||
|
handlerFactoryList.Add( |
||||
|
new EventTypeWithEventHandlerFactories(handlerFactory.Key, handlerFactory.Value)); |
||||
|
} |
||||
|
|
||||
|
return handlerFactoryList.ToArray(); |
||||
|
} |
||||
|
|
||||
|
private List<IEventHandlerFactory> GetOrCreateHandlerFactories(Type eventType) |
||||
|
{ |
||||
|
return HandlerFactories.GetOrAdd( |
||||
|
eventType, |
||||
|
type => |
||||
|
{ |
||||
|
var eventName = EventNameAttribute.GetNameOrDefault(type); |
||||
|
EventTypes[eventName] = type; |
||||
|
return new List<IEventHandlerFactory>(); |
||||
|
} |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
private static bool ShouldTriggerEventForHandler(Type targetEventType, Type handlerEventType) |
||||
|
{ |
||||
|
//Should trigger same type
|
||||
|
if (handlerEventType == targetEventType) |
||||
|
{ |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
//TODO: Support inheritance? But it does not support on subscription to RabbitMq!
|
||||
|
//Should trigger for inherited types
|
||||
|
if (handlerEventType.IsAssignableFrom(targetEventType)) |
||||
|
{ |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
return false; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,10 @@ |
|||||
|
using Volo.Abp.EventBus; |
||||
|
using Volo.Abp.Modularity; |
||||
|
|
||||
|
namespace Lion.AbpPro.CAP |
||||
|
{ |
||||
|
[DependsOn(typeof(AbpEventBusModule))] |
||||
|
public class AbpProAbpCapModule : AbpModule |
||||
|
{ |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,22 @@ |
|||||
|
using System; |
||||
|
using DotNetCore.CAP; |
||||
|
using DotNetCore.CAP.Internal; |
||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
using Volo.Abp.EventBus.Distributed; |
||||
|
using Volo.Abp.Modularity; |
||||
|
|
||||
|
namespace Lion.AbpPro.CAP |
||||
|
{ |
||||
|
public static class AbpProAbpCapServiceCollectionExtensions |
||||
|
{ |
||||
|
public static ServiceConfigurationContext AddAbpCap( |
||||
|
this ServiceConfigurationContext context, |
||||
|
Action<CapOptions> capAction) |
||||
|
{ |
||||
|
context.Services.AddCap(capAction); |
||||
|
context.Services.AddSingleton<IConsumerServiceSelector, AbpProAbpCapConsumerServiceSelector>(); |
||||
|
context.Services.AddSingleton<IDistributedEventBus, AbpProAbpCapDistributedEventBus>(); |
||||
|
return context; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,18 @@ |
|||||
|
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
|
||||
|
<Import Project="..\..\..\..\common.props" /> |
||||
|
<PropertyGroup> |
||||
|
<TargetFramework>net6.0</TargetFramework> |
||||
|
</PropertyGroup> |
||||
|
<ItemGroup> |
||||
|
<PackageReference Include="Savorboard.CAP.InMemoryMessageQueue" Version="5.1.1" /> |
||||
|
<PackageReference Include="Volo.Abp.Core" Version="$(AbpPackageVersion)" /> |
||||
|
<PackageReference Include="Volo.Abp.EventBus" Version="$(AbpPackageVersion)" /> |
||||
|
<PackageReference Include="DotNetCore.CAP" Version="$(DotNetCoreCAPVersion)" /> |
||||
|
<PackageReference Include="DotNetCore.CAP.MySql" Version="$(DotNetCoreCAPVersion)" /> |
||||
|
<PackageReference Include="DotNetCore.CAP.RabbitMQ" Version="$(DotNetCoreCAPVersion)" /> |
||||
|
<PackageReference Include="DotNetCore.CAP.Dashboard" Version="$(DotNetCoreCAPVersion)" /> |
||||
|
<PackageReference Include="DotNetCore.CAP.InMemoryStorage" Version="$(DotNetCoreCAPVersion)" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
</Project> |
||||
@ -1,20 +0,0 @@ |
|||||
<Project Sdk="Microsoft.NET.Sdk"> |
|
||||
|
|
||||
<Import Project="..\..\..\..\common.props" /> |
|
||||
<PropertyGroup> |
|
||||
<TargetFramework>net5.0</TargetFramework> |
|
||||
</PropertyGroup> |
|
||||
<ItemGroup> |
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyModel" Version="$(MicrosoftExtensionsDependencyModelVersion)" /> |
|
||||
<PackageReference Include="Microsoft.Extensions.Http" Version="$(MicrosoftExtensionsHttpVersion)" /> |
|
||||
<PackageReference Include="Newtonsoft.Json" Version="$(NewtonsoftJsonVersion)" /> |
|
||||
<PackageReference Include="System.ComponentModel.Annotations" Version="$(SystemComponentModelAnnotationsVersion)" /> |
|
||||
<PackageReference Include="Volo.Abp.Autofac" Version="$(AbpPackageVersion)" /> |
|
||||
<PackageReference Include="Volo.Abp.Json" Version="$(AbpPackageVersion)" /> |
|
||||
<PackageReference Include="Volo.Abp.Validation" Version="$(AbpPackageVersion)" /> |
|
||||
<PackageReference Include="Volo.Abp.Ddd.Domain" Version="$(AbpPackageVersion)" /> |
|
||||
<PackageReference Include="Volo.Abp.AutoMapper" Version="$(AbpPackageVersion)" /> |
|
||||
<PackageReference Include="Volo.Abp.ObjectMapping" Version="$(AbpPackageVersion)" /> |
|
||||
</ItemGroup> |
|
||||
|
|
||||
</Project> |
|
||||
@ -1,26 +0,0 @@ |
|||||
using System; |
|
||||
using System.Collections.Generic; |
|
||||
|
|
||||
namespace CompanyName.ProjectName.Extension.Customs.Dtos |
|
||||
{ |
|
||||
[Serializable] |
|
||||
public class CustomeListResultDto<T> |
|
||||
{ |
|
||||
public IReadOnlyList<T> Items |
|
||||
{ |
|
||||
get { return _items ??= new List<T>(); } |
|
||||
set => _items = value; |
|
||||
} |
|
||||
|
|
||||
private IReadOnlyList<T> _items; |
|
||||
|
|
||||
public CustomeListResultDto() |
|
||||
{ |
|
||||
} |
|
||||
|
|
||||
public CustomeListResultDto(IReadOnlyList<T> items) |
|
||||
{ |
|
||||
Items = items; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,21 +0,0 @@ |
|||||
using System; |
|
||||
using System.Collections.Generic; |
|
||||
|
|
||||
namespace CompanyName.ProjectName.Extension.Customs.Dtos |
|
||||
{ |
|
||||
[Serializable] |
|
||||
public class CustomePagedResultDto<T> : CustomeListResultDto<T> |
|
||||
{ |
|
||||
public long TotalCount { get; set; } |
|
||||
|
|
||||
public CustomePagedResultDto() |
|
||||
{ |
|
||||
} |
|
||||
|
|
||||
public CustomePagedResultDto(long totalCount, IReadOnlyList<T> items) |
|
||||
: base(items) |
|
||||
{ |
|
||||
TotalCount = totalCount; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,41 +0,0 @@ |
|||||
namespace CompanyName.ProjectName.Extension.Customs.Dtos |
|
||||
{ |
|
||||
|
|
||||
|
|
||||
public abstract class FromSelectorBase |
|
||||
{ |
|
||||
protected FromSelectorBase(int value, string label) |
|
||||
{ |
|
||||
Value = value; |
|
||||
Label = label; |
|
||||
} |
|
||||
public int Value { get; protected set; } |
|
||||
public string Label { get; protected set; } |
|
||||
} |
|
||||
|
|
||||
public abstract class FromSelectorBase<TValue, TLabel> |
|
||||
{ |
|
||||
protected FromSelectorBase(TValue value, TLabel label) |
|
||||
{ |
|
||||
Value = value; |
|
||||
Label = label; |
|
||||
} |
|
||||
|
|
||||
public TValue Value { get; protected set; } |
|
||||
public TLabel Label { get; protected set; } |
|
||||
} |
|
||||
|
|
||||
public class FromSelector : FromSelectorBase |
|
||||
{ |
|
||||
public FromSelector(int value, string label) : base(value, label) |
|
||||
{ |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public class FromSelector<TValue, TLabel> : FromSelectorBase<TValue, TLabel> |
|
||||
{ |
|
||||
public FromSelector(TValue value, TLabel label) : base(value, label) |
|
||||
{ |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,9 +0,0 @@ |
|||||
using System; |
|
||||
|
|
||||
namespace CompanyName.ProjectName.Extension.Customs.Dtos |
|
||||
{ |
|
||||
public class IdInput |
|
||||
{ |
|
||||
public Guid Id { get; set; } |
|
||||
} |
|
||||
} |
|
||||
@ -1,59 +0,0 @@ |
|||||
using System.Collections.Generic; |
|
||||
using System.ComponentModel.DataAnnotations; |
|
||||
|
|
||||
namespace CompanyName.ProjectName.Extension.Customs.Dtos |
|
||||
{ |
|
||||
|
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 分页查询时使用的Dto类型
|
|
||||
/// </summary>
|
|
||||
public class PagingBase : IValidatableObject |
|
||||
{ |
|
||||
public const int MaxPageSize = 100000; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 当前页面.默认从1开始
|
|
||||
/// </summary>
|
|
||||
public int PageIndex { get; set; } = 1; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 每页多少条.每页显示多少记录
|
|
||||
/// </summary>
|
|
||||
public int PageSize { get; set; } = 10; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 跳过多少条
|
|
||||
/// </summary>
|
|
||||
public int SkipCount => (PageIndex - 1) * PageSize; |
|
||||
|
|
||||
protected PagingBase() |
|
||||
{ |
|
||||
} |
|
||||
|
|
||||
public PagingBase(int pageIndex = 1, int pageSize = 10) |
|
||||
{ |
|
||||
PageIndex = pageIndex; |
|
||||
PageSize = pageSize; |
|
||||
} |
|
||||
|
|
||||
public virtual IEnumerable<ValidationResult> Validate(ValidationContext validationContext) |
|
||||
{ |
|
||||
if (PageIndex < 1) |
|
||||
{ |
|
||||
yield return new ValidationResult( |
|
||||
"起始页必须大于等于1", |
|
||||
new[] { "PageIndex"} |
|
||||
); |
|
||||
} |
|
||||
|
|
||||
if (PageSize > MaxPageSize) |
|
||||
{ |
|
||||
yield return new ValidationResult( |
|
||||
$"每页最大记录数不能超过'{MaxPageSize}'", |
|
||||
new[] { "PageSize"} |
|
||||
); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,271 +0,0 @@ |
|||||
using System; |
|
||||
using System.Collections.Generic; |
|
||||
using System.Diagnostics; |
|
||||
using System.IO; |
|
||||
using System.Linq; |
|
||||
|
|
||||
namespace CompanyName.ProjectName.Extension.Customs |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// 参数合法性检查类
|
|
||||
/// </summary>
|
|
||||
[DebuggerStepThrough] |
|
||||
public static class Guard |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// 检查参数不能为空引用,
|
|
||||
/// </summary>
|
|
||||
/// <param name="value"></param>
|
|
||||
/// <param name="valueName">参数名称</param>
|
|
||||
public static T NotNull<T>(T value, string valueName) |
|
||||
{ |
|
||||
if (null == value) |
|
||||
{ |
|
||||
throw new ArgumentNullException(valueName); |
|
||||
} |
|
||||
|
|
||||
return value; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 检查字符串不能为空引用或空字符串,
|
|
||||
/// </summary>
|
|
||||
/// <param name="value"></param>
|
|
||||
/// <param name="valueName">参数名称。</param>
|
|
||||
/// <param name="maxLength">字符串允许的最大长度。</param>
|
|
||||
/// <param name="minLength">字符串允许的最小长度。0表示不限制最小长度</param>
|
|
||||
public static string NotNullOrEmpty(string value, string valueName, int maxLength = int.MaxValue, |
|
||||
int minLength = 0) |
|
||||
{ |
|
||||
if (string.IsNullOrEmpty(value)) |
|
||||
{ |
|
||||
throw new ArgumentNullException(valueName); |
|
||||
} |
|
||||
|
|
||||
if (value.Length > maxLength) |
|
||||
{ |
|
||||
throw new ArgumentOutOfRangeException(valueName); |
|
||||
} |
|
||||
|
|
||||
if (minLength > 0 && value.Length < minLength) |
|
||||
{ |
|
||||
throw new ArgumentOutOfRangeException(valueName); |
|
||||
} |
|
||||
|
|
||||
return value; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 检查字符串不能为空引用或全部为空白,
|
|
||||
/// </summary>
|
|
||||
/// <param name="value">需检查的字符串</param>
|
|
||||
/// <param name="valueName">参数名称。</param>
|
|
||||
/// <param name="maxLength">字符串允许的最大长度。</param>
|
|
||||
/// <param name="minLength">字符串允许的最小长度。0表示不限制最小长度</param>
|
|
||||
public static string NotNullOrWhiteSpace( |
|
||||
string value, |
|
||||
string valueName, |
|
||||
int maxLength = int.MaxValue, |
|
||||
int minLength = 0) |
|
||||
{ |
|
||||
if (string.IsNullOrWhiteSpace(value)) |
|
||||
{ |
|
||||
throw new ArgumentNullException(valueName); |
|
||||
} |
|
||||
|
|
||||
if (value.Length > maxLength) |
|
||||
{ |
|
||||
throw new ArgumentOutOfRangeException(valueName); |
|
||||
} |
|
||||
|
|
||||
if (minLength > 0 && value.Length < minLength) |
|
||||
{ |
|
||||
throw new ArgumentOutOfRangeException(valueName); |
|
||||
} |
|
||||
|
|
||||
return value; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 检查字符串长度是否超过最大长度,或低于最小长度,
|
|
||||
/// </summary>
|
|
||||
/// <param name="value">需检查的字符串。</param>
|
|
||||
/// <param name="valueName">参数名称。</param>
|
|
||||
/// <param name="maxLength">字符串允许的最大长度。</param>
|
|
||||
/// <param name="minLength">字符串要求的最小长度。0表示不限制最小长度</param>
|
|
||||
public static string Length(string value, string valueName, int maxLength = int.MaxValue, |
|
||||
int minLength = 0) |
|
||||
{ |
|
||||
if (string.IsNullOrEmpty(value)) |
|
||||
{ |
|
||||
return value; |
|
||||
} |
|
||||
|
|
||||
if (value.Length > maxLength) |
|
||||
{ |
|
||||
throw new ArgumentOutOfRangeException(valueName); |
|
||||
} |
|
||||
|
|
||||
if (minLength > 0 && value.Length < minLength) |
|
||||
{ |
|
||||
throw new ArgumentOutOfRangeException(valueName); |
|
||||
} |
|
||||
|
|
||||
return value; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 检查Guid值不能为Guid.Empty
|
|
||||
/// </summary>
|
|
||||
/// <param name="value"></param>
|
|
||||
/// <param name="valueName">参数名称。</param>
|
|
||||
public static Guid NotEmpty( |
|
||||
Guid value, |
|
||||
string valueName) |
|
||||
{ |
|
||||
if (value == Guid.Empty) |
|
||||
{ |
|
||||
throw new ArgumentNullException(valueName); |
|
||||
} |
|
||||
|
|
||||
return value; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 检查集合不能为空引用或空集合,
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="T">集合项的类型。</typeparam>
|
|
||||
/// <param name="list"></param>
|
|
||||
/// <param name="valueName">参数名称。</param>
|
|
||||
public static void NotNullOrEmpty<T>( |
|
||||
IReadOnlyList<T> list, |
|
||||
string valueName) |
|
||||
{ |
|
||||
if (null == list || !list.Any()) |
|
||||
{ |
|
||||
throw new ArgumentNullException(valueName); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 检查参数必须小于[或可等于,参数<paramref name="canEqual"/>]指定值,
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="T">参数类型。</typeparam>
|
|
||||
/// <param name="value"></param>
|
|
||||
/// <param name="valueName">参数名称。</param>
|
|
||||
/// <param name="target">要比较的值。</param>
|
|
||||
/// <param name="canEqual">是否可等于。</param>
|
|
||||
public static void LessThan<T>( |
|
||||
T value, |
|
||||
string valueName, |
|
||||
T target, |
|
||||
bool canEqual = false) |
|
||||
where T : IComparable<T> |
|
||||
{ |
|
||||
var flag = canEqual ? value.CompareTo(target) <= 0 : value.CompareTo(target) < 0; |
|
||||
if (!flag) |
|
||||
{ |
|
||||
throw new ArgumentOutOfRangeException(valueName); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 检查参数必须大于[或可等于,参数<paramref name="canEqual"/>]指定值,
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="T">参数类型。</typeparam>
|
|
||||
/// <param name="value">需检查的参数。</param>
|
|
||||
/// <param name="valueName">参数名称。</param>
|
|
||||
/// <param name="target">要比较的值。</param>
|
|
||||
/// <param name="canEqual">是否可等于。</param>
|
|
||||
public static void GreaterThan<T>( |
|
||||
T value, |
|
||||
string valueName, |
|
||||
T target, |
|
||||
bool canEqual = false) |
|
||||
where T : IComparable<T> |
|
||||
{ |
|
||||
var flag = canEqual ? value.CompareTo(target) >= 0 : value.CompareTo(target) > 0; |
|
||||
if (!flag) |
|
||||
{ |
|
||||
throw new ArgumentOutOfRangeException(valueName); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 检查参数必须在指定范围之间
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="T">参数类型。</typeparam>
|
|
||||
/// <param name="value">需检查的参数。</param>
|
|
||||
/// <param name="valueName">参数名称。</param>
|
|
||||
/// <param name="start">比较范围的起始值。</param>
|
|
||||
/// <param name="end">比较范围的结束值。</param>
|
|
||||
/// <param name="startEqual">是否可等于起始值</param>
|
|
||||
/// <param name="endEqual">是否可等于结束值</param>
|
|
||||
public static void Between<T>( |
|
||||
T value, |
|
||||
string valueName, |
|
||||
T start, |
|
||||
T end, |
|
||||
bool startEqual = false, |
|
||||
bool endEqual = false) |
|
||||
where T : IComparable<T> |
|
||||
{ |
|
||||
var flag = startEqual ? value.CompareTo(start) >= 0 : value.CompareTo(start) > 0; |
|
||||
if (!flag) |
|
||||
{ |
|
||||
throw new ArgumentOutOfRangeException(valueName); |
|
||||
} |
|
||||
|
|
||||
flag = endEqual ? value.CompareTo(end) <= 0 : value.CompareTo(end) < 0; |
|
||||
if (!flag) |
|
||||
{ |
|
||||
throw new ArgumentOutOfRangeException(valueName); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 检查指定路径的文件夹必须存在,
|
|
||||
/// </summary>
|
|
||||
/// <param name="directory">需检查的路径。</param>
|
|
||||
/// <param name="parameterName">参数名称。</param>
|
|
||||
public static string DirectoryExists( |
|
||||
string directory, |
|
||||
string parameterName) |
|
||||
{ |
|
||||
if (string.IsNullOrWhiteSpace(directory)) |
|
||||
{ |
|
||||
throw new DirectoryNotFoundException(parameterName); |
|
||||
} |
|
||||
|
|
||||
if (!Directory.Exists(directory)) |
|
||||
{ |
|
||||
throw new DirectoryNotFoundException(directory); |
|
||||
} |
|
||||
|
|
||||
return directory; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 检查指定路径的文件必须存在,否则抛出
|
|
||||
/// </summary>
|
|
||||
/// <param name="filename"></param>
|
|
||||
/// <param name="valueName">参数名称。</param>
|
|
||||
|
|
||||
public static string FileExists( |
|
||||
string filename, |
|
||||
string valueName) |
|
||||
{ |
|
||||
if (string.IsNullOrWhiteSpace(filename)) |
|
||||
{ |
|
||||
throw new ArgumentNullException(valueName); |
|
||||
} |
|
||||
|
|
||||
if (!File.Exists(filename)) |
|
||||
{ |
|
||||
throw new FileNotFoundException(filename); |
|
||||
} |
|
||||
|
|
||||
return filename; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,164 +0,0 @@ |
|||||
using System; |
|
||||
using System.Collections.Generic; |
|
||||
using System.Net.Http; |
|
||||
using System.Net.Http.Headers; |
|
||||
using System.Text; |
|
||||
using System.Threading.Tasks; |
|
||||
using Newtonsoft.Json; |
|
||||
|
|
||||
namespace CompanyName.ProjectName.Extension.Customs.Http |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// 基于IHttpClientFactory二次封装httpclient
|
|
||||
/// </summary>
|
|
||||
public static class HttpClientHelper |
|
||||
{ |
|
||||
|
|
||||
public static async Task<TResult> GetAsync<TResult>(this IHttpClientFactory _httpClientFactory, string clientName, string url, Dictionary<string, string> headers = null) where TResult : class |
|
||||
{ |
|
||||
try |
|
||||
{ |
|
||||
var client = _httpClientFactory.CreateClient(clientName); |
|
||||
if (headers != null && headers.Count > 0) |
|
||||
{ |
|
||||
foreach (var item in headers) |
|
||||
{ |
|
||||
client.DefaultRequestHeaders.Add(item.Key, item.Value); |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
|
|
||||
client.DefaultRequestHeaders.CacheControl = CacheControlHeaderValue.Parse("no-cache"); |
|
||||
|
|
||||
//执行请求
|
|
||||
var response = await client.GetAsync(url); |
|
||||
var result = await response.Content.ReadAsStringAsync(); |
|
||||
if (response.IsSuccessStatusCode) |
|
||||
{ |
|
||||
if (result != null && !string.IsNullOrEmpty(result)) |
|
||||
return JsonConvert.DeserializeObject<TResult>(result); |
|
||||
else |
|
||||
return default(TResult); |
|
||||
} |
|
||||
else |
|
||||
{ |
|
||||
if (string.IsNullOrEmpty(result)) |
|
||||
result = response.ReasonPhrase; |
|
||||
throw new Exception(result); |
|
||||
} |
|
||||
} |
|
||||
catch (Exception e) |
|
||||
{ |
|
||||
throw new Exception(e.Message); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public static async Task<TResult> PostAsync<T, TResult>(this IHttpClientFactory _httpClientFactory, string clientName, string url, T obj, Dictionary<string, string> headers = null) where T : class where TResult : class |
|
||||
{ |
|
||||
var data = typeof(T).Name.ToLower() == "string" ? obj.ToString() : JsonConvert.SerializeObject(obj); |
|
||||
var client = _httpClientFactory.CreateClient(clientName); |
|
||||
if (headers != null && headers.Count > 0) |
|
||||
{ |
|
||||
foreach (var item in headers) |
|
||||
{ |
|
||||
client.DefaultRequestHeaders.Add(item.Key, item.Value); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
client.DefaultRequestHeaders.CacheControl = CacheControlHeaderValue.Parse("no-cache"); |
|
||||
//post 参数
|
|
||||
var content = new StringContent(data, Encoding.UTF8, "application/json"); |
|
||||
//执行请求
|
|
||||
var response = await client.PostAsync(url, content); |
|
||||
|
|
||||
var result = await response.Content.ReadAsStringAsync(); |
|
||||
if (response.IsSuccessStatusCode) |
|
||||
{ |
|
||||
if (result != null && !string.IsNullOrEmpty(result)) |
|
||||
return JsonConvert.DeserializeObject<TResult>(result); |
|
||||
else |
|
||||
return default(TResult); |
|
||||
} |
|
||||
else |
|
||||
{ |
|
||||
if (string.IsNullOrEmpty(result)) |
|
||||
result = response.ReasonPhrase; |
|
||||
|
|
||||
throw new Exception(result); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public static async Task<TResult> PutAsync<T, TResult>(this IHttpClientFactory _httpClientFactory, string clientName, string url, T obj, Dictionary<string, string> headers = null) where T : class where TResult : class |
|
||||
{ |
|
||||
var data = typeof(T).Name.ToLower() == "string" ? obj.ToString() : JsonConvert.SerializeObject(obj); |
|
||||
var client = _httpClientFactory.CreateClient(clientName); |
|
||||
if (headers != null && headers.Count > 0) |
|
||||
{ |
|
||||
foreach (var item in headers) |
|
||||
{ |
|
||||
client.DefaultRequestHeaders.Add(item.Key, item.Value); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
client.DefaultRequestHeaders.CacheControl = CacheControlHeaderValue.Parse("no-cache"); |
|
||||
//post 参数
|
|
||||
var content = new StringContent(data, Encoding.UTF8, "application/json"); |
|
||||
//执行请求
|
|
||||
var response = await client.PutAsync(url, content); |
|
||||
|
|
||||
var result = await response.Content.ReadAsStringAsync(); |
|
||||
if (response.IsSuccessStatusCode) |
|
||||
{ |
|
||||
if (result != null && !string.IsNullOrEmpty(result)) |
|
||||
return JsonConvert.DeserializeObject<TResult>(result); |
|
||||
else |
|
||||
return default(TResult); |
|
||||
} |
|
||||
else |
|
||||
{ |
|
||||
if (string.IsNullOrEmpty(result)) |
|
||||
result = response.ReasonPhrase; |
|
||||
|
|
||||
throw new Exception(result); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public static async Task<TResult> DeleteAsync<TResult>(this IHttpClientFactory _httpClientFactory, string clientName, string url, Dictionary<string, string> headers = null) where TResult : class |
|
||||
{ |
|
||||
try |
|
||||
{ |
|
||||
var client = _httpClientFactory.CreateClient(clientName); |
|
||||
if (headers != null && headers.Count > 0) |
|
||||
{ |
|
||||
foreach (var item in headers) |
|
||||
{ |
|
||||
client.DefaultRequestHeaders.Add(item.Key, item.Value); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
client.DefaultRequestHeaders.CacheControl = CacheControlHeaderValue.Parse("no-cache"); |
|
||||
|
|
||||
//执行请求
|
|
||||
var response = await client.DeleteAsync(url); |
|
||||
var result = await response.Content.ReadAsStringAsync(); |
|
||||
if (response.IsSuccessStatusCode) |
|
||||
{ |
|
||||
if (result != null && !string.IsNullOrEmpty(result)) |
|
||||
return JsonConvert.DeserializeObject<TResult>(result); |
|
||||
else |
|
||||
return default(TResult); |
|
||||
} |
|
||||
else |
|
||||
{ |
|
||||
if (string.IsNullOrEmpty(result)) |
|
||||
result = response.ReasonPhrase; |
|
||||
throw new Exception(result); |
|
||||
} |
|
||||
} |
|
||||
catch (Exception e) |
|
||||
{ |
|
||||
throw new Exception(e.Message); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,29 +0,0 @@ |
|||||
using System; |
|
||||
|
|
||||
namespace CompanyName.ProjectName.Extension.System |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// 布尔值<see cref="Boolean"/>类型的扩展辅助操作类
|
|
||||
/// </summary>
|
|
||||
public static class BooleanExtensions |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// 把布尔值转换为小写字符串
|
|
||||
/// </summary>
|
|
||||
public static string ToLower(this bool value) |
|
||||
{ |
|
||||
return value.ToString().ToLower(); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 如果条件成立,则抛出异常
|
|
||||
/// </summary>
|
|
||||
public static void TrueThrow(this bool flag, Exception exception) |
|
||||
{ |
|
||||
if (flag) |
|
||||
{ |
|
||||
throw exception; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,79 +0,0 @@ |
|||||
using System; |
|
||||
using System.Collections.Generic; |
|
||||
using System.Linq; |
|
||||
using CompanyName.ProjectName.Extension.Customs; |
|
||||
|
|
||||
namespace CompanyName.ProjectName.Extension.System.Collections.Generic |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// 集合扩展方法
|
|
||||
/// </summary>
|
|
||||
public static class CollectionExtensions |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// 如果条件成立,添加项
|
|
||||
/// </summary>
|
|
||||
public static void AddIf<T>(this ICollection<T> collection, T value, bool flag) |
|
||||
{ |
|
||||
Guard.NotNull(collection, nameof(collection)); |
|
||||
if (flag) |
|
||||
{ |
|
||||
collection.Add(value); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 如果条件成立,添加项
|
|
||||
/// </summary>
|
|
||||
public static void AddIf<T>(this ICollection<T> collection, T value, Func<bool> func) |
|
||||
{ |
|
||||
Guard.NotNull(collection, nameof(collection)); |
|
||||
if (func()) |
|
||||
{ |
|
||||
collection.Add(value); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 获取对象,不存在对使用委托添加对象
|
|
||||
/// </summary>
|
|
||||
public static T GetOrAdd<T>(this ICollection<T> collection, Func<T, bool> selector, Func<T> factory) |
|
||||
{ |
|
||||
Guard.NotNull(collection, nameof(collection)); |
|
||||
T item = collection.FirstOrDefault(selector); |
|
||||
if (item == null) |
|
||||
{ |
|
||||
item = factory(); |
|
||||
collection.Add(item); |
|
||||
} |
|
||||
|
|
||||
return item; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 判断集合是否为null或空集合
|
|
||||
/// </summary>
|
|
||||
public static bool IsNullOrEmpty<T>(this ICollection<T> collection) |
|
||||
{ |
|
||||
return collection == null || collection.Count == 0; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 交换两项的位置
|
|
||||
/// </summary>
|
|
||||
public static void Swap<T>(this List<T> list, int index1, int index2) |
|
||||
{ |
|
||||
Guard.Between(index1, nameof(index1), 0, list.Count, true); |
|
||||
Guard.Between(index2, nameof(index2), 0, list.Count, true); |
|
||||
|
|
||||
if (index1 == index2) |
|
||||
{ |
|
||||
return; |
|
||||
} |
|
||||
|
|
||||
T tmp = list[index1]; |
|
||||
list[index1] = list[index2]; |
|
||||
list[index2] = tmp; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,202 +0,0 @@ |
|||||
using System; |
|
||||
using System.Collections.Generic; |
|
||||
using System.Linq; |
|
||||
using System.Text; |
|
||||
using CompanyName.ProjectName.Extension.Customs; |
|
||||
|
|
||||
namespace CompanyName.ProjectName.Extension.System.Collections.Generic |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Enumerable集合扩展方法
|
|
||||
/// </summary>
|
|
||||
public static class EnumerableExtensions |
|
||||
{ |
|
||||
/// <summary>断言集合中的元素符合指定表达式,否则抛出异常。</summary>
|
|
||||
/// <typeparam name="T">集合项类型</typeparam>
|
|
||||
/// <param name="source">源集合</param>
|
|
||||
/// <param name="predicate">元素判断表达式</param>
|
|
||||
/// <param name="errorSelector">异常选择器</param>
|
|
||||
/// <returns>筛选过的集合</returns>
|
|
||||
public static IEnumerable<T> Assert<T>(this IEnumerable<T> source, Func<T, bool> predicate, |
|
||||
Func<T, Exception> errorSelector = null) |
|
||||
{ |
|
||||
foreach (var item in source) |
|
||||
{ |
|
||||
var success = predicate(item); |
|
||||
if (!success) |
|
||||
{ |
|
||||
throw errorSelector?.Invoke(item) ?? |
|
||||
new InvalidOperationException("集合中包含无效的元素。"); |
|
||||
} |
|
||||
|
|
||||
yield return item; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 打乱一个集合的项顺序,将一个集合洗牌
|
|
||||
/// </summary>
|
|
||||
public static IEnumerable<TSource> Shuffle<TSource>(this IEnumerable<TSource> source) |
|
||||
{ |
|
||||
// ReSharper disable PossibleMultipleEnumeration
|
|
||||
|
|
||||
Guard.NotNull(source, nameof(source)); |
|
||||
return source.OrderBy(m => Guid.NewGuid()); |
|
||||
|
|
||||
// ReSharper restore PossibleMultipleEnumeration
|
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 将集合展开并分别转换成字符串,再以指定的分隔符衔接,拼成一个字符串返回。默认分隔符为逗号。
|
|
||||
/// </summary>
|
|
||||
/// <param name="collection">要处理的集合</param>
|
|
||||
/// <param name="separator">分隔符,默认为逗号</param>
|
|
||||
/// <returns>拼接后的字符串</returns>
|
|
||||
public static string ExpandAndToString<T>(this IEnumerable<T> collection, string separator = ",") |
|
||||
{ |
|
||||
return collection.ExpandAndToString(item => item?.ToString() ?? string.Empty, separator); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 循环集合的每一项,调用委托生成字符串,返回合并后的字符串。默认分隔符为逗号
|
|
||||
/// </summary>
|
|
||||
/// <param name="collection">待处理的集合</param>
|
|
||||
/// <param name="itemFormatFunc">单个集合项的转换委托</param>
|
|
||||
/// <param name="separator">分隔符,默认为逗号</param>
|
|
||||
/// <typeparam name="T">泛型类型</typeparam>
|
|
||||
/// <returns></returns>
|
|
||||
public static string ExpandAndToString<T>( |
|
||||
this IEnumerable<T> collection, |
|
||||
Func<T, string> itemFormatFunc, |
|
||||
string separator = ",") |
|
||||
{ |
|
||||
collection = collection as IList<T> ?? collection.ToList(); |
|
||||
Guard.NotNull(itemFormatFunc, nameof(itemFormatFunc)); |
|
||||
|
|
||||
if (!collection.Any()) |
|
||||
{ |
|
||||
return string.Empty; |
|
||||
} |
|
||||
|
|
||||
var sb = new StringBuilder(); |
|
||||
var i = 0; |
|
||||
var count = collection.Count(); |
|
||||
foreach (var item in collection) |
|
||||
{ |
|
||||
if (i == count - 1) |
|
||||
{ |
|
||||
sb.Append(itemFormatFunc(item)); |
|
||||
} |
|
||||
else |
|
||||
{ |
|
||||
sb.Append(itemFormatFunc(item) + separator); |
|
||||
} |
|
||||
|
|
||||
i++; |
|
||||
} |
|
||||
|
|
||||
return sb.ToString(); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 集合是否为空
|
|
||||
/// </summary>
|
|
||||
/// <param name="collection"> 要处理的集合 </param>
|
|
||||
/// <typeparam name="T"> 动态类型 </typeparam>
|
|
||||
/// <returns> 为空返回True,不为空返回False </returns>
|
|
||||
public static bool IsEmpty<T>(this IEnumerable<T> collection) |
|
||||
{ |
|
||||
collection = collection as IList<T> ?? collection.ToList(); |
|
||||
return !collection.Any(); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 根据第三方条件是否为真来决定是否执行指定条件的查询
|
|
||||
/// </summary>
|
|
||||
/// <param name="source"> 要查询的源 </param>
|
|
||||
/// <param name="predicate"> 查询条件 </param>
|
|
||||
/// <param name="condition"> 第三方条件 </param>
|
|
||||
/// <typeparam name="T"> 动态类型 </typeparam>
|
|
||||
/// <returns> 查询的结果 </returns>
|
|
||||
public static IEnumerable<T> WhereIf<T>(this IEnumerable<T> source, Func<T, bool> predicate, bool condition) |
|
||||
{ |
|
||||
Guard.NotNull(predicate, nameof(predicate)); |
|
||||
source = source as IList<T> ?? source.ToList(); |
|
||||
|
|
||||
return condition ? source.Where(predicate) : source; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 将字符串集合按指定前缀排序
|
|
||||
/// </summary>
|
|
||||
public static IEnumerable<T> OrderByPrefixes<T>(this IEnumerable<T> source, Func<T, string> keySelector, |
|
||||
params string[] prefixes) |
|
||||
{ |
|
||||
var all = source.OrderBy(keySelector).ToList(); |
|
||||
var result = new List<T>(); |
|
||||
foreach (var prefix in prefixes) |
|
||||
{ |
|
||||
var tmpList = all.Where(m => keySelector(m).StartsWith(prefix)).OrderBy(keySelector).ToList(); |
|
||||
all = all.Except(tmpList).ToList(); |
|
||||
result.AddRange(tmpList); |
|
||||
} |
|
||||
|
|
||||
result.AddRange(all); |
|
||||
return result; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 根据指定条件返回集合中不重复的元素
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="T">动态类型</typeparam>
|
|
||||
/// <typeparam name="TKey">动态筛选条件类型</typeparam>
|
|
||||
/// <param name="source">要操作的源</param>
|
|
||||
/// <param name="keySelector">重复数据筛选条件</param>
|
|
||||
/// <returns>不重复元素的集合</returns>
|
|
||||
public static IEnumerable<T> DistinctBy<T, TKey>(this IEnumerable<T> source, Func<T, TKey> keySelector) |
|
||||
{ |
|
||||
Guard.NotNull(keySelector, nameof(keySelector)); |
|
||||
source = source as IList<T> ?? source.ToList(); |
|
||||
|
|
||||
return source.GroupBy(keySelector).Select(group => group.First()); |
|
||||
} |
|
||||
|
|
||||
#region Internal
|
|
||||
|
|
||||
internal static int? TryGetCollectionCount<T>(this IEnumerable<T> source) |
|
||||
{ |
|
||||
switch (source) |
|
||||
{ |
|
||||
case null: |
|
||||
throw new ArgumentNullException(nameof(source)); |
|
||||
case ICollection<T> collection: |
|
||||
return collection.Count; |
|
||||
case IReadOnlyCollection<T> collection: |
|
||||
return collection.Count; |
|
||||
default: |
|
||||
return null; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
static int CountUpTo<T>(this IEnumerable<T> source, int max) |
|
||||
{ |
|
||||
if (source == null) throw new ArgumentNullException(nameof(source)); |
|
||||
if (max < 0) |
|
||||
throw new ArgumentOutOfRangeException(nameof(max), "最大计数参数不能为负。"); |
|
||||
|
|
||||
var count = 0; |
|
||||
|
|
||||
using (var e = source.GetEnumerator()) |
|
||||
{ |
|
||||
while (count < max && e.MoveNext()) |
|
||||
{ |
|
||||
count++; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
return count; |
|
||||
} |
|
||||
|
|
||||
#endregion
|
|
||||
} |
|
||||
} |
|
||||
@ -1,79 +0,0 @@ |
|||||
using System; |
|
||||
using System.Globalization; |
|
||||
using System.Linq; |
|
||||
|
|
||||
namespace CompanyName.ProjectName.Extension.System |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// 时间扩展操作类
|
|
||||
/// </summary>
|
|
||||
public static class DateTimeExtensions |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// 当前时间是否周末
|
|
||||
/// </summary>
|
|
||||
/// <param name="dateTime">时间点</param>
|
|
||||
/// <returns></returns>
|
|
||||
public static bool IsWeekend(this DateTime dateTime) |
|
||||
{ |
|
||||
DayOfWeek[] weeks = { DayOfWeek.Saturday, DayOfWeek.Sunday }; |
|
||||
return weeks.Contains(dateTime.DayOfWeek); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 当前时间是否工作日
|
|
||||
/// </summary>
|
|
||||
/// <param name="dateTime">时间点</param>
|
|
||||
/// <returns></returns>
|
|
||||
public static bool IsWeekday(this DateTime dateTime) |
|
||||
{ |
|
||||
DayOfWeek[] weeks = { DayOfWeek.Monday, DayOfWeek.Tuesday, DayOfWeek.Wednesday, DayOfWeek.Thursday, DayOfWeek.Friday }; |
|
||||
return weeks.Contains(dateTime.DayOfWeek); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 获取时间相对唯一字符串
|
|
||||
/// </summary>
|
|
||||
/// <param name="dateTime"></param>
|
|
||||
/// <param name="millisecond">是否使用毫秒</param>
|
|
||||
/// <returns></returns>
|
|
||||
public static string ToUniqueString(this DateTime dateTime, bool millisecond = false) |
|
||||
{ |
|
||||
var seconds = dateTime.Hour * 3600 + dateTime.Minute * 60 + dateTime.Second; |
|
||||
var value = $"{dateTime:yyyy}{dateTime.DayOfYear}{seconds}"; |
|
||||
if (millisecond) |
|
||||
{ |
|
||||
return value + dateTime.ToString("fff"); |
|
||||
} |
|
||||
|
|
||||
return value; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 将时间转换为JS时间格式(Date.getTime())
|
|
||||
/// </summary>
|
|
||||
/// <param name="dateTime"></param>
|
|
||||
/// <param name="millisecond">是否使用毫秒</param>
|
|
||||
public static string ToJsGetTime(this DateTime dateTime, bool millisecond = true) |
|
||||
{ |
|
||||
var utc = dateTime.ToUniversalTime(); |
|
||||
var span = utc.Subtract(new DateTime(1970, 1, 1)); |
|
||||
return Math.Round(millisecond ? span.TotalMilliseconds : span.TotalSeconds).ToString(CultureInfo.InvariantCulture); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 将JS时间格式的数值转换为时间
|
|
||||
/// </summary>
|
|
||||
public static DateTime FromJsGetTime(this long jsTime) |
|
||||
{ |
|
||||
var length = jsTime.ToString().Length; |
|
||||
if (!(length == 10 || length == 13)) |
|
||||
{ |
|
||||
throw new ArgumentOutOfRangeException(null, "JS时间数值的长度不正确,必须为10位或13位"); |
|
||||
} |
|
||||
var start = new DateTime(1970, 1, 1); |
|
||||
var result = length == 10 ? start.AddSeconds(jsTime) : start.AddMilliseconds(jsTime); |
|
||||
return result.ToUniversalTime(); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,200 +0,0 @@ |
|||||
using System; |
|
||||
using System.Collections.Generic; |
|
||||
using System.Collections.Specialized; |
|
||||
using System.ComponentModel; |
|
||||
using System.Linq; |
|
||||
using System.Reflection; |
|
||||
using CompanyName.ProjectName.Extension.System.Reflection; |
|
||||
|
|
||||
namespace CompanyName.ProjectName.Extension.System |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// 枚举<see cref="Enum"/>的扩展辅助操作方法
|
|
||||
/// </summary>
|
|
||||
public static class EnumExtensions |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// 获取枚举项上的<see cref="DescriptionAttribute"/>特性的文字描述
|
|
||||
/// </summary>
|
|
||||
/// <param name="value"></param>
|
|
||||
/// <returns></returns>
|
|
||||
public static string ToDescription(this Enum value) |
|
||||
{ |
|
||||
var type = value.GetType(); |
|
||||
var member = type.GetMember(value.ToString()).FirstOrDefault(); |
|
||||
|
|
||||
return member != null ? member.GetDescription() : value.ToString(); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 枚举遍历,返回枚举的名称、值、特性
|
|
||||
/// </summary>
|
|
||||
/// <param name="enumType">枚举类型</param>
|
|
||||
/// <param name="action">回调函数</param>
|
|
||||
private static void Each(this Type enumType, Action<string, string, string, object> action) |
|
||||
{ |
|
||||
if (enumType.BaseType != typeof(Enum)) |
|
||||
{ |
|
||||
return; |
|
||||
} |
|
||||
var arr = Enum.GetValues(enumType); |
|
||||
foreach (var name in arr) |
|
||||
{ |
|
||||
var currentEnum = Enum.Parse(enumType, name.ToString()); |
|
||||
var value = Convert.ToInt32(Enum.Parse(enumType, name.ToString())); |
|
||||
var fieldInfo = enumType.GetField(name.ToString()); |
|
||||
var description = ""; |
|
||||
if (fieldInfo != null) |
|
||||
{ |
|
||||
var attr = Attribute.GetCustomAttribute(fieldInfo, |
|
||||
typeof(DescriptionAttribute), false) as DescriptionAttribute; |
|
||||
if (attr != null) |
|
||||
{ |
|
||||
description = attr.Description; |
|
||||
} |
|
||||
} |
|
||||
action(name.ToString(), value.ToString(), description, currentEnum); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 根据枚举类型值返回枚举定义Description属性
|
|
||||
/// </summary>
|
|
||||
/// <param name="value"></param>
|
|
||||
/// <param name="enumType"></param>
|
|
||||
/// <returns></returns>
|
|
||||
public static string ToEnumDescriptionString(this short value, Type enumType) |
|
||||
{ |
|
||||
var nvc = new NameValueCollection(); |
|
||||
var typeDescription = typeof(DescriptionAttribute); |
|
||||
var fields = enumType.GetFields(); |
|
||||
foreach (var field in fields) |
|
||||
{ |
|
||||
if (field.FieldType.IsEnum) |
|
||||
{ |
|
||||
var strValue = ((int)enumType.InvokeMember(field.Name, BindingFlags.GetField, null, null, null)).ToString(); |
|
||||
var arr = field.GetCustomAttributes(typeDescription, true); |
|
||||
string strText; |
|
||||
if (arr.Length > 0) |
|
||||
{ |
|
||||
var aa = (DescriptionAttribute)arr[0]; |
|
||||
strText = aa.Description; |
|
||||
} |
|
||||
else |
|
||||
{ |
|
||||
strText = ""; |
|
||||
} |
|
||||
nvc.Add(strValue, strText); |
|
||||
} |
|
||||
} |
|
||||
return nvc[value.ToString()]; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 将指定枚举转换为字典.
|
|
||||
/// 枚举的Description为字典的Key,枚举的Value为字典的Value
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="T">指定枚举</typeparam>
|
|
||||
private static List<KeyValuePair<string, string>> GetEnumTypeValueList<T>() |
|
||||
{ |
|
||||
var items = new List<KeyValuePair<string, string>>(); |
|
||||
typeof(T).Each((name, value, description, enumObj) => |
|
||||
items.Add(new KeyValuePair<string, string>(description, value))); |
|
||||
return items; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 将指定枚举转换为字典.
|
|
||||
/// 枚举的Description为字典的Key,枚举为字典的Value
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="T">指定枚举</typeparam>
|
|
||||
private static List<KeyValuePair<string, T>> GetEnumTypeList<T>() |
|
||||
{ |
|
||||
var items = new List<KeyValuePair<string, T>>(); |
|
||||
typeof(T).Each((name, value, description, enumObj) => |
|
||||
items.Add(new KeyValuePair<string, T>(description, (T)enumObj))); |
|
||||
return items; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 将指定枚举转换为字典.
|
|
||||
/// 枚举的Description为字典的Key,枚举的Name为字典的Value
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="T">指定枚举</typeparam>
|
|
||||
public static List<KeyValuePair<string, string>> GetEnumTypeDescriptionNameList<T>() |
|
||||
{ |
|
||||
var items = new List<KeyValuePair<string, string>>(); |
|
||||
typeof(T).Each((name, value, description, enumObj) => items.Add(new KeyValuePair<string, string>(description, name))); |
|
||||
return items; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 将指定枚举转换为字典.
|
|
||||
/// 枚举的Name为字典的Key,枚举的Description为字典的Value
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="T">指定枚举</typeparam>
|
|
||||
public static List<KeyValuePair<string, string>> GetEnumTypeValueNameList<T>() |
|
||||
{ |
|
||||
var items = new List<KeyValuePair<string, string>>(); |
|
||||
typeof(T).Each((name, value, description, enumObj) => items.Add(new KeyValuePair<string, string>(name, description))); |
|
||||
return items; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 将指定枚举转换为字典.
|
|
||||
/// 枚举的Name为字典的Key,枚举的Description为字典的Value
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TModel">指定枚举</typeparam>
|
|
||||
public static List<KeyValuePair<string, string>> GetStringKeyValueList<TModel>() where TModel : Enum |
|
||||
{ |
|
||||
var keyValuePairList = new List<KeyValuePair<string, string>>(); |
|
||||
var values = Enum.GetValues(typeof(TModel)); |
|
||||
var modelArray = new TModel[values.Length]; |
|
||||
values.CopyTo(modelArray, 0); |
|
||||
foreach (TModel model in modelArray) |
|
||||
keyValuePairList.Add(new KeyValuePair<string, string>(model.ToString(), model.ToString())); |
|
||||
return keyValuePairList; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 将指定枚举转换为字典.
|
|
||||
/// 枚举的Description为字典的Key,枚举为字典的Value
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TModel">指定枚举</typeparam>
|
|
||||
public static List<KeyValuePair<string, TModel>> GetEnumKeyValueList<TModel>() where TModel : Enum |
|
||||
{ |
|
||||
var enumTypeList = GetEnumTypeList<TModel>(); |
|
||||
var keyValuePairList = new List<KeyValuePair<string, TModel>>(); |
|
||||
foreach (KeyValuePair<string, TModel> keyValuePair in enumTypeList) |
|
||||
keyValuePairList.Add(new KeyValuePair<string, TModel>(keyValuePair.Key, keyValuePair.Value)); |
|
||||
return keyValuePairList; |
|
||||
} |
|
||||
|
|
||||
public static List<KeyValuePair<string, string>> GetEntityDoubleStringKeyValueList<TModel>() |
|
||||
{ |
|
||||
var enumTypeList = GetEnumTypeValueList<TModel>(); |
|
||||
var keyValuePairList = new List<KeyValuePair<string, string>>(); |
|
||||
foreach (KeyValuePair<string, string> keyValuePair in enumTypeList) |
|
||||
keyValuePairList.Add(new KeyValuePair<string, string>(keyValuePair.Key, keyValuePair.Value)); |
|
||||
return keyValuePairList; |
|
||||
} |
|
||||
|
|
||||
public static List<KeyValuePair<string, int>> GetEntityStringIntKeyValueList<TModel>() |
|
||||
{ |
|
||||
List<KeyValuePair<string, string>> enumTypeList = GetEnumTypeValueList<TModel>(); |
|
||||
List<KeyValuePair<string, int>> keyValuePairList = new List<KeyValuePair<string, int>>(); |
|
||||
foreach (KeyValuePair<string, string> keyValuePair in enumTypeList) |
|
||||
keyValuePairList.Add(new KeyValuePair<string, int>(keyValuePair.Key, Convert.ToInt32(keyValuePair.Value))); |
|
||||
return keyValuePairList; |
|
||||
} |
|
||||
|
|
||||
public static List<KeyValuePair<int, int>> GetEntityDoubleIntKeyValueList<TModel>() |
|
||||
{ |
|
||||
List<KeyValuePair<string, string>> enumTypeList = GetEnumTypeValueList<TModel>(); |
|
||||
List<KeyValuePair<int, int>> keyValuePairList = new List<KeyValuePair<int, int>>(); |
|
||||
foreach (KeyValuePair<string, string> keyValuePair in enumTypeList) |
|
||||
keyValuePairList.Add(new KeyValuePair<int, int>(Convert.ToInt32(keyValuePair.Key), Convert.ToInt32(keyValuePair.Value))); |
|
||||
return keyValuePairList; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,77 +0,0 @@ |
|||||
using System; |
|
||||
using System.Runtime.ExceptionServices; |
|
||||
using System.Text; |
|
||||
|
|
||||
namespace CompanyName.ProjectName.Extension.System |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// 异常操作扩展
|
|
||||
/// </summary>
|
|
||||
public static class ExceptionExtensions |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// 格式化异常消息
|
|
||||
/// </summary>
|
|
||||
/// <param name="e">异常对象</param>
|
|
||||
/// <param name="isHideStackTrace">是否隐藏异常规模信息</param>
|
|
||||
/// <returns>格式化后的异常信息字符串</returns>
|
|
||||
public static string FormatMessage(this Exception e, bool isHideStackTrace = false) |
|
||||
{ |
|
||||
var sb = new StringBuilder(); |
|
||||
var count = 0; |
|
||||
var appString = string.Empty; |
|
||||
while (e != null) |
|
||||
{ |
|
||||
if (count > 0) |
|
||||
{ |
|
||||
appString += " "; |
|
||||
} |
|
||||
sb.AppendLine($"{appString}异常消息:{e.Message}"); |
|
||||
sb.AppendLine($"{appString}异常类型:{e.GetType().FullName}"); |
|
||||
sb.AppendLine($"{appString}异常方法:{(e.TargetSite == null ? null : e.TargetSite.Name)}"); |
|
||||
sb.AppendLine($"{appString}异常源:{e.Source}"); |
|
||||
if (!isHideStackTrace && e.StackTrace != null) |
|
||||
{ |
|
||||
sb.AppendLine($"{appString}异常堆栈:{e.StackTrace}"); |
|
||||
} |
|
||||
if (e.InnerException != null) |
|
||||
{ |
|
||||
sb.AppendLine($"{appString}内部异常:"); |
|
||||
count++; |
|
||||
e = e.InnerException; |
|
||||
} |
|
||||
} |
|
||||
return sb.ToString(); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 将异常重新抛出
|
|
||||
/// </summary>
|
|
||||
public static void ReThrow(this Exception exception) |
|
||||
{ |
|
||||
ExceptionDispatchInfo.Capture(exception).Throw(); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 如果条件成立,则抛出异常
|
|
||||
/// </summary>
|
|
||||
public static void ThrowIf(this Exception exception, bool isThrow) |
|
||||
{ |
|
||||
if (isThrow) |
|
||||
{ |
|
||||
throw exception; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 如果条件成立,则抛出异常
|
|
||||
/// </summary>
|
|
||||
public static void ThrowIf(this Exception exception, Func<bool> isThrowFunc) |
|
||||
{ |
|
||||
if (isThrowFunc()) |
|
||||
{ |
|
||||
throw exception; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,30 +0,0 @@ |
|||||
using System; |
|
||||
using System.Linq; |
|
||||
using System.Linq.Expressions; |
|
||||
using CompanyName.ProjectName.Extension.Customs; |
|
||||
|
|
||||
namespace CompanyName.ProjectName.Extension.System.Linq |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// IQueryable集合扩展方法
|
|
||||
/// </summary>
|
|
||||
public static class QueryableExtensions |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// 根据第三方条件是否为真来决定是否执行指定条件的查询
|
|
||||
/// </summary>
|
|
||||
/// <param name="source"> 要查询的源 </param>
|
|
||||
/// <param name="predicate"> 查询条件 </param>
|
|
||||
/// <param name="condition"> 第三方条件 </param>
|
|
||||
/// <typeparam name="T"> 动态类型 </typeparam>
|
|
||||
/// <returns> 查询的结果 </returns>
|
|
||||
public static IQueryable<T> WhereIf<T>(this IQueryable<T> source, Expression<Func<T, bool>> predicate, |
|
||||
bool condition) |
|
||||
{ |
|
||||
Guard.NotNull(source, nameof(source)); |
|
||||
Guard.NotNull(predicate, nameof(predicate)); |
|
||||
|
|
||||
return condition ? source.Where(predicate) : source; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,27 +0,0 @@ |
|||||
using System.Diagnostics; |
|
||||
using System.Reflection; |
|
||||
using CompanyName.ProjectName.Extension.Customs; |
|
||||
|
|
||||
namespace CompanyName.ProjectName.Extension.System.Reflection |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// 程序集扩展操作类
|
|
||||
/// </summary>
|
|
||||
public static class AssemblyExtensions |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// 获取程序集的产品版本
|
|
||||
/// </summary>
|
|
||||
public static string GetProductVersion(this Assembly assembly) |
|
||||
{ |
|
||||
Guard.NotNull(assembly, nameof(assembly)); |
|
||||
var info = FileVersionInfo.GetVersionInfo(assembly.Location); |
|
||||
var version = info.ProductVersion; |
|
||||
if (version.Contains("+")) |
|
||||
{ |
|
||||
version = version.ReplaceRegex(@"\+(\w+)?", ""); |
|
||||
} |
|
||||
return version; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,75 +0,0 @@ |
|||||
using System; |
|
||||
using System.ComponentModel; |
|
||||
using System.ComponentModel.DataAnnotations; |
|
||||
using System.Linq; |
|
||||
using System.Reflection; |
|
||||
|
|
||||
namespace CompanyName.ProjectName.Extension.System.Reflection |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// 成员<see cref="MemberInfo"/>的扩展辅助操作方法
|
|
||||
/// </summary>
|
|
||||
public static class MemberInfoExtensions |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// 获取成员元数据的Description特性描述信息。
|
|
||||
/// </summary>
|
|
||||
/// <param name="member">成员元数据对象。</param>
|
|
||||
/// <param name="inherit">是否搜索成员的继承链以查找描述特性。</param>
|
|
||||
/// <returns>返回Description特性描述信息,如不存在则返回成员的名称。</returns>
|
|
||||
public static string GetDescription(this MemberInfo member, bool inherit = true) |
|
||||
{ |
|
||||
var desc = member.GetAttribute<DescriptionAttribute>(inherit); |
|
||||
if (desc != null) |
|
||||
{ |
|
||||
return desc.Description; |
|
||||
} |
|
||||
|
|
||||
var displayName = member.GetAttribute<DisplayNameAttribute>(inherit); |
|
||||
if (displayName != null) |
|
||||
{ |
|
||||
return displayName.DisplayName; |
|
||||
} |
|
||||
|
|
||||
var display = member.GetAttribute<DisplayAttribute>(inherit); |
|
||||
return display != null ? display.Name : member.Name; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 检查指定指定类型成员中是否存在指定的Attribute特性。
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="T">要检查的Attribute特性类型。</typeparam>
|
|
||||
/// <param name="memberInfo">要检查的类型成员</param>
|
|
||||
/// <param name="inherit">是否从继承中查找</param>
|
|
||||
/// <returns>是否存在</returns>
|
|
||||
public static bool HasAttribute<T>(this MemberInfo memberInfo, bool inherit = true) where T : Attribute |
|
||||
{ |
|
||||
return memberInfo.IsDefined(typeof(T), inherit); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 从类型成员获取指定Attribute特性
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="T">Attribute特性类型</typeparam>
|
|
||||
/// <param name="memberInfo">类型类型成员</param>
|
|
||||
/// <param name="inherit">是否从继承中查找</param>
|
|
||||
/// <returns>存在返回第一个,不存在返回null</returns>
|
|
||||
public static T GetAttribute<T>(this MemberInfo memberInfo, bool inherit = true) where T : Attribute |
|
||||
{ |
|
||||
var attributes = memberInfo.GetCustomAttributes(typeof(T), inherit); |
|
||||
return attributes.FirstOrDefault() as T; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 从类型成员获取指定Attribute特性。
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="T">Attribute特性类型。</typeparam>
|
|
||||
/// <param name="memberInfo">类型类型成员。</param>
|
|
||||
/// <param name="inherit">是否从继承中查找。</param>
|
|
||||
/// <returns>返回所有指定Attribute特性的数组。</returns>
|
|
||||
public static T[] GetAttributes<T>(this MemberInfo memberInfo, bool inherit = true) where T : Attribute |
|
||||
{ |
|
||||
return memberInfo.GetCustomAttributes(typeof(T), inherit).Cast<T>().ToArray(); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,32 +0,0 @@ |
|||||
using System.Reflection; |
|
||||
using System.Threading.Tasks; |
|
||||
|
|
||||
namespace CompanyName.ProjectName.Extension.System.Reflection |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// 方法<see cref="MethodInfo"/>的扩展辅助操作方法
|
|
||||
/// </summary>
|
|
||||
public static class MethodInfoExtensions |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// 方法是否是异步
|
|
||||
/// </summary>
|
|
||||
public static bool IsAsync(this MethodInfo method) |
|
||||
{ |
|
||||
return (method.ReturnType == typeof(Task<>) |
|
||||
|| method.ReturnType.IsGenericType |
|
||||
&& method.ReturnType.GetGenericTypeDefinition() == typeof(Task<>)) |
|
||||
|| method.ReturnType == typeof(Task); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 返回当前方法信息是否是重写方法
|
|
||||
/// </summary>
|
|
||||
/// <param name="method">要判断的方法信息</param>
|
|
||||
/// <returns>是否是重写方法</returns>
|
|
||||
public static bool IsOverridden(this MethodInfo method) |
|
||||
{ |
|
||||
return method.GetBaseDefinition().DeclaringType != method.DeclaringType; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,25 +0,0 @@ |
|||||
using System.Linq; |
|
||||
using System.Reflection; |
|
||||
|
|
||||
namespace CompanyName.ProjectName.Extension.System.Reflection |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// 属性<see cref="MethodInfo"/>的扩展辅助操作方法
|
|
||||
/// </summary>
|
|
||||
public static class PropertyInfoExtensions |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// 返回当前属性信息是否为virtual
|
|
||||
/// </summary>
|
|
||||
public static bool IsVirtual(this PropertyInfo property) |
|
||||
{ |
|
||||
var accessor = property.GetAccessors().FirstOrDefault(); |
|
||||
if (accessor == null) |
|
||||
{ |
|
||||
return false; |
|
||||
} |
|
||||
|
|
||||
return accessor.IsVirtual && !accessor.IsFinal; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,983 +0,0 @@ |
|||||
using System; |
|
||||
using System.Collections.Generic; |
|
||||
using System.Diagnostics; |
|
||||
using System.Globalization; |
|
||||
using System.Linq; |
|
||||
using System.Text; |
|
||||
using System.Text.RegularExpressions; |
|
||||
using System.Web; |
|
||||
using CompanyName.ProjectName.Extension.Customs; |
|
||||
using CompanyName.ProjectName.Extension.System.Collections.Generic; |
|
||||
using Newtonsoft.Json; |
|
||||
|
|
||||
namespace CompanyName.ProjectName.Extension.System |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// 字符串<see cref="string"/>类型的扩展辅助操作类
|
|
||||
/// </summary>
|
|
||||
[DebuggerStepThrough] |
|
||||
public static class StringExtensions |
|
||||
{ |
|
||||
#region 正则表达式
|
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 指示所指定的正则表达式在指定的输入字符串中是否找到了匹配项
|
|
||||
/// </summary>
|
|
||||
/// <param name="value">要搜索匹配项的字符串</param>
|
|
||||
/// <param name="pattern">要匹配的正则表达式模式</param>
|
|
||||
/// <param name="isContains">是否包含,否则全匹配</param>
|
|
||||
/// <returns>如果正则表达式找到匹配项,则为 true;否则,为 false</returns>
|
|
||||
public static bool IsMatch(this string value, string pattern, bool isContains = true) |
|
||||
{ |
|
||||
if (value == null) |
|
||||
{ |
|
||||
return false; |
|
||||
} |
|
||||
|
|
||||
return isContains |
|
||||
? Regex.IsMatch(value, pattern) |
|
||||
: Regex.Match(value, pattern).Success; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 在指定的输入字符串中搜索指定的正则表达式的第一个匹配项
|
|
||||
/// </summary>
|
|
||||
/// <param name="value">要搜索匹配项的字符串</param>
|
|
||||
/// <param name="pattern">要匹配的正则表达式模式</param>
|
|
||||
/// <returns>一个对象,包含有关匹配项的信息</returns>
|
|
||||
public static string Match(this string value, string pattern) |
|
||||
{ |
|
||||
if (value == null) |
|
||||
{ |
|
||||
return null; |
|
||||
} |
|
||||
|
|
||||
return Regex.Match(value, pattern).Value; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 在指定的输入字符串中匹配并替换符合指定正则表达式的子串
|
|
||||
/// </summary>
|
|
||||
public static string ReplaceRegex(this string value, string pattern, string replacement) |
|
||||
{ |
|
||||
if (value == null) |
|
||||
{ |
|
||||
return null; |
|
||||
} |
|
||||
|
|
||||
return Regex.Replace(value, pattern, replacement); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 在指定的输入字符串中搜索指定的正则表达式的所有匹配项的字符串集合
|
|
||||
/// </summary>
|
|
||||
/// <param name="value"> 要搜索匹配项的字符串 </param>
|
|
||||
/// <param name="pattern"> 要匹配的正则表达式模式 </param>
|
|
||||
/// <returns> 一个集合,包含有关匹配项的字符串值 </returns>
|
|
||||
public static IEnumerable<string> Matches(this string value, string pattern) |
|
||||
{ |
|
||||
if (value == null) |
|
||||
{ |
|
||||
return new string[] { }; |
|
||||
} |
|
||||
|
|
||||
var matches = Regex.Matches(value, pattern); |
|
||||
return from Match match in matches select match.Value; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 在指定的输入字符串中匹配第一个数字字符串
|
|
||||
/// </summary>
|
|
||||
public static string MatchFirstNumber(this string value) |
|
||||
{ |
|
||||
var matches = Regex.Matches(value, @"\d+"); |
|
||||
if (matches.Count == 0) |
|
||||
{ |
|
||||
return string.Empty; |
|
||||
} |
|
||||
|
|
||||
return matches[0].Value; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 在指定字符串中匹配最后一个数字字符串
|
|
||||
/// </summary>
|
|
||||
public static string MatchLastNumber(this string value) |
|
||||
{ |
|
||||
var matches = Regex.Matches(value, @"\d+"); |
|
||||
if (matches.Count == 0) |
|
||||
{ |
|
||||
return string.Empty; |
|
||||
} |
|
||||
|
|
||||
return matches[matches.Count - 1].Value; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 在指定字符串中匹配所有数字字符串
|
|
||||
/// </summary>
|
|
||||
public static IEnumerable<string> MatchNumbers(this string value) |
|
||||
{ |
|
||||
return Matches(value, @"\d+"); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 检测指定字符串中是否包含数字
|
|
||||
/// </summary>
|
|
||||
public static bool IsMatchNumber(this string value) |
|
||||
{ |
|
||||
return IsMatch(value, @"\d"); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 检测指定字符串是否全部为数字并且长度等于指定长度
|
|
||||
/// </summary>
|
|
||||
public static bool IsMatchNumber(this string value, int length) |
|
||||
{ |
|
||||
var regex = new Regex(@"^\d{" + length + "}$"); |
|
||||
return regex.IsMatch(value); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 截取指定字符串之间的字符串
|
|
||||
/// </summary>
|
|
||||
/// <param name="source"></param>
|
|
||||
/// <param name="startString">起始字符串</param>
|
|
||||
/// <param name="endStrings">结束字符串,可多个</param>
|
|
||||
/// <returns>返回的中间字符串</returns>
|
|
||||
public static string Substring(this string source, string startString, params string[] endStrings) |
|
||||
{ |
|
||||
if (source.IsMissing()) |
|
||||
{ |
|
||||
return string.Empty; |
|
||||
} |
|
||||
|
|
||||
var startIndex = 0; |
|
||||
if (!string.IsNullOrEmpty(startString)) |
|
||||
{ |
|
||||
startIndex = source.IndexOf(startString, StringComparison.OrdinalIgnoreCase); |
|
||||
if (startIndex < 0) |
|
||||
{ |
|
||||
throw new InvalidOperationException($"在源字符串中无法找到“{startString}”的子串位置"); |
|
||||
} |
|
||||
|
|
||||
startIndex += startString.Length; |
|
||||
} |
|
||||
|
|
||||
var endIndex = source.Length; |
|
||||
endStrings = endStrings.OrderByDescending(m => m.Length).ToArray(); |
|
||||
foreach (var endString in endStrings) |
|
||||
{ |
|
||||
if (string.IsNullOrEmpty(endString)) |
|
||||
{ |
|
||||
endIndex = source.Length; |
|
||||
break; |
|
||||
} |
|
||||
|
|
||||
endIndex = source.IndexOf(endString, startIndex, StringComparison.OrdinalIgnoreCase); |
|
||||
if (endIndex < 0 || endIndex < startIndex) |
|
||||
{ |
|
||||
continue; |
|
||||
} |
|
||||
|
|
||||
break; |
|
||||
} |
|
||||
|
|
||||
if (endIndex < 0 || endIndex < startIndex) |
|
||||
{ |
|
||||
throw new InvalidOperationException($"在源字符串中无法找到“{endStrings.ExpandAndToString()}”的子串位置"); |
|
||||
} |
|
||||
|
|
||||
var length = endIndex - startIndex; |
|
||||
|
|
||||
return source.Substring(startIndex, length); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 用正则表达式截取字符串
|
|
||||
/// </summary>
|
|
||||
public static string Substring2(this string source, string startString, string endString) |
|
||||
{ |
|
||||
return source.Substring2(startString, endString, false); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 用正则表达式截取字符串
|
|
||||
/// </summary>
|
|
||||
public static string Substring2(this string source, string startString, string endString, bool containsEmpty) |
|
||||
{ |
|
||||
if (source.IsMissing()) |
|
||||
{ |
|
||||
return string.Empty; |
|
||||
} |
|
||||
|
|
||||
var inner = containsEmpty ? "\\s\\S" : "\\S"; |
|
||||
var result = source.Match($"(?<={startString})([{inner}]+?)(?={endString})"); |
|
||||
return result.IsMissing() ? null : result; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 是否电子邮件
|
|
||||
/// </summary>
|
|
||||
public static bool IsEmail(this string value) |
|
||||
{ |
|
||||
const string pattern = @"^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$"; |
|
||||
return value.IsMatch(pattern); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 是否是IP地址
|
|
||||
/// </summary>
|
|
||||
public static bool IsIpAddress(this string value) |
|
||||
{ |
|
||||
const string pattern = |
|
||||
@"^((?:(?:25[0-5]|2[0-4]\d|((1\d{2})|([1-9]?\d)))\.){3}(?:25[0-5]|2[0-4]\d|((1\d{2})|([1-9]?\d))))$"; |
|
||||
return value.IsMatch(pattern); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 是否是整数
|
|
||||
/// </summary>
|
|
||||
public static bool IsNumeric(this string value) |
|
||||
{ |
|
||||
const string pattern = @"^\-?[0-9]+$"; |
|
||||
return value.IsMatch(pattern); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 是否是Unicode字符串
|
|
||||
/// </summary>
|
|
||||
public static bool IsUnicode(this string value) |
|
||||
{ |
|
||||
const string pattern = @"^[\u4E00-\u9FA5\uE815-\uFA29]+$"; |
|
||||
return value.IsMatch(pattern); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 是否Url字符串
|
|
||||
/// </summary>
|
|
||||
public static bool IsUrl(this string value) |
|
||||
{ |
|
||||
try |
|
||||
{ |
|
||||
if (string.IsNullOrEmpty(value) || value.Contains(' ')) |
|
||||
{ |
|
||||
return false; |
|
||||
} |
|
||||
|
|
||||
var uri = new Uri(value); |
|
||||
return true; |
|
||||
} |
|
||||
catch (Exception) |
|
||||
{ |
|
||||
return false; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 是否身份证号,验证如下3种情况:
|
|
||||
/// 1.身份证号码为15位数字;
|
|
||||
/// 2.身份证号码为18位数字;
|
|
||||
/// 3.身份证号码为17位数字+1个字母
|
|
||||
/// </summary>
|
|
||||
public static bool IsIdentityCardId(this string value) |
|
||||
{ |
|
||||
if (value.Length != 15 && value.Length != 18) |
|
||||
{ |
|
||||
return false; |
|
||||
} |
|
||||
|
|
||||
Regex regex; |
|
||||
string[] array; |
|
||||
if (value.Length == 15) |
|
||||
{ |
|
||||
regex = new Regex(@"^(\d{6})(\d{2})(\d{2})(\d{2})(\d{3})_"); |
|
||||
if (!regex.Match(value).Success) |
|
||||
{ |
|
||||
return false; |
|
||||
} |
|
||||
|
|
||||
array = regex.Split(value); |
|
||||
return DateTime.TryParse(string.Format("{0}-{1}-{2}", "19" + array[2], array[3], array[4]), out _); |
|
||||
} |
|
||||
|
|
||||
regex = new Regex(@"^(\d{6})(\d{4})(\d{2})(\d{2})(\d{3})([0-9Xx])$"); |
|
||||
if (!regex.Match(value).Success) |
|
||||
{ |
|
||||
return false; |
|
||||
} |
|
||||
|
|
||||
array = regex.Split(value); |
|
||||
if (!DateTime.TryParse(string.Format("{0}-{1}-{2}", array[2], array[3], array[4]), out _)) |
|
||||
{ |
|
||||
return false; |
|
||||
} |
|
||||
|
|
||||
//校验最后一位
|
|
||||
var chars = value.ToCharArray().Select(m => m.ToString()).ToArray(); |
|
||||
int[] weights = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2}; |
|
||||
var sum = 0; |
|
||||
for (var i = 0; i < 17; i++) |
|
||||
{ |
|
||||
var num = int.Parse(chars[i]); |
|
||||
sum += num * weights[i]; |
|
||||
} |
|
||||
|
|
||||
var mod = sum % 11; |
|
||||
var vCode = "10X98765432"; // 检验码字符串
|
|
||||
var last = vCode.ToCharArray().ElementAt(mod).ToString(); |
|
||||
return chars.Last().ToUpper() == last; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 是否手机号码
|
|
||||
/// </summary>
|
|
||||
/// <param name="value"></param>
|
|
||||
/// <param name="isRestrict">是否按严格格式验证</param>
|
|
||||
public static bool IsMobileNumber(this string value, bool isRestrict = false) |
|
||||
{ |
|
||||
var pattern = isRestrict ? @"^[1][3-8]\d{9}$" : @"^[1]\d{10}$"; |
|
||||
return value.IsMatch(pattern); |
|
||||
} |
|
||||
|
|
||||
#endregion
|
|
||||
|
|
||||
#region 其他操作
|
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 判断指定的字符串不是 null、空。
|
|
||||
/// </summary>
|
|
||||
public static bool IsNotNullOrEmpty(this string str) |
|
||||
{ |
|
||||
return !string.IsNullOrEmpty(str); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 判断指定的字符串不是 null、空或者仅由空白字符组成
|
|
||||
/// </summary>
|
|
||||
public static bool IsNotNullOrWhiteSpace(this string str) |
|
||||
{ |
|
||||
return !string.IsNullOrWhiteSpace(str); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 指示指定的字符串是 null、空或者仅由空白字符组成
|
|
||||
/// </summary>
|
|
||||
public static bool IsMissing(this string value) |
|
||||
{ |
|
||||
return string.IsNullOrWhiteSpace(value); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 为指定格式的字符串填充相应对象来生成字符串
|
|
||||
/// </summary>
|
|
||||
/// <param name="format">字符串格式,占位符以{n}表示</param>
|
|
||||
/// <param name="args">用于填充占位符的参数</param>
|
|
||||
/// <returns>格式化后的字符串</returns>
|
|
||||
public static string FormatWith(this string format, params object[] args) |
|
||||
{ |
|
||||
Guard.NotNull(format, nameof(format)); |
|
||||
return string.Format(CultureInfo.CurrentCulture, format, args); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 将字符串反转
|
|
||||
/// </summary>
|
|
||||
/// <param name="value">要反转的字符串</param>
|
|
||||
public static string ReverseString(this string value) |
|
||||
{ |
|
||||
Guard.NotNull(value, nameof(value)); |
|
||||
return new string(value.Reverse().ToArray()); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 单词复数变成单数形式
|
|
||||
/// </summary>
|
|
||||
/// <param name="word"></param>
|
|
||||
/// <returns></returns>
|
|
||||
public static string ToSingular(this string word) |
|
||||
{ |
|
||||
var plural1 = new Regex("(?<keep>[^aeiou])ies$"); |
|
||||
var plural2 = new Regex("(?<keep>[aeiou]y)s$"); |
|
||||
var plural3 = new Regex("(?<keep>[sxzh])es$"); |
|
||||
var plural4 = new Regex("(?<keep>[^sxzhyu])s$"); |
|
||||
|
|
||||
if (plural1.IsMatch(word)) |
|
||||
{ |
|
||||
return plural1.Replace(word, "${keep}y"); |
|
||||
} |
|
||||
|
|
||||
if (plural2.IsMatch(word)) |
|
||||
{ |
|
||||
return plural2.Replace(word, "${keep}"); |
|
||||
} |
|
||||
|
|
||||
if (plural3.IsMatch(word)) |
|
||||
{ |
|
||||
return plural3.Replace(word, "${keep}"); |
|
||||
} |
|
||||
|
|
||||
if (plural4.IsMatch(word)) |
|
||||
{ |
|
||||
return plural4.Replace(word, "${keep}"); |
|
||||
} |
|
||||
|
|
||||
return word; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 单词单数变成复数形式
|
|
||||
/// </summary>
|
|
||||
/// <param name="word"></param>
|
|
||||
/// <returns></returns>
|
|
||||
public static string ToPlural(this string word) |
|
||||
{ |
|
||||
var plural1 = new Regex("(?<keep>[^aeiou])y$"); |
|
||||
var plural2 = new Regex("(?<keep>[aeiou]y)$"); |
|
||||
var plural3 = new Regex("(?<keep>[sxzh])$"); |
|
||||
var plural4 = new Regex("(?<keep>[^sxzhy])$"); |
|
||||
|
|
||||
if (plural1.IsMatch(word)) |
|
||||
{ |
|
||||
return plural1.Replace(word, "${keep}ies"); |
|
||||
} |
|
||||
|
|
||||
if (plural2.IsMatch(word)) |
|
||||
{ |
|
||||
return plural2.Replace(word, "${keep}s"); |
|
||||
} |
|
||||
|
|
||||
if (plural3.IsMatch(word)) |
|
||||
{ |
|
||||
return plural3.Replace(word, "${keep}es"); |
|
||||
} |
|
||||
|
|
||||
if (plural4.IsMatch(word)) |
|
||||
{ |
|
||||
return plural4.Replace(word, "${keep}s"); |
|
||||
} |
|
||||
|
|
||||
return word; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 以指定字符串作为分隔符将指定字符串分隔成数组
|
|
||||
/// </summary>
|
|
||||
/// <param name="value">要分割的字符串</param>
|
|
||||
/// <param name="strSplit">字符串类型的分隔符</param>
|
|
||||
/// <param name="removeEmptyEntries">是否移除数据中元素为空字符串的项</param>
|
|
||||
/// <returns>分割后的数据</returns>
|
|
||||
public static string[] Split(this string value, string strSplit, bool removeEmptyEntries = false) |
|
||||
{ |
|
||||
return value.Split(new[] {strSplit}, |
|
||||
removeEmptyEntries ? StringSplitOptions.RemoveEmptyEntries : StringSplitOptions.None); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 支持汉字的字符串长度,汉字长度计为2
|
|
||||
/// </summary>
|
|
||||
/// <param name="value">参数字符串</param>
|
|
||||
/// <returns>当前字符串的长度,汉字长度为2</returns>
|
|
||||
public static int TextLength(this string value) |
|
||||
{ |
|
||||
var ascii = new ASCIIEncoding(); |
|
||||
var tempLen = 0; |
|
||||
var bytes = ascii.GetBytes(value); |
|
||||
foreach (var b in bytes) |
|
||||
{ |
|
||||
if (b == 63) |
|
||||
{ |
|
||||
tempLen += 2; |
|
||||
} |
|
||||
else |
|
||||
{ |
|
||||
tempLen += 1; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
return tempLen; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 将JSON字符串还原为对象
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="T">要转换的目标类型</typeparam>
|
|
||||
/// <param name="json">JSON字符串</param>
|
|
||||
/// <returns></returns>
|
|
||||
public static T FromJsonString<T>(this string json) |
|
||||
{ |
|
||||
Guard.NotNull(json, nameof(json)); |
|
||||
return JsonConvert.DeserializeObject<T>(json); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 将JSON字符串还原为对象
|
|
||||
/// </summary>
|
|
||||
/// <param name="json">JSON字符串 </param>
|
|
||||
/// <param name="type">数据类型</param>
|
|
||||
public static object FromJsonString(this string json, Type type) |
|
||||
{ |
|
||||
return JsonConvert.DeserializeObject(json, type); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 给URL添加查询参数
|
|
||||
/// </summary>
|
|
||||
/// <param name="url">URL字符串</param>
|
|
||||
/// <param name="queries">要添加的参数,形如:"id=1,cid=2"</param>
|
|
||||
/// <returns></returns>
|
|
||||
public static string AddUrlQuery(this string url, params string[] queries) |
|
||||
{ |
|
||||
foreach (var query in queries) |
|
||||
{ |
|
||||
if (!url.Contains("?")) |
|
||||
{ |
|
||||
url += "?"; |
|
||||
} |
|
||||
else if (!url.EndsWith("&")) |
|
||||
{ |
|
||||
url += "&"; |
|
||||
} |
|
||||
|
|
||||
url += query; |
|
||||
} |
|
||||
|
|
||||
return url; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 获取URL中指定参数的值,不存在返回空字符串
|
|
||||
/// </summary>
|
|
||||
public static string GetUrlQuery(this string url, string key) |
|
||||
{ |
|
||||
var uri = new Uri(url); |
|
||||
var query = uri.Query; |
|
||||
if (string.IsNullOrEmpty(query)) |
|
||||
{ |
|
||||
return string.Empty; |
|
||||
} |
|
||||
|
|
||||
query = query.TrimStart('?'); |
|
||||
var dict = (from m in query.Split("&", true) |
|
||||
let strs = m.Split("=") |
|
||||
select new KeyValuePair<string, string>(strs[0], strs[1])) |
|
||||
.ToDictionary(m => m.Key, m => m.Value); |
|
||||
if (dict.ContainsKey(key)) |
|
||||
{ |
|
||||
return dict[key]; |
|
||||
} |
|
||||
|
|
||||
return string.Empty; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 给URL添加 # 参数
|
|
||||
/// </summary>
|
|
||||
/// <param name="url">URL字符串</param>
|
|
||||
/// <param name="query">要添加的参数</param>
|
|
||||
/// <returns></returns>
|
|
||||
public static string AddHashFragment(this string url, string query) |
|
||||
{ |
|
||||
Guard.NotNull(url, nameof(url)); |
|
||||
Guard.NotNull(query, nameof(query)); |
|
||||
|
|
||||
if (!url.Contains("#")) |
|
||||
{ |
|
||||
url += "#"; |
|
||||
} |
|
||||
|
|
||||
return url + query; |
|
||||
} |
|
||||
|
|
||||
|
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 将<see cref="byte"/>[]数组转换为Base64字符串
|
|
||||
/// </summary>
|
|
||||
public static string ToBase64String(this byte[] bytes) |
|
||||
{ |
|
||||
Guard.NotNull(bytes, nameof(bytes)); |
|
||||
|
|
||||
return Convert.ToBase64String(bytes); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 将字符串转换为Base64字符串,默认编码为<see cref="Encoding.UTF8"/>
|
|
||||
/// </summary>
|
|
||||
/// <param name="source">正常的字符串</param>
|
|
||||
/// <param name="encoding">编码</param>
|
|
||||
/// <returns>Base64字符串</returns>
|
|
||||
public static string ToBase64String(this string source, Encoding encoding = null) |
|
||||
{ |
|
||||
Guard.NotNull(source, nameof(source)); |
|
||||
|
|
||||
if (encoding == null) encoding = Encoding.UTF8; |
|
||||
|
|
||||
return Convert.ToBase64String(encoding.GetBytes(source)); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 将Base64字符串转换为正常字符串,默认编码为<see cref="Encoding.UTF8"/>
|
|
||||
/// </summary>
|
|
||||
/// <param name="base64String">Base64字符串</param>
|
|
||||
/// <param name="encoding">编码</param>
|
|
||||
/// <returns>正常字符串</returns>
|
|
||||
public static string FromBase64String(this string base64String, Encoding encoding = null) |
|
||||
{ |
|
||||
Guard.NotNull(base64String, nameof(base64String)); |
|
||||
|
|
||||
if (encoding == null) encoding = Encoding.UTF8; |
|
||||
|
|
||||
var bytes = Convert.FromBase64String(base64String); |
|
||||
return encoding.GetString(bytes); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 将字符串进行UrlDecode解码
|
|
||||
/// </summary>
|
|
||||
/// <param name="source">待UrlDecode解码的字符串</param>
|
|
||||
/// <returns>UrlDecode解码后的字符串</returns>
|
|
||||
public static string ToUrlDecode(this string source) |
|
||||
{ |
|
||||
Guard.NotNull(source, nameof(source)); |
|
||||
|
|
||||
return HttpUtility.UrlDecode(source); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 将字符串进行UrlEncode编码
|
|
||||
/// </summary>
|
|
||||
/// <param name="source">待UrlEncode编码的字符串</param>
|
|
||||
/// <returns>UrlEncode编码后的字符串</returns>
|
|
||||
public static string ToUrlEncode(this string source) |
|
||||
{ |
|
||||
Guard.NotNull(source, nameof(source)); |
|
||||
|
|
||||
return HttpUtility.UrlEncode(source); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 将字符串进行HtmlDecode解码
|
|
||||
/// </summary>
|
|
||||
/// <param name="source">待HtmlDecode解码的字符串</param>
|
|
||||
/// <returns>HtmlDecode解码后的字符串</returns>
|
|
||||
public static string ToHtmlDecode(this string source) |
|
||||
{ |
|
||||
Guard.NotNull(source, nameof(source)); |
|
||||
|
|
||||
return HttpUtility.HtmlDecode(source); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 将字符串进行HtmlEncode编码
|
|
||||
/// </summary>
|
|
||||
/// <param name="source">待HtmlEncode编码的字符串</param>
|
|
||||
/// <returns>HtmlEncode编码后的字符串</returns>
|
|
||||
public static string ToHtmlEncode(this string source) |
|
||||
{ |
|
||||
Guard.NotNull(source, nameof(source)); |
|
||||
|
|
||||
return HttpUtility.HtmlEncode(source); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 将字符串转换为十六进制字符串,默认编码为<see cref="Encoding.UTF8"/>
|
|
||||
/// </summary>
|
|
||||
public static string ToHexString(this string source, Encoding encoding = null) |
|
||||
{ |
|
||||
Guard.NotNull(source, nameof(source)); |
|
||||
|
|
||||
if (encoding == null) encoding = Encoding.UTF8; |
|
||||
|
|
||||
byte[] bytes = encoding.GetBytes(source); |
|
||||
return bytes.ToHexString(); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 将十六进制字符串转换为常规字符串,默认编码为<see cref="Encoding.UTF8"/>
|
|
||||
/// </summary>
|
|
||||
public static string FromHexString(this string hexString, Encoding encoding = null) |
|
||||
{ |
|
||||
Guard.NotNull(hexString, nameof(hexString)); |
|
||||
|
|
||||
if (encoding == null) encoding = Encoding.UTF8; |
|
||||
|
|
||||
var bytes = hexString.ToHexBytes(); |
|
||||
return encoding.GetString(bytes); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 将byte[]编码为十六进制字符串
|
|
||||
/// </summary>
|
|
||||
/// <param name="bytes">byte[]数组</param>
|
|
||||
/// <returns>十六进制字符串</returns>
|
|
||||
public static string ToHexString(this byte[] bytes) |
|
||||
{ |
|
||||
Guard.NotNull(bytes, nameof(bytes)); |
|
||||
|
|
||||
return bytes.Aggregate(string.Empty, (current, t) => current + t.ToString("X2")); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 将十六进制字符串转换为byte[]
|
|
||||
/// </summary>
|
|
||||
/// <param name="hexString">十六进制字符串</param>
|
|
||||
/// <returns>byte[]数组</returns>
|
|
||||
public static byte[] ToHexBytes(this string hexString) |
|
||||
{ |
|
||||
hexString = hexString ?? ""; |
|
||||
hexString = hexString.Replace(" ", ""); |
|
||||
byte[] bytes = new byte[hexString.Length / 2]; |
|
||||
for (int i = 0; i < bytes.Length; i++) |
|
||||
{ |
|
||||
bytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16); |
|
||||
} |
|
||||
|
|
||||
return bytes; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 将字符串进行Unicode编码,变成形如“\u7f16\u7801”的形式
|
|
||||
/// </summary>
|
|
||||
/// <param name="source">要进行编号的字符串</param>
|
|
||||
public static string ToUnicodeString(this string source) |
|
||||
{ |
|
||||
Guard.NotNull(source, nameof(source)); |
|
||||
|
|
||||
var regex = new Regex(@"[^\u0000-\u00ff]"); |
|
||||
return regex.Replace(source, m => string.Format(@"\u{0:x4}", (short) m.Value[0])); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 将形如“\u7f16\u7801”的Unicode字符串解码
|
|
||||
/// </summary>
|
|
||||
public static string FromUnicodeString(this string source) |
|
||||
{ |
|
||||
var regex = new Regex(@"\\u([0-9a-fA-F]{4})", RegexOptions.Compiled); |
|
||||
return regex.Replace(source, |
|
||||
m => |
|
||||
{ |
|
||||
short s; |
|
||||
if (short.TryParse(m.Groups[1].Value, NumberStyles.HexNumber, CultureInfo.InstalledUICulture, |
|
||||
out s)) |
|
||||
{ |
|
||||
return "" + (char) s; |
|
||||
} |
|
||||
|
|
||||
return m.Value; |
|
||||
}); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 将驼峰字符串按单词拆分并转换成小写,再以特定字符串分隔
|
|
||||
/// </summary>
|
|
||||
/// <param name="str">待转换的字符串</param>
|
|
||||
/// <param name="splitStr">分隔符字符</param>
|
|
||||
/// <returns></returns>
|
|
||||
public static string UpperToLowerAndSplit(this string str, string splitStr = "-") |
|
||||
{ |
|
||||
if (string.IsNullOrEmpty(str)) |
|
||||
{ |
|
||||
return str; |
|
||||
} |
|
||||
|
|
||||
List<string> words = new List<string>(); |
|
||||
while (str.Length > 0) |
|
||||
{ |
|
||||
char c = str.FirstOrDefault(char.IsUpper); |
|
||||
if (c == default(char)) |
|
||||
{ |
|
||||
words.Add(str); |
|
||||
break; |
|
||||
} |
|
||||
|
|
||||
int upperIndex = str.IndexOf(c); |
|
||||
if (upperIndex < 0) //admin
|
|
||||
{ |
|
||||
return str; |
|
||||
} |
|
||||
|
|
||||
if (upperIndex > 0) //adminAdmin
|
|
||||
{ |
|
||||
string first = str.Substring(0, upperIndex); |
|
||||
words.Add(first); |
|
||||
str = str.Substring(upperIndex, str.Length - upperIndex); |
|
||||
continue; |
|
||||
} |
|
||||
|
|
||||
str = char.ToLower(str[0]) + str.Substring(1, str.Length - 1); |
|
||||
} |
|
||||
|
|
||||
return words.ExpandAndToString(splitStr); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 将驼峰字符串的第一个字符小写
|
|
||||
/// </summary>
|
|
||||
public static string LowerFirstChar(this string str) |
|
||||
{ |
|
||||
if (string.IsNullOrEmpty(str) || !char.IsUpper(str[0])) |
|
||||
{ |
|
||||
return str; |
|
||||
} |
|
||||
|
|
||||
if (str.Length == 1) |
|
||||
{ |
|
||||
return char.ToLower(str[0]).ToString(); |
|
||||
} |
|
||||
|
|
||||
return char.ToLower(str[0]) + str.Substring(1, str.Length - 1); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 将小驼峰字符串的第一个字符大写
|
|
||||
/// </summary>
|
|
||||
public static string UpperFirstChar(this string str) |
|
||||
{ |
|
||||
if (string.IsNullOrEmpty(str) || !char.IsLower(str[0])) |
|
||||
{ |
|
||||
return str; |
|
||||
} |
|
||||
|
|
||||
if (str.Length == 1) |
|
||||
{ |
|
||||
return char.ToUpper(str[0]).ToString(); |
|
||||
} |
|
||||
|
|
||||
return char.ToUpper(str[0]) + str.Substring(1, str.Length - 1); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 计算当前字符串与指定字符串的编辑距离(相似度)
|
|
||||
/// </summary>
|
|
||||
/// <param name="source">源字符串</param>
|
|
||||
/// <param name="target">目标字符串</param>
|
|
||||
/// <param name="similarity">输出相似度</param>
|
|
||||
/// <param name="ignoreCase">是否忽略大小写</param>
|
|
||||
/// <returns>编辑距离</returns>
|
|
||||
public static int LevenshteinDistance(this string source, string target, out double similarity, |
|
||||
bool ignoreCase = false) |
|
||||
{ |
|
||||
if (string.IsNullOrEmpty(source)) |
|
||||
{ |
|
||||
if (string.IsNullOrEmpty(target)) |
|
||||
{ |
|
||||
similarity = 1; |
|
||||
return 0; |
|
||||
} |
|
||||
|
|
||||
similarity = 0; |
|
||||
return target.Length; |
|
||||
} |
|
||||
|
|
||||
if (string.IsNullOrEmpty(target)) |
|
||||
{ |
|
||||
similarity = 0; |
|
||||
return source.Length; |
|
||||
} |
|
||||
|
|
||||
string from, to; |
|
||||
if (ignoreCase) |
|
||||
{ |
|
||||
from = source; |
|
||||
to = target; |
|
||||
} |
|
||||
else |
|
||||
{ |
|
||||
from = source.ToLower(); |
|
||||
to = source.ToLower(); |
|
||||
} |
|
||||
|
|
||||
int m = from.Length, n = to.Length; |
|
||||
int[,] mn = new int[m + 1, n + 1]; |
|
||||
for (int i = 0; i <= m; i++) |
|
||||
{ |
|
||||
mn[i, 0] = i; |
|
||||
} |
|
||||
|
|
||||
for (int j = 1; j <= n; j++) |
|
||||
{ |
|
||||
mn[0, j] = j; |
|
||||
} |
|
||||
|
|
||||
for (int i = 1; i <= m; i++) |
|
||||
{ |
|
||||
char c = from[i - 1]; |
|
||||
for (int j = 1; j <= n; j++) |
|
||||
{ |
|
||||
if (c == to[j - 1]) |
|
||||
{ |
|
||||
mn[i, j] = mn[i - 1, j - 1]; |
|
||||
} |
|
||||
else |
|
||||
{ |
|
||||
mn[i, j] = Math.Min(mn[i - 1, j - 1], Math.Min(mn[i - 1, j], mn[i, j - 1])) + 1; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
int maxLength = Math.Max(m, n); |
|
||||
similarity = (double) (maxLength - mn[m, n]) / maxLength; |
|
||||
return mn[m, n]; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 计算两个字符串的相似度,应用公式:相似度=kq*q/(kq*q+kr*r+ks*s)(kq>0,kr>=0,ka>=0)
|
|
||||
/// 其中,q是字符串1和字符串2中都存在的单词的总数,s是字符串1中存在,字符串2中不存在的单词总数,r是字符串2中存在,字符串1中不存在的单词总数. kq,kr和ka分别是q,r,s的权重,根据实际的计算情况,我们设kq=2,kr=ks=1.
|
|
||||
/// </summary>
|
|
||||
/// <param name="source">源字符串</param>
|
|
||||
/// <param name="target">目标字符串</param>
|
|
||||
/// <param name="ignoreCase">是否忽略大小写</param>
|
|
||||
/// <returns>字符串相似度</returns>
|
|
||||
public static double GetSimilarityWith(this string source, string target, bool ignoreCase = false) |
|
||||
{ |
|
||||
if (string.IsNullOrEmpty(source) && string.IsNullOrEmpty(target)) |
|
||||
{ |
|
||||
return 1; |
|
||||
} |
|
||||
|
|
||||
if (string.IsNullOrEmpty(source) || string.IsNullOrEmpty(target)) |
|
||||
{ |
|
||||
return 0; |
|
||||
} |
|
||||
|
|
||||
const double kq = 2, kr = 1, ks = 1; |
|
||||
char[] sourceChars = source.ToCharArray(), targetChars = target.ToCharArray(); |
|
||||
|
|
||||
//获取交集数量
|
|
||||
int q = sourceChars.Intersect(targetChars).Count(), s = sourceChars.Length - q, r = targetChars.Length - q; |
|
||||
return kq * q / (kq * q + kr * r + ks * s); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 标准化Path字符串,将 \\ 转换为 /
|
|
||||
/// </summary>
|
|
||||
/// <param name="path">Path字符串</param>
|
|
||||
public static string NormalizePath(this string path) |
|
||||
{ |
|
||||
return path.Replace('\\', '/'); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// (Pascal) 命名法 的字符串 改为 短横线分隔式命名
|
|
||||
/// 例如UserName => user-name
|
|
||||
/// </summary>
|
|
||||
public static string PascalToKebabCase(this string value) |
|
||||
{ |
|
||||
if (string.IsNullOrEmpty(value)) |
|
||||
{ |
|
||||
return value; |
|
||||
} |
|
||||
|
|
||||
return Regex.Replace( |
|
||||
value, |
|
||||
"(?<!^)([A-Z][a-z]|(?<=[a-z])[A-Z])", |
|
||||
"-$1", |
|
||||
RegexOptions.Compiled) |
|
||||
.Trim() |
|
||||
.ToLower(); |
|
||||
} |
|
||||
|
|
||||
#endregion
|
|
||||
} |
|
||||
} |
|
||||
@ -1,242 +0,0 @@ |
|||||
using System; |
|
||||
using System.Text; |
|
||||
using CompanyName.ProjectName.Extension.Customs; |
|
||||
|
|
||||
namespace CompanyName.ProjectName.Extension.System.Text |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// StringBuilder 扩展方法类
|
|
||||
/// </summary>
|
|
||||
public static class StringBuilderExtensions |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// 去除<seealso cref="StringBuilder"/>开头的空格
|
|
||||
/// </summary>
|
|
||||
/// <param name="stringBuilder"></param>
|
|
||||
/// <returns>返回修改后的StringBuilder,主要用于链式操作</returns>
|
|
||||
public static StringBuilder TrimStart(this StringBuilder stringBuilder) |
|
||||
{ |
|
||||
Guard.NotNull(stringBuilder, nameof(stringBuilder)); |
|
||||
|
|
||||
return stringBuilder.TrimStart(' '); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 去除<seealso cref="StringBuilder"/>开头的指定<seealso cref="char"/>
|
|
||||
/// </summary>
|
|
||||
/// <param name="stringBuilder"></param>
|
|
||||
/// <param name="c">要去掉的<seealso cref="char"/></param>
|
|
||||
/// <returns></returns>
|
|
||||
public static StringBuilder TrimStart(this StringBuilder stringBuilder, char c) |
|
||||
{ |
|
||||
Guard.NotNull(stringBuilder, nameof(stringBuilder)); |
|
||||
|
|
||||
if (stringBuilder.Length == 0) |
|
||||
return stringBuilder; |
|
||||
while (c.Equals(stringBuilder[0])) |
|
||||
{ |
|
||||
stringBuilder.Remove(0, 1); |
|
||||
} |
|
||||
|
|
||||
return stringBuilder; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 去除<seealso cref="StringBuilder"/>开头的指定字符数组
|
|
||||
/// </summary>
|
|
||||
/// <param name="stringBuilder"></param>
|
|
||||
/// <param name="chars">要去掉的字符数组</param>
|
|
||||
/// <returns></returns>
|
|
||||
public static StringBuilder TrimStart(this StringBuilder stringBuilder, char[] chars) |
|
||||
{ |
|
||||
Guard.NotNull(stringBuilder, nameof(stringBuilder)); |
|
||||
Guard.NotNull(chars, nameof(chars)); |
|
||||
|
|
||||
return stringBuilder.TrimStart(new string(chars)); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 去除<see cref="StringBuilder"/>开头的指定的<seealso cref="string"/>
|
|
||||
/// </summary>
|
|
||||
/// <param name="stringBuilder"></param>
|
|
||||
/// <param name="str">要去掉的<seealso cref="string"/></param>
|
|
||||
/// <returns></returns>
|
|
||||
public static StringBuilder TrimStart(this StringBuilder stringBuilder, string str) |
|
||||
{ |
|
||||
Guard.NotNull(stringBuilder, nameof(stringBuilder)); |
|
||||
|
|
||||
if (string.IsNullOrEmpty(str) |
|
||||
|| stringBuilder.Length == 0 |
|
||||
|| str.Length > stringBuilder.Length) |
|
||||
{ |
|
||||
return stringBuilder; |
|
||||
} |
|
||||
|
|
||||
while (stringBuilder.SubString(0, str.Length).Equals(str)) |
|
||||
{ |
|
||||
stringBuilder.Remove(0, str.Length); |
|
||||
if (str.Length > stringBuilder.Length) |
|
||||
{ |
|
||||
break; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
return stringBuilder; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 去除StringBuilder结尾的空格
|
|
||||
/// </summary>
|
|
||||
/// <param name="stringBuilder">StringBuilder</param>
|
|
||||
/// <returns>返回修改后的StringBuilder,主要用于链式操作</returns>
|
|
||||
public static StringBuilder TrimEnd(this StringBuilder stringBuilder) |
|
||||
{ |
|
||||
return stringBuilder.TrimEnd(' '); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 去除<see cref="StringBuilder"/>结尾指定字符
|
|
||||
/// </summary>
|
|
||||
/// <param name="stringBuilder"></param>
|
|
||||
/// <param name="c">要去掉的字符</param>
|
|
||||
/// <returns></returns>
|
|
||||
public static StringBuilder TrimEnd(this StringBuilder stringBuilder, char c) |
|
||||
{ |
|
||||
Guard.NotNull(stringBuilder, nameof(stringBuilder)); |
|
||||
if (stringBuilder.Length == 0) |
|
||||
{ |
|
||||
return stringBuilder; |
|
||||
} |
|
||||
|
|
||||
while (c.Equals(stringBuilder[stringBuilder.Length - 1])) |
|
||||
{ |
|
||||
stringBuilder.Remove(stringBuilder.Length - 1, 1); |
|
||||
} |
|
||||
|
|
||||
return stringBuilder; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 去除<see cref="StringBuilder"/>结尾指定字符数组
|
|
||||
/// </summary>
|
|
||||
/// <param name="stringBuilder"></param>
|
|
||||
/// <param name="chars">要去除的字符数组</param>
|
|
||||
/// <returns></returns>
|
|
||||
public static StringBuilder TrimEnd(this StringBuilder stringBuilder, char[] chars) |
|
||||
{ |
|
||||
Guard.NotNull(stringBuilder, nameof(stringBuilder)); |
|
||||
Guard.NotNull(chars, nameof(chars)); |
|
||||
|
|
||||
return stringBuilder.TrimEnd(new string(chars)); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 去除<see cref="StringBuilder"/>结尾指定字符串
|
|
||||
/// </summary>
|
|
||||
/// <param name="stringBuilder"></param>
|
|
||||
/// <param name="str">要去除的字符串</param>
|
|
||||
/// <returns></returns>
|
|
||||
public static StringBuilder TrimEnd(this StringBuilder stringBuilder, string str) |
|
||||
{ |
|
||||
Guard.NotNull(stringBuilder, nameof(stringBuilder)); |
|
||||
if (string.IsNullOrEmpty(str) |
|
||||
|| stringBuilder.Length == 0 |
|
||||
|| str.Length > stringBuilder.Length) |
|
||||
{ |
|
||||
return stringBuilder; |
|
||||
} |
|
||||
while (stringBuilder.SubString(stringBuilder.Length - str.Length, str.Length).Equals(str)) |
|
||||
{ |
|
||||
stringBuilder.Remove(stringBuilder.Length - str.Length, str.Length); |
|
||||
if (stringBuilder.Length < str.Length) |
|
||||
{ |
|
||||
break; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
return stringBuilder; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 去除StringBuilder两端的空格
|
|
||||
/// </summary>
|
|
||||
/// <param name="stringBuilder">StringBuilder</param>
|
|
||||
/// <returns>返回修改后的StringBuilder,主要用于链式操作</returns>
|
|
||||
public static StringBuilder Trim(this StringBuilder stringBuilder) |
|
||||
{ |
|
||||
Guard.NotNull(stringBuilder, nameof(stringBuilder)); |
|
||||
|
|
||||
if (stringBuilder.Length == 0) |
|
||||
return stringBuilder; |
|
||||
return stringBuilder.TrimEnd().TrimStart(); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 返回<see cref="StringBuilder"/>从起始位置指定长度的字符串
|
|
||||
/// </summary>
|
|
||||
/// <param name="stringBuilder"></param>
|
|
||||
/// <param name="start">起始位置</param>
|
|
||||
/// <param name="length">长度</param>
|
|
||||
/// <returns>字符串</returns>
|
|
||||
/// <exception cref="IndexOutOfRangeException">超出字符串索引长度异常</exception>
|
|
||||
public static string SubString(this StringBuilder stringBuilder, int start, int length) |
|
||||
{ |
|
||||
Guard.NotNull(stringBuilder, nameof(stringBuilder)); |
|
||||
|
|
||||
if (start + length > stringBuilder.Length) |
|
||||
{ |
|
||||
throw new IndexOutOfRangeException("超出字符串索引长度"); |
|
||||
} |
|
||||
|
|
||||
var cs = new char[length]; |
|
||||
for (var i = 0; i < length; i++) |
|
||||
{ |
|
||||
cs[i] = stringBuilder[start + i]; |
|
||||
} |
|
||||
|
|
||||
return new string(cs); |
|
||||
} |
|
||||
|
|
||||
public static StringBuilder AppendLineWithControlChar(this StringBuilder stringBuilder, StringBuilder sb, string newLine) |
|
||||
{ |
|
||||
stringBuilder = AppendWithControlChar(stringBuilder, sb.ToString()); |
|
||||
return stringBuilder.Append(newLine); |
|
||||
} |
|
||||
|
|
||||
public static StringBuilder AppendLineWithControlChar(this StringBuilder stringBuilder, string str, string newLine) |
|
||||
{ |
|
||||
stringBuilder = AppendWithControlChar(stringBuilder, str); |
|
||||
return stringBuilder.Append(newLine); |
|
||||
} |
|
||||
|
|
||||
public static StringBuilder AppendWithControlChar(this StringBuilder stringBuilder, StringBuilder sb) |
|
||||
{ |
|
||||
return AppendWithControlChar(stringBuilder, sb.ToString()); |
|
||||
} |
|
||||
|
|
||||
public static StringBuilder AppendWithControlChar(this StringBuilder stringBuilder, string str) |
|
||||
{ |
|
||||
if (str.Contains('\b')) |
|
||||
{ |
|
||||
foreach (var c in str) |
|
||||
{ |
|
||||
if (c == '\b') |
|
||||
{ |
|
||||
stringBuilder.Length--; |
|
||||
} |
|
||||
else |
|
||||
{ |
|
||||
stringBuilder.Append(c); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
else |
|
||||
{ |
|
||||
stringBuilder.Append(str); |
|
||||
} |
|
||||
|
|
||||
return stringBuilder; |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,26 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
|
||||
|
namespace Lion.AbpPro.Extension.Customs.Dtos |
||||
|
{ |
||||
|
[Serializable] |
||||
|
public class CustomeListResultDto<T> |
||||
|
{ |
||||
|
public IReadOnlyList<T> Items |
||||
|
{ |
||||
|
get { return _items ??= new List<T>(); } |
||||
|
set => _items = value; |
||||
|
} |
||||
|
|
||||
|
private IReadOnlyList<T> _items; |
||||
|
|
||||
|
public CustomeListResultDto() |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
public CustomeListResultDto(IReadOnlyList<T> items) |
||||
|
{ |
||||
|
Items = items; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,21 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
|
||||
|
namespace Lion.AbpPro.Extension.Customs.Dtos |
||||
|
{ |
||||
|
[Serializable] |
||||
|
public class CustomePagedResultDto<T> : CustomeListResultDto<T> |
||||
|
{ |
||||
|
public long TotalCount { get; set; } |
||||
|
|
||||
|
public CustomePagedResultDto() |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
public CustomePagedResultDto(long totalCount, IReadOnlyList<T> items) |
||||
|
: base(items) |
||||
|
{ |
||||
|
TotalCount = totalCount; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,41 @@ |
|||||
|
namespace Lion.AbpPro.Extension.Customs.Dtos |
||||
|
{ |
||||
|
|
||||
|
|
||||
|
public abstract class FromSelectorBase |
||||
|
{ |
||||
|
protected FromSelectorBase(int value, string label) |
||||
|
{ |
||||
|
Value = value; |
||||
|
Label = label; |
||||
|
} |
||||
|
public int Value { get; protected set; } |
||||
|
public string Label { get; protected set; } |
||||
|
} |
||||
|
|
||||
|
public abstract class FromSelectorBase<TValue, TLabel> |
||||
|
{ |
||||
|
protected FromSelectorBase(TValue value, TLabel label) |
||||
|
{ |
||||
|
Value = value; |
||||
|
Label = label; |
||||
|
} |
||||
|
|
||||
|
public TValue Value { get; protected set; } |
||||
|
public TLabel Label { get; protected set; } |
||||
|
} |
||||
|
|
||||
|
public class FromSelector : FromSelectorBase |
||||
|
{ |
||||
|
public FromSelector(int value, string label) : base(value, label) |
||||
|
{ |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public class FromSelector<TValue, TLabel> : FromSelectorBase<TValue, TLabel> |
||||
|
{ |
||||
|
public FromSelector(TValue value, TLabel label) : base(value, label) |
||||
|
{ |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,9 @@ |
|||||
|
using System; |
||||
|
|
||||
|
namespace Lion.AbpPro.Extension.Customs.Dtos |
||||
|
{ |
||||
|
public class IdInput |
||||
|
{ |
||||
|
public Guid Id { get; set; } |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,59 @@ |
|||||
|
using System.Collections.Generic; |
||||
|
using System.ComponentModel.DataAnnotations; |
||||
|
|
||||
|
namespace Lion.AbpPro.Extension.Customs.Dtos |
||||
|
{ |
||||
|
|
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 分页查询时使用的Dto类型
|
||||
|
/// </summary>
|
||||
|
public class PagingBase : IValidatableObject |
||||
|
{ |
||||
|
public const int MaxPageSize = 100000; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 当前页面.默认从1开始
|
||||
|
/// </summary>
|
||||
|
public int PageIndex { get; set; } = 1; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 每页多少条.每页显示多少记录
|
||||
|
/// </summary>
|
||||
|
public int PageSize { get; set; } = 10; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 跳过多少条
|
||||
|
/// </summary>
|
||||
|
public int SkipCount => (PageIndex - 1) * PageSize; |
||||
|
|
||||
|
protected PagingBase() |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
public PagingBase(int pageIndex = 1, int pageSize = 10) |
||||
|
{ |
||||
|
PageIndex = pageIndex; |
||||
|
PageSize = pageSize; |
||||
|
} |
||||
|
|
||||
|
public virtual IEnumerable<ValidationResult> Validate(ValidationContext validationContext) |
||||
|
{ |
||||
|
if (PageIndex < 1) |
||||
|
{ |
||||
|
yield return new ValidationResult( |
||||
|
"起始页必须大于等于1", |
||||
|
new[] { "PageIndex"} |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
if (PageSize > MaxPageSize) |
||||
|
{ |
||||
|
yield return new ValidationResult( |
||||
|
$"每页最大记录数不能超过'{MaxPageSize}'", |
||||
|
new[] { "PageSize"} |
||||
|
); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,271 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Diagnostics; |
||||
|
using System.IO; |
||||
|
using System.Linq; |
||||
|
|
||||
|
namespace Lion.AbpPro.Extension.Customs |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// 参数合法性检查类
|
||||
|
/// </summary>
|
||||
|
[DebuggerStepThrough] |
||||
|
public static class Guard |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// 检查参数不能为空引用,
|
||||
|
/// </summary>
|
||||
|
/// <param name="value"></param>
|
||||
|
/// <param name="valueName">参数名称</param>
|
||||
|
public static T NotNull<T>(T value, string valueName) |
||||
|
{ |
||||
|
if (null == value) |
||||
|
{ |
||||
|
throw new ArgumentNullException(valueName); |
||||
|
} |
||||
|
|
||||
|
return value; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 检查字符串不能为空引用或空字符串,
|
||||
|
/// </summary>
|
||||
|
/// <param name="value"></param>
|
||||
|
/// <param name="valueName">参数名称。</param>
|
||||
|
/// <param name="maxLength">字符串允许的最大长度。</param>
|
||||
|
/// <param name="minLength">字符串允许的最小长度。0表示不限制最小长度</param>
|
||||
|
public static string NotNullOrEmpty(string value, string valueName, int maxLength = int.MaxValue, |
||||
|
int minLength = 0) |
||||
|
{ |
||||
|
if (string.IsNullOrEmpty(value)) |
||||
|
{ |
||||
|
throw new ArgumentNullException(valueName); |
||||
|
} |
||||
|
|
||||
|
if (value.Length > maxLength) |
||||
|
{ |
||||
|
throw new ArgumentOutOfRangeException(valueName); |
||||
|
} |
||||
|
|
||||
|
if (minLength > 0 && value.Length < minLength) |
||||
|
{ |
||||
|
throw new ArgumentOutOfRangeException(valueName); |
||||
|
} |
||||
|
|
||||
|
return value; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 检查字符串不能为空引用或全部为空白,
|
||||
|
/// </summary>
|
||||
|
/// <param name="value">需检查的字符串</param>
|
||||
|
/// <param name="valueName">参数名称。</param>
|
||||
|
/// <param name="maxLength">字符串允许的最大长度。</param>
|
||||
|
/// <param name="minLength">字符串允许的最小长度。0表示不限制最小长度</param>
|
||||
|
public static string NotNullOrWhiteSpace( |
||||
|
string value, |
||||
|
string valueName, |
||||
|
int maxLength = int.MaxValue, |
||||
|
int minLength = 0) |
||||
|
{ |
||||
|
if (string.IsNullOrWhiteSpace(value)) |
||||
|
{ |
||||
|
throw new ArgumentNullException(valueName); |
||||
|
} |
||||
|
|
||||
|
if (value.Length > maxLength) |
||||
|
{ |
||||
|
throw new ArgumentOutOfRangeException(valueName); |
||||
|
} |
||||
|
|
||||
|
if (minLength > 0 && value.Length < minLength) |
||||
|
{ |
||||
|
throw new ArgumentOutOfRangeException(valueName); |
||||
|
} |
||||
|
|
||||
|
return value; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 检查字符串长度是否超过最大长度,或低于最小长度,
|
||||
|
/// </summary>
|
||||
|
/// <param name="value">需检查的字符串。</param>
|
||||
|
/// <param name="valueName">参数名称。</param>
|
||||
|
/// <param name="maxLength">字符串允许的最大长度。</param>
|
||||
|
/// <param name="minLength">字符串要求的最小长度。0表示不限制最小长度</param>
|
||||
|
public static string Length(string value, string valueName, int maxLength = int.MaxValue, |
||||
|
int minLength = 0) |
||||
|
{ |
||||
|
if (string.IsNullOrEmpty(value)) |
||||
|
{ |
||||
|
return value; |
||||
|
} |
||||
|
|
||||
|
if (value.Length > maxLength) |
||||
|
{ |
||||
|
throw new ArgumentOutOfRangeException(valueName); |
||||
|
} |
||||
|
|
||||
|
if (minLength > 0 && value.Length < minLength) |
||||
|
{ |
||||
|
throw new ArgumentOutOfRangeException(valueName); |
||||
|
} |
||||
|
|
||||
|
return value; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 检查Guid值不能为Guid.Empty
|
||||
|
/// </summary>
|
||||
|
/// <param name="value"></param>
|
||||
|
/// <param name="valueName">参数名称。</param>
|
||||
|
public static Guid NotEmpty( |
||||
|
Guid value, |
||||
|
string valueName) |
||||
|
{ |
||||
|
if (value == Guid.Empty) |
||||
|
{ |
||||
|
throw new ArgumentNullException(valueName); |
||||
|
} |
||||
|
|
||||
|
return value; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 检查集合不能为空引用或空集合,
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="T">集合项的类型。</typeparam>
|
||||
|
/// <param name="list"></param>
|
||||
|
/// <param name="valueName">参数名称。</param>
|
||||
|
public static void NotNullOrEmpty<T>( |
||||
|
IReadOnlyList<T> list, |
||||
|
string valueName) |
||||
|
{ |
||||
|
if (null == list || !list.Any()) |
||||
|
{ |
||||
|
throw new ArgumentNullException(valueName); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 检查参数必须小于[或可等于,参数<paramref name="canEqual"/>]指定值,
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="T">参数类型。</typeparam>
|
||||
|
/// <param name="value"></param>
|
||||
|
/// <param name="valueName">参数名称。</param>
|
||||
|
/// <param name="target">要比较的值。</param>
|
||||
|
/// <param name="canEqual">是否可等于。</param>
|
||||
|
public static void LessThan<T>( |
||||
|
T value, |
||||
|
string valueName, |
||||
|
T target, |
||||
|
bool canEqual = false) |
||||
|
where T : IComparable<T> |
||||
|
{ |
||||
|
var flag = canEqual ? value.CompareTo(target) <= 0 : value.CompareTo(target) < 0; |
||||
|
if (!flag) |
||||
|
{ |
||||
|
throw new ArgumentOutOfRangeException(valueName); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 检查参数必须大于[或可等于,参数<paramref name="canEqual"/>]指定值,
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="T">参数类型。</typeparam>
|
||||
|
/// <param name="value">需检查的参数。</param>
|
||||
|
/// <param name="valueName">参数名称。</param>
|
||||
|
/// <param name="target">要比较的值。</param>
|
||||
|
/// <param name="canEqual">是否可等于。</param>
|
||||
|
public static void GreaterThan<T>( |
||||
|
T value, |
||||
|
string valueName, |
||||
|
T target, |
||||
|
bool canEqual = false) |
||||
|
where T : IComparable<T> |
||||
|
{ |
||||
|
var flag = canEqual ? value.CompareTo(target) >= 0 : value.CompareTo(target) > 0; |
||||
|
if (!flag) |
||||
|
{ |
||||
|
throw new ArgumentOutOfRangeException(valueName); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 检查参数必须在指定范围之间
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="T">参数类型。</typeparam>
|
||||
|
/// <param name="value">需检查的参数。</param>
|
||||
|
/// <param name="valueName">参数名称。</param>
|
||||
|
/// <param name="start">比较范围的起始值。</param>
|
||||
|
/// <param name="end">比较范围的结束值。</param>
|
||||
|
/// <param name="startEqual">是否可等于起始值</param>
|
||||
|
/// <param name="endEqual">是否可等于结束值</param>
|
||||
|
public static void Between<T>( |
||||
|
T value, |
||||
|
string valueName, |
||||
|
T start, |
||||
|
T end, |
||||
|
bool startEqual = false, |
||||
|
bool endEqual = false) |
||||
|
where T : IComparable<T> |
||||
|
{ |
||||
|
var flag = startEqual ? value.CompareTo(start) >= 0 : value.CompareTo(start) > 0; |
||||
|
if (!flag) |
||||
|
{ |
||||
|
throw new ArgumentOutOfRangeException(valueName); |
||||
|
} |
||||
|
|
||||
|
flag = endEqual ? value.CompareTo(end) <= 0 : value.CompareTo(end) < 0; |
||||
|
if (!flag) |
||||
|
{ |
||||
|
throw new ArgumentOutOfRangeException(valueName); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 检查指定路径的文件夹必须存在,
|
||||
|
/// </summary>
|
||||
|
/// <param name="directory">需检查的路径。</param>
|
||||
|
/// <param name="parameterName">参数名称。</param>
|
||||
|
public static string DirectoryExists( |
||||
|
string directory, |
||||
|
string parameterName) |
||||
|
{ |
||||
|
if (string.IsNullOrWhiteSpace(directory)) |
||||
|
{ |
||||
|
throw new DirectoryNotFoundException(parameterName); |
||||
|
} |
||||
|
|
||||
|
if (!Directory.Exists(directory)) |
||||
|
{ |
||||
|
throw new DirectoryNotFoundException(directory); |
||||
|
} |
||||
|
|
||||
|
return directory; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 检查指定路径的文件必须存在,否则抛出
|
||||
|
/// </summary>
|
||||
|
/// <param name="filename"></param>
|
||||
|
/// <param name="valueName">参数名称。</param>
|
||||
|
|
||||
|
public static string FileExists( |
||||
|
string filename, |
||||
|
string valueName) |
||||
|
{ |
||||
|
if (string.IsNullOrWhiteSpace(filename)) |
||||
|
{ |
||||
|
throw new ArgumentNullException(valueName); |
||||
|
} |
||||
|
|
||||
|
if (!File.Exists(filename)) |
||||
|
{ |
||||
|
throw new FileNotFoundException(filename); |
||||
|
} |
||||
|
|
||||
|
return filename; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,164 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Net.Http; |
||||
|
using System.Net.Http.Headers; |
||||
|
using System.Text; |
||||
|
using System.Threading.Tasks; |
||||
|
using Newtonsoft.Json; |
||||
|
|
||||
|
namespace Lion.AbpPro.Extension.Customs.Http |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// 基于IHttpClientFactory二次封装httpclient
|
||||
|
/// </summary>
|
||||
|
public static class HttpClientHelper |
||||
|
{ |
||||
|
|
||||
|
public static async Task<TResult> GetAsync<TResult>(this IHttpClientFactory _httpClientFactory, string clientName, string url, Dictionary<string, string> headers = null) where TResult : class |
||||
|
{ |
||||
|
try |
||||
|
{ |
||||
|
var client = _httpClientFactory.CreateClient(clientName); |
||||
|
if (headers != null && headers.Count > 0) |
||||
|
{ |
||||
|
foreach (var item in headers) |
||||
|
{ |
||||
|
client.DefaultRequestHeaders.Add(item.Key, item.Value); |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
client.DefaultRequestHeaders.CacheControl = CacheControlHeaderValue.Parse("no-cache"); |
||||
|
|
||||
|
//执行请求
|
||||
|
var response = await client.GetAsync(url); |
||||
|
var result = await response.Content.ReadAsStringAsync(); |
||||
|
if (response.IsSuccessStatusCode) |
||||
|
{ |
||||
|
if (result != null && !string.IsNullOrEmpty(result)) |
||||
|
return JsonConvert.DeserializeObject<TResult>(result); |
||||
|
else |
||||
|
return default(TResult); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
if (string.IsNullOrEmpty(result)) |
||||
|
result = response.ReasonPhrase; |
||||
|
throw new Exception(result); |
||||
|
} |
||||
|
} |
||||
|
catch (Exception e) |
||||
|
{ |
||||
|
throw new Exception(e.Message); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public static async Task<TResult> PostAsync<T, TResult>(this IHttpClientFactory _httpClientFactory, string clientName, string url, T obj, Dictionary<string, string> headers = null) where T : class where TResult : class |
||||
|
{ |
||||
|
var data = typeof(T).Name.ToLower() == "string" ? obj.ToString() : JsonConvert.SerializeObject(obj); |
||||
|
var client = _httpClientFactory.CreateClient(clientName); |
||||
|
if (headers != null && headers.Count > 0) |
||||
|
{ |
||||
|
foreach (var item in headers) |
||||
|
{ |
||||
|
client.DefaultRequestHeaders.Add(item.Key, item.Value); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
client.DefaultRequestHeaders.CacheControl = CacheControlHeaderValue.Parse("no-cache"); |
||||
|
//post 参数
|
||||
|
var content = new StringContent(data, Encoding.UTF8, "application/json"); |
||||
|
//执行请求
|
||||
|
var response = await client.PostAsync(url, content); |
||||
|
|
||||
|
var result = await response.Content.ReadAsStringAsync(); |
||||
|
if (response.IsSuccessStatusCode) |
||||
|
{ |
||||
|
if (result != null && !string.IsNullOrEmpty(result)) |
||||
|
return JsonConvert.DeserializeObject<TResult>(result); |
||||
|
else |
||||
|
return default(TResult); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
if (string.IsNullOrEmpty(result)) |
||||
|
result = response.ReasonPhrase; |
||||
|
|
||||
|
throw new Exception(result); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public static async Task<TResult> PutAsync<T, TResult>(this IHttpClientFactory _httpClientFactory, string clientName, string url, T obj, Dictionary<string, string> headers = null) where T : class where TResult : class |
||||
|
{ |
||||
|
var data = typeof(T).Name.ToLower() == "string" ? obj.ToString() : JsonConvert.SerializeObject(obj); |
||||
|
var client = _httpClientFactory.CreateClient(clientName); |
||||
|
if (headers != null && headers.Count > 0) |
||||
|
{ |
||||
|
foreach (var item in headers) |
||||
|
{ |
||||
|
client.DefaultRequestHeaders.Add(item.Key, item.Value); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
client.DefaultRequestHeaders.CacheControl = CacheControlHeaderValue.Parse("no-cache"); |
||||
|
//post 参数
|
||||
|
var content = new StringContent(data, Encoding.UTF8, "application/json"); |
||||
|
//执行请求
|
||||
|
var response = await client.PutAsync(url, content); |
||||
|
|
||||
|
var result = await response.Content.ReadAsStringAsync(); |
||||
|
if (response.IsSuccessStatusCode) |
||||
|
{ |
||||
|
if (result != null && !string.IsNullOrEmpty(result)) |
||||
|
return JsonConvert.DeserializeObject<TResult>(result); |
||||
|
else |
||||
|
return default(TResult); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
if (string.IsNullOrEmpty(result)) |
||||
|
result = response.ReasonPhrase; |
||||
|
|
||||
|
throw new Exception(result); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public static async Task<TResult> DeleteAsync<TResult>(this IHttpClientFactory _httpClientFactory, string clientName, string url, Dictionary<string, string> headers = null) where TResult : class |
||||
|
{ |
||||
|
try |
||||
|
{ |
||||
|
var client = _httpClientFactory.CreateClient(clientName); |
||||
|
if (headers != null && headers.Count > 0) |
||||
|
{ |
||||
|
foreach (var item in headers) |
||||
|
{ |
||||
|
client.DefaultRequestHeaders.Add(item.Key, item.Value); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
client.DefaultRequestHeaders.CacheControl = CacheControlHeaderValue.Parse("no-cache"); |
||||
|
|
||||
|
//执行请求
|
||||
|
var response = await client.DeleteAsync(url); |
||||
|
var result = await response.Content.ReadAsStringAsync(); |
||||
|
if (response.IsSuccessStatusCode) |
||||
|
{ |
||||
|
if (result != null && !string.IsNullOrEmpty(result)) |
||||
|
return JsonConvert.DeserializeObject<TResult>(result); |
||||
|
else |
||||
|
return default(TResult); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
if (string.IsNullOrEmpty(result)) |
||||
|
result = response.ReasonPhrase; |
||||
|
throw new Exception(result); |
||||
|
} |
||||
|
} |
||||
|
catch (Exception e) |
||||
|
{ |
||||
|
throw new Exception(e.Message); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,20 @@ |
|||||
|
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
|
||||
|
<Import Project="..\..\..\..\common.props" /> |
||||
|
<PropertyGroup> |
||||
|
<TargetFramework>net6.0</TargetFramework> |
||||
|
</PropertyGroup> |
||||
|
<ItemGroup> |
||||
|
<PackageReference Include="Microsoft.Extensions.DependencyModel" Version="$(MicrosoftExtensionsDependencyModelVersion)" /> |
||||
|
<PackageReference Include="Microsoft.Extensions.Http" Version="$(MicrosoftVersion)" /> |
||||
|
<PackageReference Include="Newtonsoft.Json" Version="$(NewtonsoftJsonVersion)" /> |
||||
|
<PackageReference Include="System.ComponentModel.Annotations" Version="$(SystemComponentModelAnnotationsVersion)" /> |
||||
|
<PackageReference Include="Volo.Abp.Autofac" Version="$(AbpPackageVersion)" /> |
||||
|
<PackageReference Include="Volo.Abp.Json" Version="$(AbpPackageVersion)" /> |
||||
|
<PackageReference Include="Volo.Abp.Validation" Version="$(AbpPackageVersion)" /> |
||||
|
<PackageReference Include="Volo.Abp.Ddd.Domain" Version="$(AbpPackageVersion)" /> |
||||
|
<PackageReference Include="Volo.Abp.AutoMapper" Version="$(AbpPackageVersion)" /> |
||||
|
<PackageReference Include="Volo.Abp.ObjectMapping" Version="$(AbpPackageVersion)" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
</Project> |
||||
@ -0,0 +1,29 @@ |
|||||
|
using System; |
||||
|
|
||||
|
namespace Lion.AbpPro.Extension.System |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// 布尔值<see cref="Boolean"/>类型的扩展辅助操作类
|
||||
|
/// </summary>
|
||||
|
public static class BooleanExtensions |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// 把布尔值转换为小写字符串
|
||||
|
/// </summary>
|
||||
|
public static string ToLower(this bool value) |
||||
|
{ |
||||
|
return value.ToString().ToLower(); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 如果条件成立,则抛出异常
|
||||
|
/// </summary>
|
||||
|
public static void TrueThrow(this bool flag, Exception exception) |
||||
|
{ |
||||
|
if (flag) |
||||
|
{ |
||||
|
throw exception; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,79 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using Lion.AbpPro.Extension.Customs; |
||||
|
|
||||
|
namespace Lion.AbpPro.Extension.System.Collections.Generic |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// 集合扩展方法
|
||||
|
/// </summary>
|
||||
|
public static class CollectionExtensions |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// 如果条件成立,添加项
|
||||
|
/// </summary>
|
||||
|
public static void AddIf<T>(this ICollection<T> collection, T value, bool flag) |
||||
|
{ |
||||
|
Guard.NotNull(collection, nameof(collection)); |
||||
|
if (flag) |
||||
|
{ |
||||
|
collection.Add(value); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 如果条件成立,添加项
|
||||
|
/// </summary>
|
||||
|
public static void AddIf<T>(this ICollection<T> collection, T value, Func<bool> func) |
||||
|
{ |
||||
|
Guard.NotNull(collection, nameof(collection)); |
||||
|
if (func()) |
||||
|
{ |
||||
|
collection.Add(value); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 获取对象,不存在对使用委托添加对象
|
||||
|
/// </summary>
|
||||
|
public static T GetOrAdd<T>(this ICollection<T> collection, Func<T, bool> selector, Func<T> factory) |
||||
|
{ |
||||
|
Guard.NotNull(collection, nameof(collection)); |
||||
|
T item = collection.FirstOrDefault(selector); |
||||
|
if (item == null) |
||||
|
{ |
||||
|
item = factory(); |
||||
|
collection.Add(item); |
||||
|
} |
||||
|
|
||||
|
return item; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 判断集合是否为null或空集合
|
||||
|
/// </summary>
|
||||
|
public static bool IsNullOrEmpty<T>(this ICollection<T> collection) |
||||
|
{ |
||||
|
return collection == null || collection.Count == 0; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 交换两项的位置
|
||||
|
/// </summary>
|
||||
|
public static void Swap<T>(this List<T> list, int index1, int index2) |
||||
|
{ |
||||
|
Guard.Between(index1, nameof(index1), 0, list.Count, true); |
||||
|
Guard.Between(index2, nameof(index2), 0, list.Count, true); |
||||
|
|
||||
|
if (index1 == index2) |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
T tmp = list[index1]; |
||||
|
list[index1] = list[index2]; |
||||
|
list[index2] = tmp; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,202 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using System.Text; |
||||
|
using Lion.AbpPro.Extension.Customs; |
||||
|
|
||||
|
namespace Lion.AbpPro.Extension.System.Collections.Generic |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Enumerable集合扩展方法
|
||||
|
/// </summary>
|
||||
|
public static class EnumerableExtensions |
||||
|
{ |
||||
|
/// <summary>断言集合中的元素符合指定表达式,否则抛出异常。</summary>
|
||||
|
/// <typeparam name="T">集合项类型</typeparam>
|
||||
|
/// <param name="source">源集合</param>
|
||||
|
/// <param name="predicate">元素判断表达式</param>
|
||||
|
/// <param name="errorSelector">异常选择器</param>
|
||||
|
/// <returns>筛选过的集合</returns>
|
||||
|
public static IEnumerable<T> Assert<T>(this IEnumerable<T> source, Func<T, bool> predicate, |
||||
|
Func<T, Exception> errorSelector = null) |
||||
|
{ |
||||
|
foreach (var item in source) |
||||
|
{ |
||||
|
var success = predicate(item); |
||||
|
if (!success) |
||||
|
{ |
||||
|
throw errorSelector?.Invoke(item) ?? |
||||
|
new InvalidOperationException("集合中包含无效的元素。"); |
||||
|
} |
||||
|
|
||||
|
yield return item; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 打乱一个集合的项顺序,将一个集合洗牌
|
||||
|
/// </summary>
|
||||
|
public static IEnumerable<TSource> Shuffle<TSource>(this IEnumerable<TSource> source) |
||||
|
{ |
||||
|
// ReSharper disable PossibleMultipleEnumeration
|
||||
|
|
||||
|
Guard.NotNull(source, nameof(source)); |
||||
|
return source.OrderBy(m => Guid.NewGuid()); |
||||
|
|
||||
|
// ReSharper restore PossibleMultipleEnumeration
|
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 将集合展开并分别转换成字符串,再以指定的分隔符衔接,拼成一个字符串返回。默认分隔符为逗号。
|
||||
|
/// </summary>
|
||||
|
/// <param name="collection">要处理的集合</param>
|
||||
|
/// <param name="separator">分隔符,默认为逗号</param>
|
||||
|
/// <returns>拼接后的字符串</returns>
|
||||
|
public static string ExpandAndToString<T>(this IEnumerable<T> collection, string separator = ",") |
||||
|
{ |
||||
|
return collection.ExpandAndToString(item => item?.ToString() ?? string.Empty, separator); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 循环集合的每一项,调用委托生成字符串,返回合并后的字符串。默认分隔符为逗号
|
||||
|
/// </summary>
|
||||
|
/// <param name="collection">待处理的集合</param>
|
||||
|
/// <param name="itemFormatFunc">单个集合项的转换委托</param>
|
||||
|
/// <param name="separator">分隔符,默认为逗号</param>
|
||||
|
/// <typeparam name="T">泛型类型</typeparam>
|
||||
|
/// <returns></returns>
|
||||
|
public static string ExpandAndToString<T>( |
||||
|
this IEnumerable<T> collection, |
||||
|
Func<T, string> itemFormatFunc, |
||||
|
string separator = ",") |
||||
|
{ |
||||
|
collection = collection as IList<T> ?? collection.ToList(); |
||||
|
Guard.NotNull(itemFormatFunc, nameof(itemFormatFunc)); |
||||
|
|
||||
|
if (!collection.Any()) |
||||
|
{ |
||||
|
return string.Empty; |
||||
|
} |
||||
|
|
||||
|
var sb = new StringBuilder(); |
||||
|
var i = 0; |
||||
|
var count = collection.Count(); |
||||
|
foreach (var item in collection) |
||||
|
{ |
||||
|
if (i == count - 1) |
||||
|
{ |
||||
|
sb.Append(itemFormatFunc(item)); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
sb.Append(itemFormatFunc(item) + separator); |
||||
|
} |
||||
|
|
||||
|
i++; |
||||
|
} |
||||
|
|
||||
|
return sb.ToString(); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 集合是否为空
|
||||
|
/// </summary>
|
||||
|
/// <param name="collection"> 要处理的集合 </param>
|
||||
|
/// <typeparam name="T"> 动态类型 </typeparam>
|
||||
|
/// <returns> 为空返回True,不为空返回False </returns>
|
||||
|
public static bool IsEmpty<T>(this IEnumerable<T> collection) |
||||
|
{ |
||||
|
collection = collection as IList<T> ?? collection.ToList(); |
||||
|
return !collection.Any(); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 根据第三方条件是否为真来决定是否执行指定条件的查询
|
||||
|
/// </summary>
|
||||
|
/// <param name="source"> 要查询的源 </param>
|
||||
|
/// <param name="predicate"> 查询条件 </param>
|
||||
|
/// <param name="condition"> 第三方条件 </param>
|
||||
|
/// <typeparam name="T"> 动态类型 </typeparam>
|
||||
|
/// <returns> 查询的结果 </returns>
|
||||
|
public static IEnumerable<T> WhereIf<T>(this IEnumerable<T> source, Func<T, bool> predicate, bool condition) |
||||
|
{ |
||||
|
Guard.NotNull(predicate, nameof(predicate)); |
||||
|
source = source as IList<T> ?? source.ToList(); |
||||
|
|
||||
|
return condition ? source.Where(predicate) : source; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 将字符串集合按指定前缀排序
|
||||
|
/// </summary>
|
||||
|
public static IEnumerable<T> OrderByPrefixes<T>(this IEnumerable<T> source, Func<T, string> keySelector, |
||||
|
params string[] prefixes) |
||||
|
{ |
||||
|
var all = source.OrderBy(keySelector).ToList(); |
||||
|
var result = new List<T>(); |
||||
|
foreach (var prefix in prefixes) |
||||
|
{ |
||||
|
var tmpList = all.Where(m => keySelector(m).StartsWith(prefix)).OrderBy(keySelector).ToList(); |
||||
|
all = all.Except(tmpList).ToList(); |
||||
|
result.AddRange(tmpList); |
||||
|
} |
||||
|
|
||||
|
result.AddRange(all); |
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 根据指定条件返回集合中不重复的元素
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="T">动态类型</typeparam>
|
||||
|
/// <typeparam name="TKey">动态筛选条件类型</typeparam>
|
||||
|
/// <param name="source">要操作的源</param>
|
||||
|
/// <param name="keySelector">重复数据筛选条件</param>
|
||||
|
/// <returns>不重复元素的集合</returns>
|
||||
|
public static IEnumerable<T> DistinctBy<T, TKey>(this IEnumerable<T> source, Func<T, TKey> keySelector) |
||||
|
{ |
||||
|
Guard.NotNull(keySelector, nameof(keySelector)); |
||||
|
source = source as IList<T> ?? source.ToList(); |
||||
|
|
||||
|
return source.GroupBy(keySelector).Select(group => group.First()); |
||||
|
} |
||||
|
|
||||
|
#region Internal
|
||||
|
|
||||
|
internal static int? TryGetCollectionCount<T>(this IEnumerable<T> source) |
||||
|
{ |
||||
|
switch (source) |
||||
|
{ |
||||
|
case null: |
||||
|
throw new ArgumentNullException(nameof(source)); |
||||
|
case ICollection<T> collection: |
||||
|
return collection.Count; |
||||
|
case IReadOnlyCollection<T> collection: |
||||
|
return collection.Count; |
||||
|
default: |
||||
|
return null; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
static int CountUpTo<T>(this IEnumerable<T> source, int max) |
||||
|
{ |
||||
|
if (source == null) throw new ArgumentNullException(nameof(source)); |
||||
|
if (max < 0) |
||||
|
throw new ArgumentOutOfRangeException(nameof(max), "最大计数参数不能为负。"); |
||||
|
|
||||
|
var count = 0; |
||||
|
|
||||
|
using (var e = source.GetEnumerator()) |
||||
|
{ |
||||
|
while (count < max && e.MoveNext()) |
||||
|
{ |
||||
|
count++; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return count; |
||||
|
} |
||||
|
|
||||
|
#endregion
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,79 @@ |
|||||
|
using System; |
||||
|
using System.Globalization; |
||||
|
using System.Linq; |
||||
|
|
||||
|
namespace Lion.AbpPro.Extension.System |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// 时间扩展操作类
|
||||
|
/// </summary>
|
||||
|
public static class DateTimeExtensions |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// 当前时间是否周末
|
||||
|
/// </summary>
|
||||
|
/// <param name="dateTime">时间点</param>
|
||||
|
/// <returns></returns>
|
||||
|
public static bool IsWeekend(this DateTime dateTime) |
||||
|
{ |
||||
|
DayOfWeek[] weeks = { DayOfWeek.Saturday, DayOfWeek.Sunday }; |
||||
|
return weeks.Contains(dateTime.DayOfWeek); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 当前时间是否工作日
|
||||
|
/// </summary>
|
||||
|
/// <param name="dateTime">时间点</param>
|
||||
|
/// <returns></returns>
|
||||
|
public static bool IsWeekday(this DateTime dateTime) |
||||
|
{ |
||||
|
DayOfWeek[] weeks = { DayOfWeek.Monday, DayOfWeek.Tuesday, DayOfWeek.Wednesday, DayOfWeek.Thursday, DayOfWeek.Friday }; |
||||
|
return weeks.Contains(dateTime.DayOfWeek); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 获取时间相对唯一字符串
|
||||
|
/// </summary>
|
||||
|
/// <param name="dateTime"></param>
|
||||
|
/// <param name="millisecond">是否使用毫秒</param>
|
||||
|
/// <returns></returns>
|
||||
|
public static string ToUniqueString(this DateTime dateTime, bool millisecond = false) |
||||
|
{ |
||||
|
var seconds = dateTime.Hour * 3600 + dateTime.Minute * 60 + dateTime.Second; |
||||
|
var value = $"{dateTime:yyyy}{dateTime.DayOfYear}{seconds}"; |
||||
|
if (millisecond) |
||||
|
{ |
||||
|
return value + dateTime.ToString("fff"); |
||||
|
} |
||||
|
|
||||
|
return value; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 将时间转换为JS时间格式(Date.getTime())
|
||||
|
/// </summary>
|
||||
|
/// <param name="dateTime"></param>
|
||||
|
/// <param name="millisecond">是否使用毫秒</param>
|
||||
|
public static string ToJsGetTime(this DateTime dateTime, bool millisecond = true) |
||||
|
{ |
||||
|
var utc = dateTime.ToUniversalTime(); |
||||
|
var span = utc.Subtract(new DateTime(1970, 1, 1)); |
||||
|
return Math.Round(millisecond ? span.TotalMilliseconds : span.TotalSeconds).ToString(CultureInfo.InvariantCulture); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 将JS时间格式的数值转换为时间
|
||||
|
/// </summary>
|
||||
|
public static DateTime FromJsGetTime(this long jsTime) |
||||
|
{ |
||||
|
var length = jsTime.ToString().Length; |
||||
|
if (!(length == 10 || length == 13)) |
||||
|
{ |
||||
|
throw new ArgumentOutOfRangeException(null, "JS时间数值的长度不正确,必须为10位或13位"); |
||||
|
} |
||||
|
var start = new DateTime(1970, 1, 1); |
||||
|
var result = length == 10 ? start.AddSeconds(jsTime) : start.AddMilliseconds(jsTime); |
||||
|
return result.ToUniversalTime(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,200 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Collections.Specialized; |
||||
|
using System.ComponentModel; |
||||
|
using System.Linq; |
||||
|
using System.Reflection; |
||||
|
using Lion.AbpPro.Extension.System.Reflection; |
||||
|
|
||||
|
namespace Lion.AbpPro.Extension.System |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// 枚举<see cref="Enum"/>的扩展辅助操作方法
|
||||
|
/// </summary>
|
||||
|
public static class EnumExtensions |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// 获取枚举项上的<see cref="DescriptionAttribute"/>特性的文字描述
|
||||
|
/// </summary>
|
||||
|
/// <param name="value"></param>
|
||||
|
/// <returns></returns>
|
||||
|
public static string ToDescription(this Enum value) |
||||
|
{ |
||||
|
var type = value.GetType(); |
||||
|
var member = type.GetMember(value.ToString()).FirstOrDefault(); |
||||
|
|
||||
|
return member != null ? member.GetDescription() : value.ToString(); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 枚举遍历,返回枚举的名称、值、特性
|
||||
|
/// </summary>
|
||||
|
/// <param name="enumType">枚举类型</param>
|
||||
|
/// <param name="action">回调函数</param>
|
||||
|
private static void Each(this Type enumType, Action<string, string, string, object> action) |
||||
|
{ |
||||
|
if (enumType.BaseType != typeof(Enum)) |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
var arr = Enum.GetValues(enumType); |
||||
|
foreach (var name in arr) |
||||
|
{ |
||||
|
var currentEnum = Enum.Parse(enumType, name.ToString()); |
||||
|
var value = Convert.ToInt32(Enum.Parse(enumType, name.ToString())); |
||||
|
var fieldInfo = enumType.GetField(name.ToString()); |
||||
|
var description = ""; |
||||
|
if (fieldInfo != null) |
||||
|
{ |
||||
|
var attr = Attribute.GetCustomAttribute(fieldInfo, |
||||
|
typeof(DescriptionAttribute), false) as DescriptionAttribute; |
||||
|
if (attr != null) |
||||
|
{ |
||||
|
description = attr.Description; |
||||
|
} |
||||
|
} |
||||
|
action(name.ToString(), value.ToString(), description, currentEnum); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 根据枚举类型值返回枚举定义Description属性
|
||||
|
/// </summary>
|
||||
|
/// <param name="value"></param>
|
||||
|
/// <param name="enumType"></param>
|
||||
|
/// <returns></returns>
|
||||
|
public static string ToEnumDescriptionString(this short value, Type enumType) |
||||
|
{ |
||||
|
var nvc = new NameValueCollection(); |
||||
|
var typeDescription = typeof(DescriptionAttribute); |
||||
|
var fields = enumType.GetFields(); |
||||
|
foreach (var field in fields) |
||||
|
{ |
||||
|
if (field.FieldType.IsEnum) |
||||
|
{ |
||||
|
var strValue = ((int)enumType.InvokeMember(field.Name, BindingFlags.GetField, null, null, null)).ToString(); |
||||
|
var arr = field.GetCustomAttributes(typeDescription, true); |
||||
|
string strText; |
||||
|
if (arr.Length > 0) |
||||
|
{ |
||||
|
var aa = (DescriptionAttribute)arr[0]; |
||||
|
strText = aa.Description; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
strText = ""; |
||||
|
} |
||||
|
nvc.Add(strValue, strText); |
||||
|
} |
||||
|
} |
||||
|
return nvc[value.ToString()]; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 将指定枚举转换为字典.
|
||||
|
/// 枚举的Description为字典的Key,枚举的Value为字典的Value
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="T">指定枚举</typeparam>
|
||||
|
private static List<KeyValuePair<string, string>> GetEnumTypeValueList<T>() |
||||
|
{ |
||||
|
var items = new List<KeyValuePair<string, string>>(); |
||||
|
typeof(T).Each((name, value, description, enumObj) => |
||||
|
items.Add(new KeyValuePair<string, string>(description, value))); |
||||
|
return items; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 将指定枚举转换为字典.
|
||||
|
/// 枚举的Description为字典的Key,枚举为字典的Value
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="T">指定枚举</typeparam>
|
||||
|
private static List<KeyValuePair<string, T>> GetEnumTypeList<T>() |
||||
|
{ |
||||
|
var items = new List<KeyValuePair<string, T>>(); |
||||
|
typeof(T).Each((name, value, description, enumObj) => |
||||
|
items.Add(new KeyValuePair<string, T>(description, (T)enumObj))); |
||||
|
return items; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 将指定枚举转换为字典.
|
||||
|
/// 枚举的Description为字典的Key,枚举的Name为字典的Value
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="T">指定枚举</typeparam>
|
||||
|
public static List<KeyValuePair<string, string>> GetEnumTypeDescriptionNameList<T>() |
||||
|
{ |
||||
|
var items = new List<KeyValuePair<string, string>>(); |
||||
|
typeof(T).Each((name, value, description, enumObj) => items.Add(new KeyValuePair<string, string>(description, name))); |
||||
|
return items; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 将指定枚举转换为字典.
|
||||
|
/// 枚举的Name为字典的Key,枚举的Description为字典的Value
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="T">指定枚举</typeparam>
|
||||
|
public static List<KeyValuePair<string, string>> GetEnumTypeValueNameList<T>() |
||||
|
{ |
||||
|
var items = new List<KeyValuePair<string, string>>(); |
||||
|
typeof(T).Each((name, value, description, enumObj) => items.Add(new KeyValuePair<string, string>(name, description))); |
||||
|
return items; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 将指定枚举转换为字典.
|
||||
|
/// 枚举的Name为字典的Key,枚举的Description为字典的Value
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TModel">指定枚举</typeparam>
|
||||
|
public static List<KeyValuePair<string, string>> GetStringKeyValueList<TModel>() where TModel : Enum |
||||
|
{ |
||||
|
var keyValuePairList = new List<KeyValuePair<string, string>>(); |
||||
|
var values = Enum.GetValues(typeof(TModel)); |
||||
|
var modelArray = new TModel[values.Length]; |
||||
|
values.CopyTo(modelArray, 0); |
||||
|
foreach (TModel model in modelArray) |
||||
|
keyValuePairList.Add(new KeyValuePair<string, string>(model.ToString(), model.ToString())); |
||||
|
return keyValuePairList; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 将指定枚举转换为字典.
|
||||
|
/// 枚举的Description为字典的Key,枚举为字典的Value
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TModel">指定枚举</typeparam>
|
||||
|
public static List<KeyValuePair<string, TModel>> GetEnumKeyValueList<TModel>() where TModel : Enum |
||||
|
{ |
||||
|
var enumTypeList = GetEnumTypeList<TModel>(); |
||||
|
var keyValuePairList = new List<KeyValuePair<string, TModel>>(); |
||||
|
foreach (KeyValuePair<string, TModel> keyValuePair in enumTypeList) |
||||
|
keyValuePairList.Add(new KeyValuePair<string, TModel>(keyValuePair.Key, keyValuePair.Value)); |
||||
|
return keyValuePairList; |
||||
|
} |
||||
|
|
||||
|
public static List<KeyValuePair<string, string>> GetEntityDoubleStringKeyValueList<TModel>() |
||||
|
{ |
||||
|
var enumTypeList = GetEnumTypeValueList<TModel>(); |
||||
|
var keyValuePairList = new List<KeyValuePair<string, string>>(); |
||||
|
foreach (KeyValuePair<string, string> keyValuePair in enumTypeList) |
||||
|
keyValuePairList.Add(new KeyValuePair<string, string>(keyValuePair.Key, keyValuePair.Value)); |
||||
|
return keyValuePairList; |
||||
|
} |
||||
|
|
||||
|
public static List<KeyValuePair<string, int>> GetEntityStringIntKeyValueList<TModel>() |
||||
|
{ |
||||
|
List<KeyValuePair<string, string>> enumTypeList = GetEnumTypeValueList<TModel>(); |
||||
|
List<KeyValuePair<string, int>> keyValuePairList = new List<KeyValuePair<string, int>>(); |
||||
|
foreach (KeyValuePair<string, string> keyValuePair in enumTypeList) |
||||
|
keyValuePairList.Add(new KeyValuePair<string, int>(keyValuePair.Key, Convert.ToInt32(keyValuePair.Value))); |
||||
|
return keyValuePairList; |
||||
|
} |
||||
|
|
||||
|
public static List<KeyValuePair<int, int>> GetEntityDoubleIntKeyValueList<TModel>() |
||||
|
{ |
||||
|
List<KeyValuePair<string, string>> enumTypeList = GetEnumTypeValueList<TModel>(); |
||||
|
List<KeyValuePair<int, int>> keyValuePairList = new List<KeyValuePair<int, int>>(); |
||||
|
foreach (KeyValuePair<string, string> keyValuePair in enumTypeList) |
||||
|
keyValuePairList.Add(new KeyValuePair<int, int>(Convert.ToInt32(keyValuePair.Key), Convert.ToInt32(keyValuePair.Value))); |
||||
|
return keyValuePairList; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,77 @@ |
|||||
|
using System; |
||||
|
using System.Runtime.ExceptionServices; |
||||
|
using System.Text; |
||||
|
|
||||
|
namespace Lion.AbpPro.Extension.System |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// 异常操作扩展
|
||||
|
/// </summary>
|
||||
|
public static class ExceptionExtensions |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// 格式化异常消息
|
||||
|
/// </summary>
|
||||
|
/// <param name="e">异常对象</param>
|
||||
|
/// <param name="isHideStackTrace">是否隐藏异常规模信息</param>
|
||||
|
/// <returns>格式化后的异常信息字符串</returns>
|
||||
|
public static string FormatMessage(this Exception e, bool isHideStackTrace = false) |
||||
|
{ |
||||
|
var sb = new StringBuilder(); |
||||
|
var count = 0; |
||||
|
var appString = string.Empty; |
||||
|
while (e != null) |
||||
|
{ |
||||
|
if (count > 0) |
||||
|
{ |
||||
|
appString += " "; |
||||
|
} |
||||
|
sb.AppendLine($"{appString}异常消息:{e.Message}"); |
||||
|
sb.AppendLine($"{appString}异常类型:{e.GetType().FullName}"); |
||||
|
sb.AppendLine($"{appString}异常方法:{(e.TargetSite == null ? null : e.TargetSite.Name)}"); |
||||
|
sb.AppendLine($"{appString}异常源:{e.Source}"); |
||||
|
if (!isHideStackTrace && e.StackTrace != null) |
||||
|
{ |
||||
|
sb.AppendLine($"{appString}异常堆栈:{e.StackTrace}"); |
||||
|
} |
||||
|
if (e.InnerException != null) |
||||
|
{ |
||||
|
sb.AppendLine($"{appString}内部异常:"); |
||||
|
count++; |
||||
|
e = e.InnerException; |
||||
|
} |
||||
|
} |
||||
|
return sb.ToString(); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 将异常重新抛出
|
||||
|
/// </summary>
|
||||
|
public static void ReThrow(this Exception exception) |
||||
|
{ |
||||
|
ExceptionDispatchInfo.Capture(exception).Throw(); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 如果条件成立,则抛出异常
|
||||
|
/// </summary>
|
||||
|
public static void ThrowIf(this Exception exception, bool isThrow) |
||||
|
{ |
||||
|
if (isThrow) |
||||
|
{ |
||||
|
throw exception; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 如果条件成立,则抛出异常
|
||||
|
/// </summary>
|
||||
|
public static void ThrowIf(this Exception exception, Func<bool> isThrowFunc) |
||||
|
{ |
||||
|
if (isThrowFunc()) |
||||
|
{ |
||||
|
throw exception; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,30 @@ |
|||||
|
using System; |
||||
|
using System.Linq; |
||||
|
using System.Linq.Expressions; |
||||
|
using Lion.AbpPro.Extension.Customs; |
||||
|
|
||||
|
namespace Lion.AbpPro.Extension.System.Linq |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// IQueryable集合扩展方法
|
||||
|
/// </summary>
|
||||
|
public static class QueryableExtensions |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// 根据第三方条件是否为真来决定是否执行指定条件的查询
|
||||
|
/// </summary>
|
||||
|
/// <param name="source"> 要查询的源 </param>
|
||||
|
/// <param name="predicate"> 查询条件 </param>
|
||||
|
/// <param name="condition"> 第三方条件 </param>
|
||||
|
/// <typeparam name="T"> 动态类型 </typeparam>
|
||||
|
/// <returns> 查询的结果 </returns>
|
||||
|
public static IQueryable<T> WhereIf<T>(this IQueryable<T> source, Expression<Func<T, bool>> predicate, |
||||
|
bool condition) |
||||
|
{ |
||||
|
Guard.NotNull(source, nameof(source)); |
||||
|
Guard.NotNull(predicate, nameof(predicate)); |
||||
|
|
||||
|
return condition ? source.Where(predicate) : source; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,27 @@ |
|||||
|
using System.Diagnostics; |
||||
|
using System.Reflection; |
||||
|
using Lion.AbpPro.Extension.Customs; |
||||
|
|
||||
|
namespace Lion.AbpPro.Extension.System.Reflection |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// 程序集扩展操作类
|
||||
|
/// </summary>
|
||||
|
public static class AssemblyExtensions |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// 获取程序集的产品版本
|
||||
|
/// </summary>
|
||||
|
public static string GetProductVersion(this Assembly assembly) |
||||
|
{ |
||||
|
Guard.NotNull(assembly, nameof(assembly)); |
||||
|
var info = FileVersionInfo.GetVersionInfo(assembly.Location); |
||||
|
var version = info.ProductVersion; |
||||
|
if (version.Contains("+")) |
||||
|
{ |
||||
|
version = version.ReplaceRegex(@"\+(\w+)?", ""); |
||||
|
} |
||||
|
return version; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,75 @@ |
|||||
|
using System; |
||||
|
using System.ComponentModel; |
||||
|
using System.ComponentModel.DataAnnotations; |
||||
|
using System.Linq; |
||||
|
using System.Reflection; |
||||
|
|
||||
|
namespace Lion.AbpPro.Extension.System.Reflection |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// 成员<see cref="MemberInfo"/>的扩展辅助操作方法
|
||||
|
/// </summary>
|
||||
|
public static class MemberInfoExtensions |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// 获取成员元数据的Description特性描述信息。
|
||||
|
/// </summary>
|
||||
|
/// <param name="member">成员元数据对象。</param>
|
||||
|
/// <param name="inherit">是否搜索成员的继承链以查找描述特性。</param>
|
||||
|
/// <returns>返回Description特性描述信息,如不存在则返回成员的名称。</returns>
|
||||
|
public static string GetDescription(this MemberInfo member, bool inherit = true) |
||||
|
{ |
||||
|
var desc = member.GetAttribute<DescriptionAttribute>(inherit); |
||||
|
if (desc != null) |
||||
|
{ |
||||
|
return desc.Description; |
||||
|
} |
||||
|
|
||||
|
var displayName = member.GetAttribute<DisplayNameAttribute>(inherit); |
||||
|
if (displayName != null) |
||||
|
{ |
||||
|
return displayName.DisplayName; |
||||
|
} |
||||
|
|
||||
|
var display = member.GetAttribute<DisplayAttribute>(inherit); |
||||
|
return display != null ? display.Name : member.Name; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 检查指定指定类型成员中是否存在指定的Attribute特性。
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="T">要检查的Attribute特性类型。</typeparam>
|
||||
|
/// <param name="memberInfo">要检查的类型成员</param>
|
||||
|
/// <param name="inherit">是否从继承中查找</param>
|
||||
|
/// <returns>是否存在</returns>
|
||||
|
public static bool HasAttribute<T>(this MemberInfo memberInfo, bool inherit = true) where T : Attribute |
||||
|
{ |
||||
|
return memberInfo.IsDefined(typeof(T), inherit); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 从类型成员获取指定Attribute特性
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="T">Attribute特性类型</typeparam>
|
||||
|
/// <param name="memberInfo">类型类型成员</param>
|
||||
|
/// <param name="inherit">是否从继承中查找</param>
|
||||
|
/// <returns>存在返回第一个,不存在返回null</returns>
|
||||
|
public static T GetAttribute<T>(this MemberInfo memberInfo, bool inherit = true) where T : Attribute |
||||
|
{ |
||||
|
var attributes = memberInfo.GetCustomAttributes(typeof(T), inherit); |
||||
|
return attributes.FirstOrDefault() as T; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 从类型成员获取指定Attribute特性。
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="T">Attribute特性类型。</typeparam>
|
||||
|
/// <param name="memberInfo">类型类型成员。</param>
|
||||
|
/// <param name="inherit">是否从继承中查找。</param>
|
||||
|
/// <returns>返回所有指定Attribute特性的数组。</returns>
|
||||
|
public static T[] GetAttributes<T>(this MemberInfo memberInfo, bool inherit = true) where T : Attribute |
||||
|
{ |
||||
|
return memberInfo.GetCustomAttributes(typeof(T), inherit).Cast<T>().ToArray(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,32 @@ |
|||||
|
using System.Reflection; |
||||
|
using System.Threading.Tasks; |
||||
|
|
||||
|
namespace Lion.AbpPro.Extension.System.Reflection |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// 方法<see cref="MethodInfo"/>的扩展辅助操作方法
|
||||
|
/// </summary>
|
||||
|
public static class MethodInfoExtensions |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// 方法是否是异步
|
||||
|
/// </summary>
|
||||
|
public static bool IsAsync(this MethodInfo method) |
||||
|
{ |
||||
|
return (method.ReturnType == typeof(Task<>) |
||||
|
|| method.ReturnType.IsGenericType |
||||
|
&& method.ReturnType.GetGenericTypeDefinition() == typeof(Task<>)) |
||||
|
|| method.ReturnType == typeof(Task); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 返回当前方法信息是否是重写方法
|
||||
|
/// </summary>
|
||||
|
/// <param name="method">要判断的方法信息</param>
|
||||
|
/// <returns>是否是重写方法</returns>
|
||||
|
public static bool IsOverridden(this MethodInfo method) |
||||
|
{ |
||||
|
return method.GetBaseDefinition().DeclaringType != method.DeclaringType; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,25 @@ |
|||||
|
using System.Linq; |
||||
|
using System.Reflection; |
||||
|
|
||||
|
namespace Lion.AbpPro.Extension.System.Reflection |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// 属性<see cref="MethodInfo"/>的扩展辅助操作方法
|
||||
|
/// </summary>
|
||||
|
public static class PropertyInfoExtensions |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// 返回当前属性信息是否为virtual
|
||||
|
/// </summary>
|
||||
|
public static bool IsVirtual(this PropertyInfo property) |
||||
|
{ |
||||
|
var accessor = property.GetAccessors().FirstOrDefault(); |
||||
|
if (accessor == null) |
||||
|
{ |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
return accessor.IsVirtual && !accessor.IsFinal; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,983 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Diagnostics; |
||||
|
using System.Globalization; |
||||
|
using System.Linq; |
||||
|
using System.Text; |
||||
|
using System.Text.RegularExpressions; |
||||
|
using System.Web; |
||||
|
using Lion.AbpPro.Extension.Customs; |
||||
|
using Lion.AbpPro.Extension.System.Collections.Generic; |
||||
|
using Newtonsoft.Json; |
||||
|
|
||||
|
namespace Lion.AbpPro.Extension.System |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// 字符串<see cref="string"/>类型的扩展辅助操作类
|
||||
|
/// </summary>
|
||||
|
[DebuggerStepThrough] |
||||
|
public static class StringExtensions |
||||
|
{ |
||||
|
#region 正则表达式
|
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 指示所指定的正则表达式在指定的输入字符串中是否找到了匹配项
|
||||
|
/// </summary>
|
||||
|
/// <param name="value">要搜索匹配项的字符串</param>
|
||||
|
/// <param name="pattern">要匹配的正则表达式模式</param>
|
||||
|
/// <param name="isContains">是否包含,否则全匹配</param>
|
||||
|
/// <returns>如果正则表达式找到匹配项,则为 true;否则,为 false</returns>
|
||||
|
public static bool IsMatch(this string value, string pattern, bool isContains = true) |
||||
|
{ |
||||
|
if (value == null) |
||||
|
{ |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
return isContains |
||||
|
? Regex.IsMatch(value, pattern) |
||||
|
: Regex.Match(value, pattern).Success; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 在指定的输入字符串中搜索指定的正则表达式的第一个匹配项
|
||||
|
/// </summary>
|
||||
|
/// <param name="value">要搜索匹配项的字符串</param>
|
||||
|
/// <param name="pattern">要匹配的正则表达式模式</param>
|
||||
|
/// <returns>一个对象,包含有关匹配项的信息</returns>
|
||||
|
public static string Match(this string value, string pattern) |
||||
|
{ |
||||
|
if (value == null) |
||||
|
{ |
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
return Regex.Match(value, pattern).Value; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 在指定的输入字符串中匹配并替换符合指定正则表达式的子串
|
||||
|
/// </summary>
|
||||
|
public static string ReplaceRegex(this string value, string pattern, string replacement) |
||||
|
{ |
||||
|
if (value == null) |
||||
|
{ |
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
return Regex.Replace(value, pattern, replacement); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 在指定的输入字符串中搜索指定的正则表达式的所有匹配项的字符串集合
|
||||
|
/// </summary>
|
||||
|
/// <param name="value"> 要搜索匹配项的字符串 </param>
|
||||
|
/// <param name="pattern"> 要匹配的正则表达式模式 </param>
|
||||
|
/// <returns> 一个集合,包含有关匹配项的字符串值 </returns>
|
||||
|
public static IEnumerable<string> Matches(this string value, string pattern) |
||||
|
{ |
||||
|
if (value == null) |
||||
|
{ |
||||
|
return new string[] { }; |
||||
|
} |
||||
|
|
||||
|
var matches = Regex.Matches(value, pattern); |
||||
|
return from Match match in matches select match.Value; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 在指定的输入字符串中匹配第一个数字字符串
|
||||
|
/// </summary>
|
||||
|
public static string MatchFirstNumber(this string value) |
||||
|
{ |
||||
|
var matches = Regex.Matches(value, @"\d+"); |
||||
|
if (matches.Count == 0) |
||||
|
{ |
||||
|
return string.Empty; |
||||
|
} |
||||
|
|
||||
|
return matches[0].Value; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 在指定字符串中匹配最后一个数字字符串
|
||||
|
/// </summary>
|
||||
|
public static string MatchLastNumber(this string value) |
||||
|
{ |
||||
|
var matches = Regex.Matches(value, @"\d+"); |
||||
|
if (matches.Count == 0) |
||||
|
{ |
||||
|
return string.Empty; |
||||
|
} |
||||
|
|
||||
|
return matches[matches.Count - 1].Value; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 在指定字符串中匹配所有数字字符串
|
||||
|
/// </summary>
|
||||
|
public static IEnumerable<string> MatchNumbers(this string value) |
||||
|
{ |
||||
|
return Matches(value, @"\d+"); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 检测指定字符串中是否包含数字
|
||||
|
/// </summary>
|
||||
|
public static bool IsMatchNumber(this string value) |
||||
|
{ |
||||
|
return IsMatch(value, @"\d"); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 检测指定字符串是否全部为数字并且长度等于指定长度
|
||||
|
/// </summary>
|
||||
|
public static bool IsMatchNumber(this string value, int length) |
||||
|
{ |
||||
|
var regex = new Regex(@"^\d{" + length + "}$"); |
||||
|
return regex.IsMatch(value); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 截取指定字符串之间的字符串
|
||||
|
/// </summary>
|
||||
|
/// <param name="source"></param>
|
||||
|
/// <param name="startString">起始字符串</param>
|
||||
|
/// <param name="endStrings">结束字符串,可多个</param>
|
||||
|
/// <returns>返回的中间字符串</returns>
|
||||
|
public static string Substring(this string source, string startString, params string[] endStrings) |
||||
|
{ |
||||
|
if (source.IsMissing()) |
||||
|
{ |
||||
|
return string.Empty; |
||||
|
} |
||||
|
|
||||
|
var startIndex = 0; |
||||
|
if (!string.IsNullOrEmpty(startString)) |
||||
|
{ |
||||
|
startIndex = source.IndexOf(startString, StringComparison.OrdinalIgnoreCase); |
||||
|
if (startIndex < 0) |
||||
|
{ |
||||
|
throw new InvalidOperationException($"在源字符串中无法找到“{startString}”的子串位置"); |
||||
|
} |
||||
|
|
||||
|
startIndex += startString.Length; |
||||
|
} |
||||
|
|
||||
|
var endIndex = source.Length; |
||||
|
endStrings = endStrings.OrderByDescending(m => m.Length).ToArray(); |
||||
|
foreach (var endString in endStrings) |
||||
|
{ |
||||
|
if (string.IsNullOrEmpty(endString)) |
||||
|
{ |
||||
|
endIndex = source.Length; |
||||
|
break; |
||||
|
} |
||||
|
|
||||
|
endIndex = source.IndexOf(endString, startIndex, StringComparison.OrdinalIgnoreCase); |
||||
|
if (endIndex < 0 || endIndex < startIndex) |
||||
|
{ |
||||
|
continue; |
||||
|
} |
||||
|
|
||||
|
break; |
||||
|
} |
||||
|
|
||||
|
if (endIndex < 0 || endIndex < startIndex) |
||||
|
{ |
||||
|
throw new InvalidOperationException($"在源字符串中无法找到“{endStrings.ExpandAndToString()}”的子串位置"); |
||||
|
} |
||||
|
|
||||
|
var length = endIndex - startIndex; |
||||
|
|
||||
|
return source.Substring(startIndex, length); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 用正则表达式截取字符串
|
||||
|
/// </summary>
|
||||
|
public static string Substring2(this string source, string startString, string endString) |
||||
|
{ |
||||
|
return source.Substring2(startString, endString, false); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 用正则表达式截取字符串
|
||||
|
/// </summary>
|
||||
|
public static string Substring2(this string source, string startString, string endString, bool containsEmpty) |
||||
|
{ |
||||
|
if (source.IsMissing()) |
||||
|
{ |
||||
|
return string.Empty; |
||||
|
} |
||||
|
|
||||
|
var inner = containsEmpty ? "\\s\\S" : "\\S"; |
||||
|
var result = source.Match($"(?<={startString})([{inner}]+?)(?={endString})"); |
||||
|
return result.IsMissing() ? null : result; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 是否电子邮件
|
||||
|
/// </summary>
|
||||
|
public static bool IsEmail(this string value) |
||||
|
{ |
||||
|
const string pattern = @"^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$"; |
||||
|
return value.IsMatch(pattern); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 是否是IP地址
|
||||
|
/// </summary>
|
||||
|
public static bool IsIpAddress(this string value) |
||||
|
{ |
||||
|
const string pattern = |
||||
|
@"^((?:(?:25[0-5]|2[0-4]\d|((1\d{2})|([1-9]?\d)))\.){3}(?:25[0-5]|2[0-4]\d|((1\d{2})|([1-9]?\d))))$"; |
||||
|
return value.IsMatch(pattern); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 是否是整数
|
||||
|
/// </summary>
|
||||
|
public static bool IsNumeric(this string value) |
||||
|
{ |
||||
|
const string pattern = @"^\-?[0-9]+$"; |
||||
|
return value.IsMatch(pattern); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 是否是Unicode字符串
|
||||
|
/// </summary>
|
||||
|
public static bool IsUnicode(this string value) |
||||
|
{ |
||||
|
const string pattern = @"^[\u4E00-\u9FA5\uE815-\uFA29]+$"; |
||||
|
return value.IsMatch(pattern); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 是否Url字符串
|
||||
|
/// </summary>
|
||||
|
public static bool IsUrl(this string value) |
||||
|
{ |
||||
|
try |
||||
|
{ |
||||
|
if (string.IsNullOrEmpty(value) || value.Contains(' ')) |
||||
|
{ |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
var uri = new Uri(value); |
||||
|
return true; |
||||
|
} |
||||
|
catch (Exception) |
||||
|
{ |
||||
|
return false; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 是否身份证号,验证如下3种情况:
|
||||
|
/// 1.身份证号码为15位数字;
|
||||
|
/// 2.身份证号码为18位数字;
|
||||
|
/// 3.身份证号码为17位数字+1个字母
|
||||
|
/// </summary>
|
||||
|
public static bool IsIdentityCardId(this string value) |
||||
|
{ |
||||
|
if (value.Length != 15 && value.Length != 18) |
||||
|
{ |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
Regex regex; |
||||
|
string[] array; |
||||
|
if (value.Length == 15) |
||||
|
{ |
||||
|
regex = new Regex(@"^(\d{6})(\d{2})(\d{2})(\d{2})(\d{3})_"); |
||||
|
if (!regex.Match(value).Success) |
||||
|
{ |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
array = regex.Split(value); |
||||
|
return DateTime.TryParse(string.Format("{0}-{1}-{2}", "19" + array[2], array[3], array[4]), out _); |
||||
|
} |
||||
|
|
||||
|
regex = new Regex(@"^(\d{6})(\d{4})(\d{2})(\d{2})(\d{3})([0-9Xx])$"); |
||||
|
if (!regex.Match(value).Success) |
||||
|
{ |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
array = regex.Split(value); |
||||
|
if (!DateTime.TryParse(string.Format("{0}-{1}-{2}", array[2], array[3], array[4]), out _)) |
||||
|
{ |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
//校验最后一位
|
||||
|
var chars = value.ToCharArray().Select(m => m.ToString()).ToArray(); |
||||
|
int[] weights = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2}; |
||||
|
var sum = 0; |
||||
|
for (var i = 0; i < 17; i++) |
||||
|
{ |
||||
|
var num = int.Parse(chars[i]); |
||||
|
sum += num * weights[i]; |
||||
|
} |
||||
|
|
||||
|
var mod = sum % 11; |
||||
|
var vCode = "10X98765432"; // 检验码字符串
|
||||
|
var last = vCode.ToCharArray().ElementAt(mod).ToString(); |
||||
|
return chars.Last().ToUpper() == last; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 是否手机号码
|
||||
|
/// </summary>
|
||||
|
/// <param name="value"></param>
|
||||
|
/// <param name="isRestrict">是否按严格格式验证</param>
|
||||
|
public static bool IsMobileNumber(this string value, bool isRestrict = false) |
||||
|
{ |
||||
|
var pattern = isRestrict ? @"^[1][3-8]\d{9}$" : @"^[1]\d{10}$"; |
||||
|
return value.IsMatch(pattern); |
||||
|
} |
||||
|
|
||||
|
#endregion
|
||||
|
|
||||
|
#region 其他操作
|
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 判断指定的字符串不是 null、空。
|
||||
|
/// </summary>
|
||||
|
public static bool IsNotNullOrEmpty(this string str) |
||||
|
{ |
||||
|
return !string.IsNullOrEmpty(str); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 判断指定的字符串不是 null、空或者仅由空白字符组成
|
||||
|
/// </summary>
|
||||
|
public static bool IsNotNullOrWhiteSpace(this string str) |
||||
|
{ |
||||
|
return !string.IsNullOrWhiteSpace(str); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 指示指定的字符串是 null、空或者仅由空白字符组成
|
||||
|
/// </summary>
|
||||
|
public static bool IsMissing(this string value) |
||||
|
{ |
||||
|
return string.IsNullOrWhiteSpace(value); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 为指定格式的字符串填充相应对象来生成字符串
|
||||
|
/// </summary>
|
||||
|
/// <param name="format">字符串格式,占位符以{n}表示</param>
|
||||
|
/// <param name="args">用于填充占位符的参数</param>
|
||||
|
/// <returns>格式化后的字符串</returns>
|
||||
|
public static string FormatWith(this string format, params object[] args) |
||||
|
{ |
||||
|
Guard.NotNull(format, nameof(format)); |
||||
|
return string.Format(CultureInfo.CurrentCulture, format, args); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 将字符串反转
|
||||
|
/// </summary>
|
||||
|
/// <param name="value">要反转的字符串</param>
|
||||
|
public static string ReverseString(this string value) |
||||
|
{ |
||||
|
Guard.NotNull(value, nameof(value)); |
||||
|
return new string(value.Reverse().ToArray()); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 单词复数变成单数形式
|
||||
|
/// </summary>
|
||||
|
/// <param name="word"></param>
|
||||
|
/// <returns></returns>
|
||||
|
public static string ToSingular(this string word) |
||||
|
{ |
||||
|
var plural1 = new Regex("(?<keep>[^aeiou])ies$"); |
||||
|
var plural2 = new Regex("(?<keep>[aeiou]y)s$"); |
||||
|
var plural3 = new Regex("(?<keep>[sxzh])es$"); |
||||
|
var plural4 = new Regex("(?<keep>[^sxzhyu])s$"); |
||||
|
|
||||
|
if (plural1.IsMatch(word)) |
||||
|
{ |
||||
|
return plural1.Replace(word, "${keep}y"); |
||||
|
} |
||||
|
|
||||
|
if (plural2.IsMatch(word)) |
||||
|
{ |
||||
|
return plural2.Replace(word, "${keep}"); |
||||
|
} |
||||
|
|
||||
|
if (plural3.IsMatch(word)) |
||||
|
{ |
||||
|
return plural3.Replace(word, "${keep}"); |
||||
|
} |
||||
|
|
||||
|
if (plural4.IsMatch(word)) |
||||
|
{ |
||||
|
return plural4.Replace(word, "${keep}"); |
||||
|
} |
||||
|
|
||||
|
return word; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 单词单数变成复数形式
|
||||
|
/// </summary>
|
||||
|
/// <param name="word"></param>
|
||||
|
/// <returns></returns>
|
||||
|
public static string ToPlural(this string word) |
||||
|
{ |
||||
|
var plural1 = new Regex("(?<keep>[^aeiou])y$"); |
||||
|
var plural2 = new Regex("(?<keep>[aeiou]y)$"); |
||||
|
var plural3 = new Regex("(?<keep>[sxzh])$"); |
||||
|
var plural4 = new Regex("(?<keep>[^sxzhy])$"); |
||||
|
|
||||
|
if (plural1.IsMatch(word)) |
||||
|
{ |
||||
|
return plural1.Replace(word, "${keep}ies"); |
||||
|
} |
||||
|
|
||||
|
if (plural2.IsMatch(word)) |
||||
|
{ |
||||
|
return plural2.Replace(word, "${keep}s"); |
||||
|
} |
||||
|
|
||||
|
if (plural3.IsMatch(word)) |
||||
|
{ |
||||
|
return plural3.Replace(word, "${keep}es"); |
||||
|
} |
||||
|
|
||||
|
if (plural4.IsMatch(word)) |
||||
|
{ |
||||
|
return plural4.Replace(word, "${keep}s"); |
||||
|
} |
||||
|
|
||||
|
return word; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 以指定字符串作为分隔符将指定字符串分隔成数组
|
||||
|
/// </summary>
|
||||
|
/// <param name="value">要分割的字符串</param>
|
||||
|
/// <param name="strSplit">字符串类型的分隔符</param>
|
||||
|
/// <param name="removeEmptyEntries">是否移除数据中元素为空字符串的项</param>
|
||||
|
/// <returns>分割后的数据</returns>
|
||||
|
public static string[] Split(this string value, string strSplit, bool removeEmptyEntries = false) |
||||
|
{ |
||||
|
return value.Split(new[] {strSplit}, |
||||
|
removeEmptyEntries ? StringSplitOptions.RemoveEmptyEntries : StringSplitOptions.None); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 支持汉字的字符串长度,汉字长度计为2
|
||||
|
/// </summary>
|
||||
|
/// <param name="value">参数字符串</param>
|
||||
|
/// <returns>当前字符串的长度,汉字长度为2</returns>
|
||||
|
public static int TextLength(this string value) |
||||
|
{ |
||||
|
var ascii = new ASCIIEncoding(); |
||||
|
var tempLen = 0; |
||||
|
var bytes = ascii.GetBytes(value); |
||||
|
foreach (var b in bytes) |
||||
|
{ |
||||
|
if (b == 63) |
||||
|
{ |
||||
|
tempLen += 2; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
tempLen += 1; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return tempLen; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 将JSON字符串还原为对象
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="T">要转换的目标类型</typeparam>
|
||||
|
/// <param name="json">JSON字符串</param>
|
||||
|
/// <returns></returns>
|
||||
|
public static T FromJsonString<T>(this string json) |
||||
|
{ |
||||
|
Guard.NotNull(json, nameof(json)); |
||||
|
return JsonConvert.DeserializeObject<T>(json); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 将JSON字符串还原为对象
|
||||
|
/// </summary>
|
||||
|
/// <param name="json">JSON字符串 </param>
|
||||
|
/// <param name="type">数据类型</param>
|
||||
|
public static object FromJsonString(this string json, Type type) |
||||
|
{ |
||||
|
return JsonConvert.DeserializeObject(json, type); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 给URL添加查询参数
|
||||
|
/// </summary>
|
||||
|
/// <param name="url">URL字符串</param>
|
||||
|
/// <param name="queries">要添加的参数,形如:"id=1,cid=2"</param>
|
||||
|
/// <returns></returns>
|
||||
|
public static string AddUrlQuery(this string url, params string[] queries) |
||||
|
{ |
||||
|
foreach (var query in queries) |
||||
|
{ |
||||
|
if (!url.Contains("?")) |
||||
|
{ |
||||
|
url += "?"; |
||||
|
} |
||||
|
else if (!url.EndsWith("&")) |
||||
|
{ |
||||
|
url += "&"; |
||||
|
} |
||||
|
|
||||
|
url += query; |
||||
|
} |
||||
|
|
||||
|
return url; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 获取URL中指定参数的值,不存在返回空字符串
|
||||
|
/// </summary>
|
||||
|
public static string GetUrlQuery(this string url, string key) |
||||
|
{ |
||||
|
var uri = new Uri(url); |
||||
|
var query = uri.Query; |
||||
|
if (string.IsNullOrEmpty(query)) |
||||
|
{ |
||||
|
return string.Empty; |
||||
|
} |
||||
|
|
||||
|
query = query.TrimStart('?'); |
||||
|
var dict = (from m in query.Split("&", true) |
||||
|
let strs = m.Split("=") |
||||
|
select new KeyValuePair<string, string>(strs[0], strs[1])) |
||||
|
.ToDictionary(m => m.Key, m => m.Value); |
||||
|
if (dict.ContainsKey(key)) |
||||
|
{ |
||||
|
return dict[key]; |
||||
|
} |
||||
|
|
||||
|
return string.Empty; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 给URL添加 # 参数
|
||||
|
/// </summary>
|
||||
|
/// <param name="url">URL字符串</param>
|
||||
|
/// <param name="query">要添加的参数</param>
|
||||
|
/// <returns></returns>
|
||||
|
public static string AddHashFragment(this string url, string query) |
||||
|
{ |
||||
|
Guard.NotNull(url, nameof(url)); |
||||
|
Guard.NotNull(query, nameof(query)); |
||||
|
|
||||
|
if (!url.Contains("#")) |
||||
|
{ |
||||
|
url += "#"; |
||||
|
} |
||||
|
|
||||
|
return url + query; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 将<see cref="byte"/>[]数组转换为Base64字符串
|
||||
|
/// </summary>
|
||||
|
public static string ToBase64String(this byte[] bytes) |
||||
|
{ |
||||
|
Guard.NotNull(bytes, nameof(bytes)); |
||||
|
|
||||
|
return Convert.ToBase64String(bytes); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 将字符串转换为Base64字符串,默认编码为<see cref="Encoding.UTF8"/>
|
||||
|
/// </summary>
|
||||
|
/// <param name="source">正常的字符串</param>
|
||||
|
/// <param name="encoding">编码</param>
|
||||
|
/// <returns>Base64字符串</returns>
|
||||
|
public static string ToBase64String(this string source, Encoding encoding = null) |
||||
|
{ |
||||
|
Guard.NotNull(source, nameof(source)); |
||||
|
|
||||
|
if (encoding == null) encoding = Encoding.UTF8; |
||||
|
|
||||
|
return Convert.ToBase64String(encoding.GetBytes(source)); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 将Base64字符串转换为正常字符串,默认编码为<see cref="Encoding.UTF8"/>
|
||||
|
/// </summary>
|
||||
|
/// <param name="base64String">Base64字符串</param>
|
||||
|
/// <param name="encoding">编码</param>
|
||||
|
/// <returns>正常字符串</returns>
|
||||
|
public static string FromBase64String(this string base64String, Encoding encoding = null) |
||||
|
{ |
||||
|
Guard.NotNull(base64String, nameof(base64String)); |
||||
|
|
||||
|
if (encoding == null) encoding = Encoding.UTF8; |
||||
|
|
||||
|
var bytes = Convert.FromBase64String(base64String); |
||||
|
return encoding.GetString(bytes); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 将字符串进行UrlDecode解码
|
||||
|
/// </summary>
|
||||
|
/// <param name="source">待UrlDecode解码的字符串</param>
|
||||
|
/// <returns>UrlDecode解码后的字符串</returns>
|
||||
|
public static string ToUrlDecode(this string source) |
||||
|
{ |
||||
|
Guard.NotNull(source, nameof(source)); |
||||
|
|
||||
|
return HttpUtility.UrlDecode(source); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 将字符串进行UrlEncode编码
|
||||
|
/// </summary>
|
||||
|
/// <param name="source">待UrlEncode编码的字符串</param>
|
||||
|
/// <returns>UrlEncode编码后的字符串</returns>
|
||||
|
public static string ToUrlEncode(this string source) |
||||
|
{ |
||||
|
Guard.NotNull(source, nameof(source)); |
||||
|
|
||||
|
return HttpUtility.UrlEncode(source); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 将字符串进行HtmlDecode解码
|
||||
|
/// </summary>
|
||||
|
/// <param name="source">待HtmlDecode解码的字符串</param>
|
||||
|
/// <returns>HtmlDecode解码后的字符串</returns>
|
||||
|
public static string ToHtmlDecode(this string source) |
||||
|
{ |
||||
|
Guard.NotNull(source, nameof(source)); |
||||
|
|
||||
|
return HttpUtility.HtmlDecode(source); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 将字符串进行HtmlEncode编码
|
||||
|
/// </summary>
|
||||
|
/// <param name="source">待HtmlEncode编码的字符串</param>
|
||||
|
/// <returns>HtmlEncode编码后的字符串</returns>
|
||||
|
public static string ToHtmlEncode(this string source) |
||||
|
{ |
||||
|
Guard.NotNull(source, nameof(source)); |
||||
|
|
||||
|
return HttpUtility.HtmlEncode(source); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 将字符串转换为十六进制字符串,默认编码为<see cref="Encoding.UTF8"/>
|
||||
|
/// </summary>
|
||||
|
public static string ToHexString(this string source, Encoding encoding = null) |
||||
|
{ |
||||
|
Guard.NotNull(source, nameof(source)); |
||||
|
|
||||
|
if (encoding == null) encoding = Encoding.UTF8; |
||||
|
|
||||
|
byte[] bytes = encoding.GetBytes(source); |
||||
|
return bytes.ToHexString(); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 将十六进制字符串转换为常规字符串,默认编码为<see cref="Encoding.UTF8"/>
|
||||
|
/// </summary>
|
||||
|
public static string FromHexString(this string hexString, Encoding encoding = null) |
||||
|
{ |
||||
|
Guard.NotNull(hexString, nameof(hexString)); |
||||
|
|
||||
|
if (encoding == null) encoding = Encoding.UTF8; |
||||
|
|
||||
|
var bytes = hexString.ToHexBytes(); |
||||
|
return encoding.GetString(bytes); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 将byte[]编码为十六进制字符串
|
||||
|
/// </summary>
|
||||
|
/// <param name="bytes">byte[]数组</param>
|
||||
|
/// <returns>十六进制字符串</returns>
|
||||
|
public static string ToHexString(this byte[] bytes) |
||||
|
{ |
||||
|
Guard.NotNull(bytes, nameof(bytes)); |
||||
|
|
||||
|
return bytes.Aggregate(string.Empty, (current, t) => current + t.ToString("X2")); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 将十六进制字符串转换为byte[]
|
||||
|
/// </summary>
|
||||
|
/// <param name="hexString">十六进制字符串</param>
|
||||
|
/// <returns>byte[]数组</returns>
|
||||
|
public static byte[] ToHexBytes(this string hexString) |
||||
|
{ |
||||
|
hexString = hexString ?? ""; |
||||
|
hexString = hexString.Replace(" ", ""); |
||||
|
byte[] bytes = new byte[hexString.Length / 2]; |
||||
|
for (int i = 0; i < bytes.Length; i++) |
||||
|
{ |
||||
|
bytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16); |
||||
|
} |
||||
|
|
||||
|
return bytes; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 将字符串进行Unicode编码,变成形如“\u7f16\u7801”的形式
|
||||
|
/// </summary>
|
||||
|
/// <param name="source">要进行编号的字符串</param>
|
||||
|
public static string ToUnicodeString(this string source) |
||||
|
{ |
||||
|
Guard.NotNull(source, nameof(source)); |
||||
|
|
||||
|
var regex = new Regex(@"[^\u0000-\u00ff]"); |
||||
|
return regex.Replace(source, m => string.Format(@"\u{0:x4}", (short) m.Value[0])); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 将形如“\u7f16\u7801”的Unicode字符串解码
|
||||
|
/// </summary>
|
||||
|
public static string FromUnicodeString(this string source) |
||||
|
{ |
||||
|
var regex = new Regex(@"\\u([0-9a-fA-F]{4})", RegexOptions.Compiled); |
||||
|
return regex.Replace(source, |
||||
|
m => |
||||
|
{ |
||||
|
short s; |
||||
|
if (short.TryParse(m.Groups[1].Value, NumberStyles.HexNumber, CultureInfo.InstalledUICulture, |
||||
|
out s)) |
||||
|
{ |
||||
|
return "" + (char) s; |
||||
|
} |
||||
|
|
||||
|
return m.Value; |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 将驼峰字符串按单词拆分并转换成小写,再以特定字符串分隔
|
||||
|
/// </summary>
|
||||
|
/// <param name="str">待转换的字符串</param>
|
||||
|
/// <param name="splitStr">分隔符字符</param>
|
||||
|
/// <returns></returns>
|
||||
|
public static string UpperToLowerAndSplit(this string str, string splitStr = "-") |
||||
|
{ |
||||
|
if (string.IsNullOrEmpty(str)) |
||||
|
{ |
||||
|
return str; |
||||
|
} |
||||
|
|
||||
|
List<string> words = new List<string>(); |
||||
|
while (str.Length > 0) |
||||
|
{ |
||||
|
char c = str.FirstOrDefault(char.IsUpper); |
||||
|
if (c == default(char)) |
||||
|
{ |
||||
|
words.Add(str); |
||||
|
break; |
||||
|
} |
||||
|
|
||||
|
int upperIndex = str.IndexOf(c); |
||||
|
if (upperIndex < 0) //admin
|
||||
|
{ |
||||
|
return str; |
||||
|
} |
||||
|
|
||||
|
if (upperIndex > 0) //adminAdmin
|
||||
|
{ |
||||
|
string first = str.Substring(0, upperIndex); |
||||
|
words.Add(first); |
||||
|
str = str.Substring(upperIndex, str.Length - upperIndex); |
||||
|
continue; |
||||
|
} |
||||
|
|
||||
|
str = char.ToLower(str[0]) + str.Substring(1, str.Length - 1); |
||||
|
} |
||||
|
|
||||
|
return words.ExpandAndToString(splitStr); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 将驼峰字符串的第一个字符小写
|
||||
|
/// </summary>
|
||||
|
public static string LowerFirstChar(this string str) |
||||
|
{ |
||||
|
if (string.IsNullOrEmpty(str) || !char.IsUpper(str[0])) |
||||
|
{ |
||||
|
return str; |
||||
|
} |
||||
|
|
||||
|
if (str.Length == 1) |
||||
|
{ |
||||
|
return char.ToLower(str[0]).ToString(); |
||||
|
} |
||||
|
|
||||
|
return char.ToLower(str[0]) + str.Substring(1, str.Length - 1); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 将小驼峰字符串的第一个字符大写
|
||||
|
/// </summary>
|
||||
|
public static string UpperFirstChar(this string str) |
||||
|
{ |
||||
|
if (string.IsNullOrEmpty(str) || !char.IsLower(str[0])) |
||||
|
{ |
||||
|
return str; |
||||
|
} |
||||
|
|
||||
|
if (str.Length == 1) |
||||
|
{ |
||||
|
return char.ToUpper(str[0]).ToString(); |
||||
|
} |
||||
|
|
||||
|
return char.ToUpper(str[0]) + str.Substring(1, str.Length - 1); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 计算当前字符串与指定字符串的编辑距离(相似度)
|
||||
|
/// </summary>
|
||||
|
/// <param name="source">源字符串</param>
|
||||
|
/// <param name="target">目标字符串</param>
|
||||
|
/// <param name="similarity">输出相似度</param>
|
||||
|
/// <param name="ignoreCase">是否忽略大小写</param>
|
||||
|
/// <returns>编辑距离</returns>
|
||||
|
public static int LevenshteinDistance(this string source, string target, out double similarity, |
||||
|
bool ignoreCase = false) |
||||
|
{ |
||||
|
if (string.IsNullOrEmpty(source)) |
||||
|
{ |
||||
|
if (string.IsNullOrEmpty(target)) |
||||
|
{ |
||||
|
similarity = 1; |
||||
|
return 0; |
||||
|
} |
||||
|
|
||||
|
similarity = 0; |
||||
|
return target.Length; |
||||
|
} |
||||
|
|
||||
|
if (string.IsNullOrEmpty(target)) |
||||
|
{ |
||||
|
similarity = 0; |
||||
|
return source.Length; |
||||
|
} |
||||
|
|
||||
|
string from, to; |
||||
|
if (ignoreCase) |
||||
|
{ |
||||
|
from = source; |
||||
|
to = target; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
from = source.ToLower(); |
||||
|
to = source.ToLower(); |
||||
|
} |
||||
|
|
||||
|
int m = from.Length, n = to.Length; |
||||
|
int[,] mn = new int[m + 1, n + 1]; |
||||
|
for (int i = 0; i <= m; i++) |
||||
|
{ |
||||
|
mn[i, 0] = i; |
||||
|
} |
||||
|
|
||||
|
for (int j = 1; j <= n; j++) |
||||
|
{ |
||||
|
mn[0, j] = j; |
||||
|
} |
||||
|
|
||||
|
for (int i = 1; i <= m; i++) |
||||
|
{ |
||||
|
char c = from[i - 1]; |
||||
|
for (int j = 1; j <= n; j++) |
||||
|
{ |
||||
|
if (c == to[j - 1]) |
||||
|
{ |
||||
|
mn[i, j] = mn[i - 1, j - 1]; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
mn[i, j] = Math.Min(mn[i - 1, j - 1], Math.Min(mn[i - 1, j], mn[i, j - 1])) + 1; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
int maxLength = Math.Max(m, n); |
||||
|
similarity = (double) (maxLength - mn[m, n]) / maxLength; |
||||
|
return mn[m, n]; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 计算两个字符串的相似度,应用公式:相似度=kq*q/(kq*q+kr*r+ks*s)(kq>0,kr>=0,ka>=0)
|
||||
|
/// 其中,q是字符串1和字符串2中都存在的单词的总数,s是字符串1中存在,字符串2中不存在的单词总数,r是字符串2中存在,字符串1中不存在的单词总数. kq,kr和ka分别是q,r,s的权重,根据实际的计算情况,我们设kq=2,kr=ks=1.
|
||||
|
/// </summary>
|
||||
|
/// <param name="source">源字符串</param>
|
||||
|
/// <param name="target">目标字符串</param>
|
||||
|
/// <param name="ignoreCase">是否忽略大小写</param>
|
||||
|
/// <returns>字符串相似度</returns>
|
||||
|
public static double GetSimilarityWith(this string source, string target, bool ignoreCase = false) |
||||
|
{ |
||||
|
if (string.IsNullOrEmpty(source) && string.IsNullOrEmpty(target)) |
||||
|
{ |
||||
|
return 1; |
||||
|
} |
||||
|
|
||||
|
if (string.IsNullOrEmpty(source) || string.IsNullOrEmpty(target)) |
||||
|
{ |
||||
|
return 0; |
||||
|
} |
||||
|
|
||||
|
const double kq = 2, kr = 1, ks = 1; |
||||
|
char[] sourceChars = source.ToCharArray(), targetChars = target.ToCharArray(); |
||||
|
|
||||
|
//获取交集数量
|
||||
|
int q = sourceChars.Intersect(targetChars).Count(), s = sourceChars.Length - q, r = targetChars.Length - q; |
||||
|
return kq * q / (kq * q + kr * r + ks * s); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 标准化Path字符串,将 \\ 转换为 /
|
||||
|
/// </summary>
|
||||
|
/// <param name="path">Path字符串</param>
|
||||
|
public static string NormalizePath(this string path) |
||||
|
{ |
||||
|
return path.Replace('\\', '/'); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// (Pascal) 命名法 的字符串 改为 短横线分隔式命名
|
||||
|
/// 例如UserName => user-name
|
||||
|
/// </summary>
|
||||
|
public static string PascalToKebabCase(this string value) |
||||
|
{ |
||||
|
if (string.IsNullOrEmpty(value)) |
||||
|
{ |
||||
|
return value; |
||||
|
} |
||||
|
|
||||
|
return Regex.Replace( |
||||
|
value, |
||||
|
"(?<!^)([A-Z][a-z]|(?<=[a-z])[A-Z])", |
||||
|
"-$1", |
||||
|
RegexOptions.Compiled) |
||||
|
.Trim() |
||||
|
.ToLower(); |
||||
|
} |
||||
|
|
||||
|
#endregion
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,242 @@ |
|||||
|
using System; |
||||
|
using System.Text; |
||||
|
using Lion.AbpPro.Extension.Customs; |
||||
|
|
||||
|
namespace Lion.AbpPro.Extension.System.Text |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// StringBuilder 扩展方法类
|
||||
|
/// </summary>
|
||||
|
public static class StringBuilderExtensions |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// 去除<seealso cref="StringBuilder"/>开头的空格
|
||||
|
/// </summary>
|
||||
|
/// <param name="stringBuilder"></param>
|
||||
|
/// <returns>返回修改后的StringBuilder,主要用于链式操作</returns>
|
||||
|
public static StringBuilder TrimStart(this StringBuilder stringBuilder) |
||||
|
{ |
||||
|
Guard.NotNull(stringBuilder, nameof(stringBuilder)); |
||||
|
|
||||
|
return stringBuilder.TrimStart(' '); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 去除<seealso cref="StringBuilder"/>开头的指定<seealso cref="char"/>
|
||||
|
/// </summary>
|
||||
|
/// <param name="stringBuilder"></param>
|
||||
|
/// <param name="c">要去掉的<seealso cref="char"/></param>
|
||||
|
/// <returns></returns>
|
||||
|
public static StringBuilder TrimStart(this StringBuilder stringBuilder, char c) |
||||
|
{ |
||||
|
Guard.NotNull(stringBuilder, nameof(stringBuilder)); |
||||
|
|
||||
|
if (stringBuilder.Length == 0) |
||||
|
return stringBuilder; |
||||
|
while (c.Equals(stringBuilder[0])) |
||||
|
{ |
||||
|
stringBuilder.Remove(0, 1); |
||||
|
} |
||||
|
|
||||
|
return stringBuilder; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 去除<seealso cref="StringBuilder"/>开头的指定字符数组
|
||||
|
/// </summary>
|
||||
|
/// <param name="stringBuilder"></param>
|
||||
|
/// <param name="chars">要去掉的字符数组</param>
|
||||
|
/// <returns></returns>
|
||||
|
public static StringBuilder TrimStart(this StringBuilder stringBuilder, char[] chars) |
||||
|
{ |
||||
|
Guard.NotNull(stringBuilder, nameof(stringBuilder)); |
||||
|
Guard.NotNull(chars, nameof(chars)); |
||||
|
|
||||
|
return stringBuilder.TrimStart(new string(chars)); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 去除<see cref="StringBuilder"/>开头的指定的<seealso cref="string"/>
|
||||
|
/// </summary>
|
||||
|
/// <param name="stringBuilder"></param>
|
||||
|
/// <param name="str">要去掉的<seealso cref="string"/></param>
|
||||
|
/// <returns></returns>
|
||||
|
public static StringBuilder TrimStart(this StringBuilder stringBuilder, string str) |
||||
|
{ |
||||
|
Guard.NotNull(stringBuilder, nameof(stringBuilder)); |
||||
|
|
||||
|
if (string.IsNullOrEmpty(str) |
||||
|
|| stringBuilder.Length == 0 |
||||
|
|| str.Length > stringBuilder.Length) |
||||
|
{ |
||||
|
return stringBuilder; |
||||
|
} |
||||
|
|
||||
|
while (stringBuilder.SubString(0, str.Length).Equals(str)) |
||||
|
{ |
||||
|
stringBuilder.Remove(0, str.Length); |
||||
|
if (str.Length > stringBuilder.Length) |
||||
|
{ |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return stringBuilder; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 去除StringBuilder结尾的空格
|
||||
|
/// </summary>
|
||||
|
/// <param name="stringBuilder">StringBuilder</param>
|
||||
|
/// <returns>返回修改后的StringBuilder,主要用于链式操作</returns>
|
||||
|
public static StringBuilder TrimEnd(this StringBuilder stringBuilder) |
||||
|
{ |
||||
|
return stringBuilder.TrimEnd(' '); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 去除<see cref="StringBuilder"/>结尾指定字符
|
||||
|
/// </summary>
|
||||
|
/// <param name="stringBuilder"></param>
|
||||
|
/// <param name="c">要去掉的字符</param>
|
||||
|
/// <returns></returns>
|
||||
|
public static StringBuilder TrimEnd(this StringBuilder stringBuilder, char c) |
||||
|
{ |
||||
|
Guard.NotNull(stringBuilder, nameof(stringBuilder)); |
||||
|
if (stringBuilder.Length == 0) |
||||
|
{ |
||||
|
return stringBuilder; |
||||
|
} |
||||
|
|
||||
|
while (c.Equals(stringBuilder[stringBuilder.Length - 1])) |
||||
|
{ |
||||
|
stringBuilder.Remove(stringBuilder.Length - 1, 1); |
||||
|
} |
||||
|
|
||||
|
return stringBuilder; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 去除<see cref="StringBuilder"/>结尾指定字符数组
|
||||
|
/// </summary>
|
||||
|
/// <param name="stringBuilder"></param>
|
||||
|
/// <param name="chars">要去除的字符数组</param>
|
||||
|
/// <returns></returns>
|
||||
|
public static StringBuilder TrimEnd(this StringBuilder stringBuilder, char[] chars) |
||||
|
{ |
||||
|
Guard.NotNull(stringBuilder, nameof(stringBuilder)); |
||||
|
Guard.NotNull(chars, nameof(chars)); |
||||
|
|
||||
|
return stringBuilder.TrimEnd(new string(chars)); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 去除<see cref="StringBuilder"/>结尾指定字符串
|
||||
|
/// </summary>
|
||||
|
/// <param name="stringBuilder"></param>
|
||||
|
/// <param name="str">要去除的字符串</param>
|
||||
|
/// <returns></returns>
|
||||
|
public static StringBuilder TrimEnd(this StringBuilder stringBuilder, string str) |
||||
|
{ |
||||
|
Guard.NotNull(stringBuilder, nameof(stringBuilder)); |
||||
|
if (string.IsNullOrEmpty(str) |
||||
|
|| stringBuilder.Length == 0 |
||||
|
|| str.Length > stringBuilder.Length) |
||||
|
{ |
||||
|
return stringBuilder; |
||||
|
} |
||||
|
while (stringBuilder.SubString(stringBuilder.Length - str.Length, str.Length).Equals(str)) |
||||
|
{ |
||||
|
stringBuilder.Remove(stringBuilder.Length - str.Length, str.Length); |
||||
|
if (stringBuilder.Length < str.Length) |
||||
|
{ |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return stringBuilder; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 去除StringBuilder两端的空格
|
||||
|
/// </summary>
|
||||
|
/// <param name="stringBuilder">StringBuilder</param>
|
||||
|
/// <returns>返回修改后的StringBuilder,主要用于链式操作</returns>
|
||||
|
public static StringBuilder Trim(this StringBuilder stringBuilder) |
||||
|
{ |
||||
|
Guard.NotNull(stringBuilder, nameof(stringBuilder)); |
||||
|
|
||||
|
if (stringBuilder.Length == 0) |
||||
|
return stringBuilder; |
||||
|
return stringBuilder.TrimEnd().TrimStart(); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 返回<see cref="StringBuilder"/>从起始位置指定长度的字符串
|
||||
|
/// </summary>
|
||||
|
/// <param name="stringBuilder"></param>
|
||||
|
/// <param name="start">起始位置</param>
|
||||
|
/// <param name="length">长度</param>
|
||||
|
/// <returns>字符串</returns>
|
||||
|
/// <exception cref="IndexOutOfRangeException">超出字符串索引长度异常</exception>
|
||||
|
public static string SubString(this StringBuilder stringBuilder, int start, int length) |
||||
|
{ |
||||
|
Guard.NotNull(stringBuilder, nameof(stringBuilder)); |
||||
|
|
||||
|
if (start + length > stringBuilder.Length) |
||||
|
{ |
||||
|
throw new IndexOutOfRangeException("超出字符串索引长度"); |
||||
|
} |
||||
|
|
||||
|
var cs = new char[length]; |
||||
|
for (var i = 0; i < length; i++) |
||||
|
{ |
||||
|
cs[i] = stringBuilder[start + i]; |
||||
|
} |
||||
|
|
||||
|
return new string(cs); |
||||
|
} |
||||
|
|
||||
|
public static StringBuilder AppendLineWithControlChar(this StringBuilder stringBuilder, StringBuilder sb, string newLine) |
||||
|
{ |
||||
|
stringBuilder = AppendWithControlChar(stringBuilder, sb.ToString()); |
||||
|
return stringBuilder.Append(newLine); |
||||
|
} |
||||
|
|
||||
|
public static StringBuilder AppendLineWithControlChar(this StringBuilder stringBuilder, string str, string newLine) |
||||
|
{ |
||||
|
stringBuilder = AppendWithControlChar(stringBuilder, str); |
||||
|
return stringBuilder.Append(newLine); |
||||
|
} |
||||
|
|
||||
|
public static StringBuilder AppendWithControlChar(this StringBuilder stringBuilder, StringBuilder sb) |
||||
|
{ |
||||
|
return AppendWithControlChar(stringBuilder, sb.ToString()); |
||||
|
} |
||||
|
|
||||
|
public static StringBuilder AppendWithControlChar(this StringBuilder stringBuilder, string str) |
||||
|
{ |
||||
|
if (str.Contains('\b')) |
||||
|
{ |
||||
|
foreach (var c in str) |
||||
|
{ |
||||
|
if (c == '\b') |
||||
|
{ |
||||
|
stringBuilder.Length--; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
stringBuilder.Append(c); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
stringBuilder.Append(str); |
||||
|
} |
||||
|
|
||||
|
return stringBuilder; |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
} |
||||
@ -1,12 +0,0 @@ |
|||||
<Project Sdk="Microsoft.NET.Sdk.Web"> |
|
||||
|
|
||||
<PropertyGroup> |
|
||||
<TargetFramework>net5.0</TargetFramework> |
|
||||
</PropertyGroup> |
|
||||
|
|
||||
|
|
||||
<ItemGroup> |
|
||||
<ProjectReference Include="..\..\shared\CompanyName.ProjectName.Shared.Hosting.Gateways\CompanyName.ProjectName.Shared.Hosting.Gateways.csproj" /> |
|
||||
</ItemGroup> |
|
||||
|
|
||||
</Project> |
|
||||
@ -1,24 +0,0 @@ |
|||||
using System; |
|
||||
using System.Collections.Generic; |
|
||||
using System.Linq; |
|
||||
using System.Threading.Tasks; |
|
||||
using Microsoft.AspNetCore.Hosting; |
|
||||
using Microsoft.Extensions.Configuration; |
|
||||
using Microsoft.Extensions.Hosting; |
|
||||
using Microsoft.Extensions.Logging; |
|
||||
|
|
||||
namespace CompanyName.ProjectName.WebGateway |
|
||||
{ |
|
||||
public class Program |
|
||||
{ |
|
||||
public static void Main(string[] args) |
|
||||
{ |
|
||||
CreateHostBuilder(args).Build().Run(); |
|
||||
} |
|
||||
|
|
||||
public static IHostBuilder CreateHostBuilder(string[] args) => |
|
||||
Host.CreateDefaultBuilder(args) |
|
||||
.ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); }) |
|
||||
.UseAutofac(); |
|
||||
} |
|
||||
} |
|
||||
@ -1,14 +0,0 @@ |
|||||
{ |
|
||||
"$schema": "http://json.schemastore.org/launchsettings.json", |
|
||||
"profiles": { |
|
||||
"CompanyName.ProjectName.WebGateway": { |
|
||||
"commandName": "Project", |
|
||||
"launchBrowser": false, |
|
||||
"launchUrl": "swagger", |
|
||||
"applicationUrl": "http://localhost:44314", |
|
||||
"environmentVariables": { |
|
||||
"ASPNETCORE_ENVIRONMENT": "Development" |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,29 +0,0 @@ |
|||||
using System; |
|
||||
using System.Collections.Generic; |
|
||||
using System.Linq; |
|
||||
using System.Threading.Tasks; |
|
||||
using Microsoft.AspNetCore.Builder; |
|
||||
using Microsoft.AspNetCore.Hosting; |
|
||||
using Microsoft.AspNetCore.HttpsPolicy; |
|
||||
using Microsoft.AspNetCore.Mvc; |
|
||||
using Microsoft.Extensions.Configuration; |
|
||||
using Microsoft.Extensions.DependencyInjection; |
|
||||
using Microsoft.Extensions.Hosting; |
|
||||
using Microsoft.Extensions.Logging; |
|
||||
using Microsoft.OpenApi.Models; |
|
||||
|
|
||||
namespace CompanyName.ProjectName.WebGateway |
|
||||
{ |
|
||||
public class Startup |
|
||||
{ |
|
||||
public void ConfigureServices(IServiceCollection services) |
|
||||
{ |
|
||||
services.AddApplication<WebGatewayModule>(); |
|
||||
} |
|
||||
|
|
||||
public void Configure(IApplicationBuilder app) |
|
||||
{ |
|
||||
app.InitializeApplication(); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,66 +0,0 @@ |
|||||
using System; |
|
||||
using System.Collections.Generic; |
|
||||
using System.Linq; |
|
||||
using CompanyName.ProjectName.Shared.Hosting.Gateways; |
|
||||
using Microsoft.AspNetCore.Builder; |
|
||||
using Microsoft.AspNetCore.Cors; |
|
||||
using Microsoft.Extensions.DependencyInjection; |
|
||||
using Microsoft.OpenApi.Models; |
|
||||
using Ocelot.Middleware; |
|
||||
using Swashbuckle.AspNetCore.SwaggerUI; |
|
||||
using Volo.Abp; |
|
||||
using Volo.Abp.Modularity; |
|
||||
|
|
||||
namespace CompanyName.ProjectName.WebGateway |
|
||||
{ |
|
||||
[DependsOn( |
|
||||
typeof(SharedHostingGatewayModule))] |
|
||||
public class WebGatewayModule : AbpModule |
|
||||
{ |
|
||||
private const string DefaultCorsPolicyName = "Default"; |
|
||||
|
|
||||
public override void ConfigureServices(ServiceConfigurationContext context) |
|
||||
{ |
|
||||
ConfigureCors(context); |
|
||||
|
|
||||
} |
|
||||
|
|
||||
public override void OnApplicationInitialization(ApplicationInitializationContext context) |
|
||||
{ |
|
||||
var app = context.GetApplicationBuilder(); |
|
||||
app.UseCorrelationId(); |
|
||||
app.UseCors(DefaultCorsPolicyName); |
|
||||
app.UseRouting(); |
|
||||
app.UseConfiguredEndpoints(endpoints => { endpoints.MapHealthChecks("/health"); }); |
|
||||
app.UseWebSockets(); |
|
||||
app.UseOcelot().Wait(); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 配置跨域
|
|
||||
/// </summary>
|
|
||||
private void ConfigureCors(ServiceConfigurationContext context) |
|
||||
{ |
|
||||
var configuration = context.Services.GetConfiguration(); |
|
||||
context.Services.AddCors(options => |
|
||||
{ |
|
||||
options.AddPolicy(DefaultCorsPolicyName, builder => |
|
||||
{ |
|
||||
builder |
|
||||
.WithOrigins( |
|
||||
configuration["App:CorsOrigins"] |
|
||||
.Split(",", StringSplitOptions.RemoveEmptyEntries) |
|
||||
.Select(o => o.RemovePostFix("/")) |
|
||||
.ToArray() |
|
||||
) |
|
||||
.WithAbpExposedHeaders() |
|
||||
.SetIsOriginAllowedToAllowWildcardSubdomains() |
|
||||
.AllowAnyHeader() |
|
||||
.AllowAnyMethod() |
|
||||
.AllowCredentials(); |
|
||||
}); |
|
||||
}); |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,19 @@ |
|||||
|
FROM mcr.microsoft.com/dotnet/aspnet:6.0 |
||||
|
|
||||
|
# 创建目录 |
||||
|
RUN mkdir /app |
||||
|
|
||||
|
COPY publish /app |
||||
|
|
||||
|
# 设置工作目录 |
||||
|
WORKDIR /app |
||||
|
|
||||
|
# 暴露80端口 |
||||
|
EXPOSE 80 |
||||
|
|
||||
|
# 设置环境变量 |
||||
|
ENV ASPNETCORE_ENVIRONMENT=Production |
||||
|
|
||||
|
ENTRYPOINT ["dotnet", "Lion.AbpPro.WebGateway.dll"] |
||||
|
|
||||
|
|
||||
@ -0,0 +1,12 @@ |
|||||
|
<Project Sdk="Microsoft.NET.Sdk.Web"> |
||||
|
|
||||
|
<PropertyGroup> |
||||
|
<TargetFramework>net6.0</TargetFramework> |
||||
|
</PropertyGroup> |
||||
|
|
||||
|
|
||||
|
<ItemGroup> |
||||
|
<ProjectReference Include="..\..\shared\Lion.AbpPro.Shared.Hosting.Gateways\Lion.AbpPro.Shared.Hosting.Gateways.csproj" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
</Project> |
||||
@ -0,0 +1,24 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using System.Threading.Tasks; |
||||
|
using Microsoft.AspNetCore.Hosting; |
||||
|
using Microsoft.Extensions.Configuration; |
||||
|
using Microsoft.Extensions.Hosting; |
||||
|
using Microsoft.Extensions.Logging; |
||||
|
|
||||
|
namespace Lion.AbpPro.WebGateway |
||||
|
{ |
||||
|
public class Program |
||||
|
{ |
||||
|
public static void Main(string[] args) |
||||
|
{ |
||||
|
CreateHostBuilder(args).Build().Run(); |
||||
|
} |
||||
|
|
||||
|
public static IHostBuilder CreateHostBuilder(string[] args) => |
||||
|
Host.CreateDefaultBuilder(args) |
||||
|
.ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); }) |
||||
|
.UseAutofac(); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,14 @@ |
|||||
|
{ |
||||
|
"$schema": "http://json.schemastore.org/launchsettings.json", |
||||
|
"profiles": { |
||||
|
"Lion.AbpPro.WebGateway": { |
||||
|
"commandName": "Project", |
||||
|
"launchBrowser": false, |
||||
|
"launchUrl": "swagger", |
||||
|
"applicationUrl": "http://localhost:44314", |
||||
|
"environmentVariables": { |
||||
|
"ASPNETCORE_ENVIRONMENT": "Development" |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,29 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using System.Threading.Tasks; |
||||
|
using Microsoft.AspNetCore.Builder; |
||||
|
using Microsoft.AspNetCore.Hosting; |
||||
|
using Microsoft.AspNetCore.HttpsPolicy; |
||||
|
using Microsoft.AspNetCore.Mvc; |
||||
|
using Microsoft.Extensions.Configuration; |
||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
using Microsoft.Extensions.Hosting; |
||||
|
using Microsoft.Extensions.Logging; |
||||
|
using Microsoft.OpenApi.Models; |
||||
|
|
||||
|
namespace Lion.AbpPro.WebGateway |
||||
|
{ |
||||
|
public class Startup |
||||
|
{ |
||||
|
public void ConfigureServices(IServiceCollection services) |
||||
|
{ |
||||
|
services.AddApplication<WebGatewayModule>(); |
||||
|
} |
||||
|
|
||||
|
public void Configure(IApplicationBuilder app) |
||||
|
{ |
||||
|
app.InitializeApplication(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,66 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using Lion.AbpPro.Shared.Hosting.Gateways; |
||||
|
using Microsoft.AspNetCore.Builder; |
||||
|
using Microsoft.AspNetCore.Cors; |
||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
using Microsoft.OpenApi.Models; |
||||
|
using Ocelot.Middleware; |
||||
|
using Swashbuckle.AspNetCore.SwaggerUI; |
||||
|
using Volo.Abp; |
||||
|
using Volo.Abp.Modularity; |
||||
|
|
||||
|
namespace Lion.AbpPro.WebGateway |
||||
|
{ |
||||
|
[DependsOn( |
||||
|
typeof(SharedHostingGatewayModule))] |
||||
|
public class WebGatewayModule : AbpModule |
||||
|
{ |
||||
|
private const string DefaultCorsPolicyName = "Default"; |
||||
|
|
||||
|
public override void ConfigureServices(ServiceConfigurationContext context) |
||||
|
{ |
||||
|
ConfigureCors(context); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
public override void OnApplicationInitialization(ApplicationInitializationContext context) |
||||
|
{ |
||||
|
var app = context.GetApplicationBuilder(); |
||||
|
app.UseCorrelationId(); |
||||
|
app.UseCors(DefaultCorsPolicyName); |
||||
|
app.UseRouting(); |
||||
|
app.UseConfiguredEndpoints(endpoints => { endpoints.MapHealthChecks("/health"); }); |
||||
|
app.UseWebSockets(); |
||||
|
app.UseOcelot().Wait(); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 配置跨域
|
||||
|
/// </summary>
|
||||
|
private void ConfigureCors(ServiceConfigurationContext context) |
||||
|
{ |
||||
|
var configuration = context.Services.GetConfiguration(); |
||||
|
context.Services.AddCors(options => |
||||
|
{ |
||||
|
options.AddPolicy(DefaultCorsPolicyName, builder => |
||||
|
{ |
||||
|
builder |
||||
|
.WithOrigins( |
||||
|
configuration["App:CorsOrigins"] |
||||
|
.Split(",", StringSplitOptions.RemoveEmptyEntries) |
||||
|
.Select(o => o.RemovePostFix("/")) |
||||
|
.ToArray() |
||||
|
) |
||||
|
.WithAbpExposedHeaders() |
||||
|
.SetIsOriginAllowedToAllowWildcardSubdomains() |
||||
|
.AllowAnyHeader() |
||||
|
.AllowAnyMethod() |
||||
|
.AllowCredentials(); |
||||
|
}); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
} |
||||
@ -1,6 +1,6 @@ |
|||||
{ |
{ |
||||
"sdk": { |
"sdk": { |
||||
"version": "5.0.101", |
"version": "6.0.100", |
||||
"rollForward": "latestFeature" |
"rollForward": "latestFeature" |
||||
} |
} |
||||
} |
} |
||||
|
|||||
@ -1,41 +0,0 @@ |
|||||
<Project Sdk="Microsoft.NET.Sdk.Web"> |
|
||||
|
|
||||
<Import Project="../../../../common.props" /> |
|
||||
|
|
||||
<PropertyGroup> |
|
||||
<TargetFramework>net5.0</TargetFramework> |
|
||||
<RootNamespace>CompanyName.ProjectName.DataDictionaryManagement</RootNamespace> |
|
||||
<PreserveCompilationReferences>true</PreserveCompilationReferences> |
|
||||
<UserSecretsId>CompanyName.ProjectName.DataDictionaryManagement-c2d31439-b723-48e2-b061-5ebd7aeb6010</UserSecretsId> |
|
||||
</PropertyGroup> |
|
||||
|
|
||||
<ItemGroup> |
|
||||
<PackageReference Include="Serilog.AspNetCore" Version="$(SerilogAspNetCoreVersion)" /> |
|
||||
<PackageReference Include="Serilog.Sinks.Async" Version="$(SerilogSinksAsyncVersion)" /> |
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="$(MicrosoftVersion)" /> |
|
||||
<PackageReference Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" Version="$(MicrosoftVersion)" /> |
|
||||
<PackageReference Include="Volo.Abp.Autofac" Version="$(AbpPackageVersion)" /> |
|
||||
<PackageReference Include="Volo.Abp.Caching.StackExchangeRedis" Version="$(AbpPackageVersion)" /> |
|
||||
<PackageReference Include="Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy" Version="$(AbpPackageVersion)" /> |
|
||||
<PackageReference Include="Volo.Abp.EntityFrameworkCore.MySQL" Version="$(AbpPackageVersion)" /> |
|
||||
<PackageReference Include="Volo.Abp.AspNetCore.Serilog" Version="$(AbpPackageVersion)" /> |
|
||||
<PackageReference Include="Volo.Abp.Swashbuckle" Version="$(AbpPackageVersion)" /> |
|
||||
<PackageReference Include="Volo.Abp.PermissionManagement.EntityFrameworkCore" Version="$(AbpPackageVersion)" /> |
|
||||
<PackageReference Include="Volo.Abp.SettingManagement.EntityFrameworkCore" Version="$(AbpPackageVersion)" /> |
|
||||
<PackageReference Include="Volo.Abp.AuditLogging.EntityFrameworkCore" Version="$(AbpPackageVersion)" /> |
|
||||
</ItemGroup> |
|
||||
|
|
||||
<ItemGroup> |
|
||||
<ProjectReference Include="..\..\src\CompanyName.ProjectName.DataDictionaryManagement.HttpApi\CompanyName.ProjectName.DataDictionaryManagement.HttpApi.csproj" /> |
|
||||
<ProjectReference Include="..\..\src\CompanyName.ProjectName.DataDictionaryManagement.Application\CompanyName.ProjectName.DataDictionaryManagement.Application.csproj" /> |
|
||||
<ProjectReference Include="..\..\src\CompanyName.ProjectName.DataDictionaryManagement.EntityFrameworkCore\CompanyName.ProjectName.DataDictionaryManagement.EntityFrameworkCore.csproj" /> |
|
||||
</ItemGroup> |
|
||||
|
|
||||
<ItemGroup> |
|
||||
<Compile Remove="Logs\**" /> |
|
||||
<Content Remove="Logs\**" /> |
|
||||
<EmbeddedResource Remove="Logs\**" /> |
|
||||
<None Remove="Logs\**" /> |
|
||||
</ItemGroup> |
|
||||
|
|
||||
</Project> |
|
||||
@ -1,13 +0,0 @@ |
|||||
using Microsoft.AspNetCore.Mvc; |
|
||||
using Volo.Abp.AspNetCore.Mvc; |
|
||||
|
|
||||
namespace CompanyName.ProjectName.DataDictionaryManagement.Controllers |
|
||||
{ |
|
||||
public class HomeController : AbpController |
|
||||
{ |
|
||||
public ActionResult Index() |
|
||||
{ |
|
||||
return Redirect("~/swagger"); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,232 +0,0 @@ |
|||||
using System; |
|
||||
using System.Collections.Generic; |
|
||||
using System.Linq; |
|
||||
using Microsoft.AspNetCore.Authentication.JwtBearer; |
|
||||
using Microsoft.AspNetCore.Builder; |
|
||||
using Microsoft.AspNetCore.Cors; |
|
||||
using Microsoft.AspNetCore.DataProtection; |
|
||||
using Microsoft.Extensions.DependencyInjection; |
|
||||
using Microsoft.Extensions.Hosting; |
|
||||
using CompanyName.ProjectName.DataDictionaryManagement.EntityFrameworkCore; |
|
||||
using StackExchange.Redis; |
|
||||
using Microsoft.OpenApi.Models; |
|
||||
using Volo.Abp; |
|
||||
using Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy; |
|
||||
using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared; |
|
||||
using Volo.Abp.AspNetCore.Serilog; |
|
||||
using Volo.Abp.AuditLogging.EntityFrameworkCore; |
|
||||
using Volo.Abp.Autofac; |
|
||||
using Volo.Abp.Caching; |
|
||||
using Volo.Abp.Caching.StackExchangeRedis; |
|
||||
using Volo.Abp.EntityFrameworkCore; |
|
||||
using Volo.Abp.EntityFrameworkCore.MySQL; |
|
||||
using Volo.Abp.Localization; |
|
||||
using Volo.Abp.Modularity; |
|
||||
using Volo.Abp.PermissionManagement.EntityFrameworkCore; |
|
||||
using Volo.Abp.SettingManagement.EntityFrameworkCore; |
|
||||
using Volo.Abp.Swashbuckle; |
|
||||
using Volo.Abp.VirtualFileSystem; |
|
||||
|
|
||||
namespace CompanyName.ProjectName.DataDictionaryManagement |
|
||||
{ |
|
||||
[DependsOn( |
|
||||
typeof(DataDictionaryManagementApplicationModule), |
|
||||
typeof(DataDictionaryManagementEntityFrameworkCoreModule), |
|
||||
typeof(DataDictionaryManagementHttpApiModule), |
|
||||
typeof(AbpAspNetCoreMvcUiMultiTenancyModule), |
|
||||
typeof(AbpAutofacModule), |
|
||||
typeof(AbpCachingStackExchangeRedisModule), |
|
||||
typeof(AbpEntityFrameworkCoreMySQLModule), |
|
||||
typeof(AbpAuditLoggingEntityFrameworkCoreModule), |
|
||||
typeof(AbpPermissionManagementEntityFrameworkCoreModule), |
|
||||
typeof(AbpSettingManagementEntityFrameworkCoreModule), |
|
||||
typeof(AbpAspNetCoreSerilogModule), |
|
||||
typeof(AbpSwashbuckleModule) |
|
||||
)] |
|
||||
public class DataDictionaryManagementHttpApiHostModule : AbpModule |
|
||||
{ |
|
||||
private const string DefaultCorsPolicyName = "Default"; |
|
||||
|
|
||||
public override void ConfigureServices(ServiceConfigurationContext context) |
|
||||
{ |
|
||||
|
|
||||
// Configure<AbpMultiTenancyOptions>(options =>
|
|
||||
// {
|
|
||||
// options.IsEnabled = MultiTenancyConsts.IsEnabled;
|
|
||||
// });
|
|
||||
|
|
||||
ConfigureSwaggerServices(context); |
|
||||
ConfigureCache(context); |
|
||||
ConfigureCors(context); |
|
||||
ConfigureDB(); |
|
||||
ConfigureLocalization(); |
|
||||
ConfigureVirtualFileSystem(context); |
|
||||
} |
|
||||
|
|
||||
public override void OnApplicationInitialization(ApplicationInitializationContext context) |
|
||||
{ |
|
||||
var app = context.GetApplicationBuilder(); |
|
||||
var env = context.GetEnvironment(); |
|
||||
|
|
||||
if (env.IsDevelopment()) |
|
||||
{ |
|
||||
app.UseDeveloperExceptionPage(); |
|
||||
} |
|
||||
else |
|
||||
{ |
|
||||
app.UseErrorPage(); |
|
||||
app.UseHsts(); |
|
||||
} |
|
||||
|
|
||||
app.UseHttpsRedirection(); |
|
||||
app.UseCorrelationId(); |
|
||||
app.UseStaticFiles(); |
|
||||
app.UseRouting(); |
|
||||
app.UseCors(DefaultCorsPolicyName); |
|
||||
app.UseAuthentication(); |
|
||||
// if (MultiTenancyConsts.IsEnabled)
|
|
||||
// {
|
|
||||
// app.UseMultiTenancy();
|
|
||||
// }
|
|
||||
app.UseAbpRequestLocalization(); |
|
||||
app.UseAuthorization(); |
|
||||
app.UseSwagger(); |
|
||||
app.UseAbpSwaggerUI(options => |
|
||||
{ |
|
||||
options.SwaggerEndpoint("/swagger/v1/swagger.json", "Support APP API"); |
|
||||
|
|
||||
var configuration = context.GetConfiguration(); |
|
||||
options.OAuthClientId(configuration["AuthServer:SwaggerClientId"]); |
|
||||
options.OAuthClientSecret(configuration["AuthServer:SwaggerClientSecret"]); |
|
||||
options.OAuthScopes("DataDictionaryManagement"); |
|
||||
}); |
|
||||
app.UseAuditing(); |
|
||||
app.UseAbpSerilogEnrichers(); |
|
||||
app.UseConfiguredEndpoints(); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 配置跨域
|
|
||||
/// </summary>
|
|
||||
/// <param name="context"></param>
|
|
||||
private void ConfigureCors(ServiceConfigurationContext context) |
|
||||
{ |
|
||||
var configuration = context.Services.GetConfiguration(); |
|
||||
context.Services.AddCors(options => |
|
||||
{ |
|
||||
options.AddPolicy(DefaultCorsPolicyName, builder => |
|
||||
{ |
|
||||
builder |
|
||||
.WithOrigins( |
|
||||
configuration["App:CorsOrigins"] |
|
||||
.Split(",", StringSplitOptions.RemoveEmptyEntries) |
|
||||
.Select(o => o.RemovePostFix("/")) |
|
||||
.ToArray() |
|
||||
) |
|
||||
.WithAbpExposedHeaders() |
|
||||
.SetIsOriginAllowedToAllowWildcardSubdomains() |
|
||||
.AllowAnyHeader() |
|
||||
.AllowAnyMethod() |
|
||||
.AllowCredentials(); |
|
||||
}); |
|
||||
}); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 配置SwaggerUI
|
|
||||
/// </summary>
|
|
||||
/// <param name="context"></param>
|
|
||||
private static void ConfigureSwaggerServices(ServiceConfigurationContext context) |
|
||||
{ |
|
||||
context.Services.AddSwaggerGen( |
|
||||
options => |
|
||||
{ |
|
||||
options.SwaggerDoc("v1", new OpenApiInfo {Title = "DataDictionaryManagement API", Version = "v1"}); |
|
||||
|
|
||||
options.DocInclusionPredicate((docName, description) => true); |
|
||||
|
|
||||
#region 添加token
|
|
||||
|
|
||||
options.AddSecurityDefinition(JwtBearerDefaults.AuthenticationScheme, new OpenApiSecurityScheme() |
|
||||
{ |
|
||||
Description = "请输入Token", |
|
||||
Name = "Authorization", |
|
||||
In = ParameterLocation.Header, |
|
||||
Type = SecuritySchemeType.Http, |
|
||||
Scheme = JwtBearerDefaults.AuthenticationScheme, |
|
||||
BearerFormat = "JWT" |
|
||||
}); |
|
||||
options.AddSecurityRequirement(new OpenApiSecurityRequirement |
|
||||
{ |
|
||||
{ |
|
||||
new OpenApiSecurityScheme |
|
||||
{ |
|
||||
Reference = new OpenApiReference |
|
||||
{ |
|
||||
Type = ReferenceType.SecurityScheme, Id = "Bearer" |
|
||||
} |
|
||||
}, |
|
||||
new List<string>() |
|
||||
} |
|
||||
}); |
|
||||
|
|
||||
#endregion
|
|
||||
}); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Redis缓存
|
|
||||
/// </summary>
|
|
||||
/// <param name="context"></param>
|
|
||||
private void ConfigureCache(ServiceConfigurationContext context) |
|
||||
{ |
|
||||
var hostingEnvironment = context.Services.GetHostingEnvironment(); |
|
||||
var configuration = context.Services.GetConfiguration(); |
|
||||
Configure<AbpDistributedCacheOptions>(options => { options.KeyPrefix = "DataDictionaryManagement:"; }); |
|
||||
|
|
||||
if (!hostingEnvironment.IsDevelopment()) |
|
||||
{ |
|
||||
var redis = ConnectionMultiplexer.Connect(configuration["Redis:Configuration"]); |
|
||||
context.Services |
|
||||
.AddDataProtection() |
|
||||
.PersistKeysToStackExchangeRedis(redis, "DataDictionaryManagement-Protection-Keys"); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
private void ConfigureDB() |
|
||||
{ |
|
||||
Configure<AbpDbContextOptions>(options => { options.UseMySQL(); }); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
///配置本地化
|
|
||||
/// </summary>
|
|
||||
private void ConfigureLocalization() |
|
||||
{ |
|
||||
Configure<AbpLocalizationOptions>(options => |
|
||||
{ |
|
||||
options.Languages.Add(new LanguageInfo("cs", "cs", "Čeština")); |
|
||||
options.Languages.Add(new LanguageInfo("en", "en", "English")); |
|
||||
options.Languages.Add(new LanguageInfo("en-GB", "en-GB", "English (UK)")); |
|
||||
options.Languages.Add(new LanguageInfo("fr", "fr", "Français")); |
|
||||
options.Languages.Add(new LanguageInfo("hu", "hu", "Magyar")); |
|
||||
options.Languages.Add(new LanguageInfo("pt-BR", "pt-BR", "Português")); |
|
||||
options.Languages.Add(new LanguageInfo("ru", "ru", "Русский")); |
|
||||
options.Languages.Add(new LanguageInfo("tr", "tr", "Türkçe")); |
|
||||
options.Languages.Add(new LanguageInfo("zh-Hans", "zh-Hans", "简体中文")); |
|
||||
options.Languages.Add(new LanguageInfo("zh-Hant", "zh-Hant", "繁體中文")); |
|
||||
}); |
|
||||
} |
|
||||
/// <summary>
|
|
||||
/// 配置虚拟文件系统
|
|
||||
/// </summary>
|
|
||||
/// <param name="context"></param>
|
|
||||
private void ConfigureVirtualFileSystem(ServiceConfigurationContext context) |
|
||||
{ |
|
||||
Configure<AbpVirtualFileSystemOptions>(options => |
|
||||
{ |
|
||||
options.FileSets.AddEmbedded<DataDictionaryManagementHttpApiHostModule>(); |
|
||||
}); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,18 +0,0 @@ |
|||||
FROM mcr.microsoft.com/dotnet/core/aspnet:3.0-buster-slim AS base |
|
||||
WORKDIR /app |
|
||||
EXPOSE 80 |
|
||||
|
|
||||
FROM mcr.microsoft.com/dotnet/core/sdk:3.0-buster AS build |
|
||||
WORKDIR /src |
|
||||
COPY . . |
|
||||
WORKDIR /src/templates/service/host/CompanyName.ProjectName.DataDictionaryManagement.HttpApi.Host |
|
||||
RUN dotnet restore -nowarn:msb3202,nu1503 |
|
||||
RUN dotnet build --no-restore -c Release -o /app |
|
||||
|
|
||||
FROM build AS publish |
|
||||
RUN dotnet publish --no-restore -c Release -o /app |
|
||||
|
|
||||
FROM base AS final |
|
||||
WORKDIR /app |
|
||||
COPY --from=publish /app . |
|
||||
ENTRYPOINT ["dotnet", "CompanyName.ProjectName.DataDictionaryManagement.HttpApi.Host.dll"] |
|
||||
@ -1,21 +0,0 @@ |
|||||
using Microsoft.EntityFrameworkCore; |
|
||||
using Volo.Abp.EntityFrameworkCore; |
|
||||
|
|
||||
namespace CompanyName.ProjectName.DataDictionaryManagement.EntityFrameworkCore |
|
||||
{ |
|
||||
public class DataDictionaryManagementHttpApiHostMigrationsDbContext : AbpDbContext<DataDictionaryManagementHttpApiHostMigrationsDbContext> |
|
||||
{ |
|
||||
public DataDictionaryManagementHttpApiHostMigrationsDbContext(DbContextOptions<DataDictionaryManagementHttpApiHostMigrationsDbContext> options) |
|
||||
: base(options) |
|
||||
{ |
|
||||
|
|
||||
} |
|
||||
|
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder) |
|
||||
{ |
|
||||
base.OnModelCreating(modelBuilder); |
|
||||
|
|
||||
modelBuilder.ConfigureDataDictionaryManagement(); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,28 +0,0 @@ |
|||||
using System.IO; |
|
||||
using Microsoft.EntityFrameworkCore; |
|
||||
using Microsoft.EntityFrameworkCore.Design; |
|
||||
using Microsoft.Extensions.Configuration; |
|
||||
|
|
||||
namespace CompanyName.ProjectName.DataDictionaryManagement.EntityFrameworkCore |
|
||||
{ |
|
||||
public class DataDictionaryManagementHttpApiHostMigrationsDbContextFactory : IDesignTimeDbContextFactory<DataDictionaryManagementHttpApiHostMigrationsDbContext> |
|
||||
{ |
|
||||
public DataDictionaryManagementHttpApiHostMigrationsDbContext CreateDbContext(string[] args) |
|
||||
{ |
|
||||
var configuration = BuildConfiguration(); |
|
||||
|
|
||||
var builder = new DbContextOptionsBuilder<DataDictionaryManagementHttpApiHostMigrationsDbContext>() |
|
||||
.UseMySql(configuration.GetConnectionString("DataDictionaryManagement"), MySqlServerVersion.LatestSupportedServerVersion); |
|
||||
return new DataDictionaryManagementHttpApiHostMigrationsDbContext(builder.Options); |
|
||||
} |
|
||||
|
|
||||
private static IConfigurationRoot BuildConfiguration() |
|
||||
{ |
|
||||
var builder = new ConfigurationBuilder() |
|
||||
.SetBasePath(Directory.GetCurrentDirectory()) |
|
||||
.AddJsonFile("appsettings.json", optional: false); |
|
||||
|
|
||||
return builder.Build(); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,153 +0,0 @@ |
|||||
// <auto-generated />
|
|
||||
using System; |
|
||||
using CompanyName.ProjectName.DataDictionaryManagement.EntityFrameworkCore; |
|
||||
using Microsoft.EntityFrameworkCore; |
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure; |
|
||||
using Microsoft.EntityFrameworkCore.Migrations; |
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion; |
|
||||
using Volo.Abp.EntityFrameworkCore; |
|
||||
|
|
||||
namespace CompanyName.ProjectName.DataDictionaryManagement.Migrations |
|
||||
{ |
|
||||
[DbContext(typeof(DataDictionaryManagementHttpApiHostMigrationsDbContext))] |
|
||||
[Migration("20210812130334_Init")] |
|
||||
partial class Init |
|
||||
{ |
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder) |
|
||||
{ |
|
||||
#pragma warning disable 612, 618
|
|
||||
modelBuilder |
|
||||
.HasAnnotation("_Abp_DatabaseProvider", EfCoreDatabaseProvider.MySql) |
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 64) |
|
||||
.HasAnnotation("ProductVersion", "5.0.7"); |
|
||||
|
|
||||
modelBuilder.Entity("CompanyName.ProjectName.DataDictionaryManagement.DataDictionaries.Aggregates.DataDictionary", b => |
|
||||
{ |
|
||||
b.Property<Guid>("Id") |
|
||||
.ValueGeneratedOnAdd() |
|
||||
.HasColumnType("char(36)"); |
|
||||
|
|
||||
b.Property<string>("Code") |
|
||||
.IsRequired() |
|
||||
.HasMaxLength(64) |
|
||||
.HasColumnType("varchar(64) CHARACTER SET utf8mb4"); |
|
||||
|
|
||||
b.Property<string>("ConcurrencyStamp") |
|
||||
.IsConcurrencyToken() |
|
||||
.HasMaxLength(40) |
|
||||
.HasColumnType("varchar(40) CHARACTER SET utf8mb4") |
|
||||
.HasColumnName("ConcurrencyStamp"); |
|
||||
|
|
||||
b.Property<DateTime>("CreationTime") |
|
||||
.HasColumnType("datetime(6)") |
|
||||
.HasColumnName("CreationTime"); |
|
||||
|
|
||||
b.Property<Guid?>("CreatorId") |
|
||||
.HasColumnType("char(36)") |
|
||||
.HasColumnName("CreatorId"); |
|
||||
|
|
||||
b.Property<Guid?>("DeleterId") |
|
||||
.HasColumnType("char(36)") |
|
||||
.HasColumnName("DeleterId"); |
|
||||
|
|
||||
b.Property<DateTime?>("DeletionTime") |
|
||||
.HasColumnType("datetime(6)") |
|
||||
.HasColumnName("DeletionTime"); |
|
||||
|
|
||||
b.Property<string>("Description") |
|
||||
.IsRequired() |
|
||||
.HasMaxLength(1024) |
|
||||
.HasColumnType("varchar(1024) CHARACTER SET utf8mb4"); |
|
||||
|
|
||||
b.Property<string>("DisplayText") |
|
||||
.IsRequired() |
|
||||
.HasMaxLength(64) |
|
||||
.HasColumnType("varchar(64) CHARACTER SET utf8mb4"); |
|
||||
|
|
||||
b.Property<string>("ExtraProperties") |
|
||||
.HasColumnType("longtext CHARACTER SET utf8mb4") |
|
||||
.HasColumnName("ExtraProperties"); |
|
||||
|
|
||||
b.Property<bool>("IsDeleted") |
|
||||
.ValueGeneratedOnAdd() |
|
||||
.HasColumnType("tinyint(1)") |
|
||||
.HasDefaultValue(false) |
|
||||
.HasColumnName("IsDeleted"); |
|
||||
|
|
||||
b.Property<DateTime?>("LastModificationTime") |
|
||||
.HasColumnType("datetime(6)") |
|
||||
.HasColumnName("LastModificationTime"); |
|
||||
|
|
||||
b.Property<Guid?>("LastModifierId") |
|
||||
.HasColumnType("char(36)") |
|
||||
.HasColumnName("LastModifierId"); |
|
||||
|
|
||||
b.HasKey("Id"); |
|
||||
|
|
||||
b.ToTable("DataDictionary"); |
|
||||
}); |
|
||||
|
|
||||
modelBuilder.Entity("CompanyName.ProjectName.DataDictionaryManagement.DataDictionaries.Aggregates.DataDictionaryDetail", b => |
|
||||
{ |
|
||||
b.Property<Guid>("Id") |
|
||||
.ValueGeneratedOnAdd() |
|
||||
.HasColumnType("char(36)"); |
|
||||
|
|
||||
b.Property<string>("Code") |
|
||||
.HasColumnType("longtext CHARACTER SET utf8mb4"); |
|
||||
|
|
||||
b.Property<DateTime>("CreationTime") |
|
||||
.HasColumnType("datetime(6)") |
|
||||
.HasColumnName("CreationTime"); |
|
||||
|
|
||||
b.Property<Guid?>("CreatorId") |
|
||||
.HasColumnType("char(36)") |
|
||||
.HasColumnName("CreatorId"); |
|
||||
|
|
||||
b.Property<Guid>("DataDictionaryId") |
|
||||
.HasColumnType("char(36)"); |
|
||||
|
|
||||
b.Property<string>("Description") |
|
||||
.HasColumnType("longtext CHARACTER SET utf8mb4"); |
|
||||
|
|
||||
b.Property<string>("DisplayText") |
|
||||
.HasColumnType("longtext CHARACTER SET utf8mb4"); |
|
||||
|
|
||||
b.Property<bool>("IsEnabled") |
|
||||
.HasColumnType("tinyint(1)"); |
|
||||
|
|
||||
b.Property<DateTime?>("LastModificationTime") |
|
||||
.HasColumnType("datetime(6)") |
|
||||
.HasColumnName("LastModificationTime"); |
|
||||
|
|
||||
b.Property<Guid?>("LastModifierId") |
|
||||
.HasColumnType("char(36)") |
|
||||
.HasColumnName("LastModifierId"); |
|
||||
|
|
||||
b.Property<int>("Order") |
|
||||
.HasColumnType("int"); |
|
||||
|
|
||||
b.HasKey("Id"); |
|
||||
|
|
||||
b.HasIndex("DataDictionaryId"); |
|
||||
|
|
||||
b.ToTable("DataDictionaryDetail"); |
|
||||
}); |
|
||||
|
|
||||
modelBuilder.Entity("CompanyName.ProjectName.DataDictionaryManagement.DataDictionaries.Aggregates.DataDictionaryDetail", b => |
|
||||
{ |
|
||||
b.HasOne("CompanyName.ProjectName.DataDictionaryManagement.DataDictionaries.Aggregates.DataDictionary", null) |
|
||||
.WithMany("Details") |
|
||||
.HasForeignKey("DataDictionaryId") |
|
||||
.OnDelete(DeleteBehavior.Cascade) |
|
||||
.IsRequired(); |
|
||||
}); |
|
||||
|
|
||||
modelBuilder.Entity("CompanyName.ProjectName.DataDictionaryManagement.DataDictionaries.Aggregates.DataDictionary", b => |
|
||||
{ |
|
||||
b.Navigation("Details"); |
|
||||
}); |
|
||||
#pragma warning restore 612, 618
|
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,75 +0,0 @@ |
|||||
using System; |
|
||||
using Microsoft.EntityFrameworkCore.Migrations; |
|
||||
|
|
||||
namespace CompanyName.ProjectName.DataDictionaryManagement.Migrations |
|
||||
{ |
|
||||
public partial class Init : Migration |
|
||||
{ |
|
||||
protected override void Up(MigrationBuilder migrationBuilder) |
|
||||
{ |
|
||||
migrationBuilder.CreateTable( |
|
||||
name: "DataDictionary", |
|
||||
columns: table => new |
|
||||
{ |
|
||||
Id = table.Column<Guid>(type: "char(36)", nullable: false), |
|
||||
Code = table.Column<string>(type: "varchar(64) CHARACTER SET utf8mb4", maxLength: 64, nullable: false), |
|
||||
DisplayText = table.Column<string>(type: "varchar(64) CHARACTER SET utf8mb4", maxLength: 64, nullable: false), |
|
||||
Description = table.Column<string>(type: "varchar(1024) CHARACTER SET utf8mb4", maxLength: 1024, nullable: false), |
|
||||
ExtraProperties = table.Column<string>(type: "longtext CHARACTER SET utf8mb4", nullable: true), |
|
||||
ConcurrencyStamp = table.Column<string>(type: "varchar(40) CHARACTER SET utf8mb4", maxLength: 40, nullable: true), |
|
||||
CreationTime = table.Column<DateTime>(type: "datetime(6)", nullable: false), |
|
||||
CreatorId = table.Column<Guid>(type: "char(36)", nullable: true), |
|
||||
LastModificationTime = table.Column<DateTime>(type: "datetime(6)", nullable: true), |
|
||||
LastModifierId = table.Column<Guid>(type: "char(36)", nullable: true), |
|
||||
IsDeleted = table.Column<bool>(type: "tinyint(1)", nullable: false, defaultValue: false), |
|
||||
DeleterId = table.Column<Guid>(type: "char(36)", nullable: true), |
|
||||
DeletionTime = table.Column<DateTime>(type: "datetime(6)", nullable: true) |
|
||||
}, |
|
||||
constraints: table => |
|
||||
{ |
|
||||
table.PrimaryKey("PK_DataDictionary", x => x.Id); |
|
||||
}); |
|
||||
|
|
||||
migrationBuilder.CreateTable( |
|
||||
name: "DataDictionaryDetail", |
|
||||
columns: table => new |
|
||||
{ |
|
||||
Id = table.Column<Guid>(type: "char(36)", nullable: false), |
|
||||
DataDictionaryId = table.Column<Guid>(type: "char(36)", nullable: false), |
|
||||
Code = table.Column<string>(type: "longtext CHARACTER SET utf8mb4", nullable: true), |
|
||||
Order = table.Column<int>(type: "int", nullable: false), |
|
||||
DisplayText = table.Column<string>(type: "longtext CHARACTER SET utf8mb4", nullable: true), |
|
||||
Description = table.Column<string>(type: "longtext CHARACTER SET utf8mb4", nullable: true), |
|
||||
IsEnabled = table.Column<bool>(type: "tinyint(1)", nullable: false), |
|
||||
CreationTime = table.Column<DateTime>(type: "datetime(6)", nullable: false), |
|
||||
CreatorId = table.Column<Guid>(type: "char(36)", nullable: true), |
|
||||
LastModificationTime = table.Column<DateTime>(type: "datetime(6)", nullable: true), |
|
||||
LastModifierId = table.Column<Guid>(type: "char(36)", nullable: true) |
|
||||
}, |
|
||||
constraints: table => |
|
||||
{ |
|
||||
table.PrimaryKey("PK_DataDictionaryDetail", x => x.Id); |
|
||||
table.ForeignKey( |
|
||||
name: "FK_DataDictionaryDetail_DataDictionary_DataDictionaryId", |
|
||||
column: x => x.DataDictionaryId, |
|
||||
principalTable: "DataDictionary", |
|
||||
principalColumn: "Id", |
|
||||
onDelete: ReferentialAction.Cascade); |
|
||||
}); |
|
||||
|
|
||||
migrationBuilder.CreateIndex( |
|
||||
name: "IX_DataDictionaryDetail_DataDictionaryId", |
|
||||
table: "DataDictionaryDetail", |
|
||||
column: "DataDictionaryId"); |
|
||||
} |
|
||||
|
|
||||
protected override void Down(MigrationBuilder migrationBuilder) |
|
||||
{ |
|
||||
migrationBuilder.DropTable( |
|
||||
name: "DataDictionaryDetail"); |
|
||||
|
|
||||
migrationBuilder.DropTable( |
|
||||
name: "DataDictionary"); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,157 +0,0 @@ |
|||||
// <auto-generated />
|
|
||||
using System; |
|
||||
using CompanyName.ProjectName.DataDictionaryManagement.EntityFrameworkCore; |
|
||||
using Microsoft.EntityFrameworkCore; |
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure; |
|
||||
using Microsoft.EntityFrameworkCore.Migrations; |
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion; |
|
||||
using Volo.Abp.EntityFrameworkCore; |
|
||||
|
|
||||
namespace CompanyName.ProjectName.DataDictionaryManagement.Migrations |
|
||||
{ |
|
||||
[DbContext(typeof(DataDictionaryManagementHttpApiHostMigrationsDbContext))] |
|
||||
[Migration("20210812154152_AddTenantId")] |
|
||||
partial class AddTenantId |
|
||||
{ |
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder) |
|
||||
{ |
|
||||
#pragma warning disable 612, 618
|
|
||||
modelBuilder |
|
||||
.HasAnnotation("_Abp_DatabaseProvider", EfCoreDatabaseProvider.MySql) |
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 64) |
|
||||
.HasAnnotation("ProductVersion", "5.0.7"); |
|
||||
|
|
||||
modelBuilder.Entity("CompanyName.ProjectName.DataDictionaryManagement.DataDictionaries.Aggregates.DataDictionary", b => |
|
||||
{ |
|
||||
b.Property<Guid>("Id") |
|
||||
.ValueGeneratedOnAdd() |
|
||||
.HasColumnType("char(36)"); |
|
||||
|
|
||||
b.Property<string>("Code") |
|
||||
.IsRequired() |
|
||||
.HasMaxLength(64) |
|
||||
.HasColumnType("varchar(64) CHARACTER SET utf8mb4"); |
|
||||
|
|
||||
b.Property<string>("ConcurrencyStamp") |
|
||||
.IsConcurrencyToken() |
|
||||
.HasMaxLength(40) |
|
||||
.HasColumnType("varchar(40) CHARACTER SET utf8mb4") |
|
||||
.HasColumnName("ConcurrencyStamp"); |
|
||||
|
|
||||
b.Property<DateTime>("CreationTime") |
|
||||
.HasColumnType("datetime(6)") |
|
||||
.HasColumnName("CreationTime"); |
|
||||
|
|
||||
b.Property<Guid?>("CreatorId") |
|
||||
.HasColumnType("char(36)") |
|
||||
.HasColumnName("CreatorId"); |
|
||||
|
|
||||
b.Property<Guid?>("DeleterId") |
|
||||
.HasColumnType("char(36)") |
|
||||
.HasColumnName("DeleterId"); |
|
||||
|
|
||||
b.Property<DateTime?>("DeletionTime") |
|
||||
.HasColumnType("datetime(6)") |
|
||||
.HasColumnName("DeletionTime"); |
|
||||
|
|
||||
b.Property<string>("Description") |
|
||||
.IsRequired() |
|
||||
.HasMaxLength(1024) |
|
||||
.HasColumnType("varchar(1024) CHARACTER SET utf8mb4"); |
|
||||
|
|
||||
b.Property<string>("DisplayText") |
|
||||
.IsRequired() |
|
||||
.HasMaxLength(64) |
|
||||
.HasColumnType("varchar(64) CHARACTER SET utf8mb4"); |
|
||||
|
|
||||
b.Property<string>("ExtraProperties") |
|
||||
.HasColumnType("longtext CHARACTER SET utf8mb4") |
|
||||
.HasColumnName("ExtraProperties"); |
|
||||
|
|
||||
b.Property<bool>("IsDeleted") |
|
||||
.ValueGeneratedOnAdd() |
|
||||
.HasColumnType("tinyint(1)") |
|
||||
.HasDefaultValue(false) |
|
||||
.HasColumnName("IsDeleted"); |
|
||||
|
|
||||
b.Property<DateTime?>("LastModificationTime") |
|
||||
.HasColumnType("datetime(6)") |
|
||||
.HasColumnName("LastModificationTime"); |
|
||||
|
|
||||
b.Property<Guid?>("LastModifierId") |
|
||||
.HasColumnType("char(36)") |
|
||||
.HasColumnName("LastModifierId"); |
|
||||
|
|
||||
b.Property<Guid?>("TenantId") |
|
||||
.HasColumnType("char(36)") |
|
||||
.HasColumnName("TenantId"); |
|
||||
|
|
||||
b.HasKey("Id"); |
|
||||
|
|
||||
b.ToTable("DataDictionary"); |
|
||||
}); |
|
||||
|
|
||||
modelBuilder.Entity("CompanyName.ProjectName.DataDictionaryManagement.DataDictionaries.Aggregates.DataDictionaryDetail", b => |
|
||||
{ |
|
||||
b.Property<Guid>("Id") |
|
||||
.ValueGeneratedOnAdd() |
|
||||
.HasColumnType("char(36)"); |
|
||||
|
|
||||
b.Property<string>("Code") |
|
||||
.HasColumnType("longtext CHARACTER SET utf8mb4"); |
|
||||
|
|
||||
b.Property<DateTime>("CreationTime") |
|
||||
.HasColumnType("datetime(6)") |
|
||||
.HasColumnName("CreationTime"); |
|
||||
|
|
||||
b.Property<Guid?>("CreatorId") |
|
||||
.HasColumnType("char(36)") |
|
||||
.HasColumnName("CreatorId"); |
|
||||
|
|
||||
b.Property<Guid>("DataDictionaryId") |
|
||||
.HasColumnType("char(36)"); |
|
||||
|
|
||||
b.Property<string>("Description") |
|
||||
.HasColumnType("longtext CHARACTER SET utf8mb4"); |
|
||||
|
|
||||
b.Property<string>("DisplayText") |
|
||||
.HasColumnType("longtext CHARACTER SET utf8mb4"); |
|
||||
|
|
||||
b.Property<bool>("IsEnabled") |
|
||||
.HasColumnType("tinyint(1)"); |
|
||||
|
|
||||
b.Property<DateTime?>("LastModificationTime") |
|
||||
.HasColumnType("datetime(6)") |
|
||||
.HasColumnName("LastModificationTime"); |
|
||||
|
|
||||
b.Property<Guid?>("LastModifierId") |
|
||||
.HasColumnType("char(36)") |
|
||||
.HasColumnName("LastModifierId"); |
|
||||
|
|
||||
b.Property<int>("Order") |
|
||||
.HasColumnType("int"); |
|
||||
|
|
||||
b.HasKey("Id"); |
|
||||
|
|
||||
b.HasIndex("DataDictionaryId"); |
|
||||
|
|
||||
b.ToTable("DataDictionaryDetail"); |
|
||||
}); |
|
||||
|
|
||||
modelBuilder.Entity("CompanyName.ProjectName.DataDictionaryManagement.DataDictionaries.Aggregates.DataDictionaryDetail", b => |
|
||||
{ |
|
||||
b.HasOne("CompanyName.ProjectName.DataDictionaryManagement.DataDictionaries.Aggregates.DataDictionary", null) |
|
||||
.WithMany("Details") |
|
||||
.HasForeignKey("DataDictionaryId") |
|
||||
.OnDelete(DeleteBehavior.Cascade) |
|
||||
.IsRequired(); |
|
||||
}); |
|
||||
|
|
||||
modelBuilder.Entity("CompanyName.ProjectName.DataDictionaryManagement.DataDictionaries.Aggregates.DataDictionary", b => |
|
||||
{ |
|
||||
b.Navigation("Details"); |
|
||||
}); |
|
||||
#pragma warning restore 612, 618
|
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,24 +0,0 @@ |
|||||
using System; |
|
||||
using Microsoft.EntityFrameworkCore.Migrations; |
|
||||
|
|
||||
namespace CompanyName.ProjectName.DataDictionaryManagement.Migrations |
|
||||
{ |
|
||||
public partial class AddTenantId : Migration |
|
||||
{ |
|
||||
protected override void Up(MigrationBuilder migrationBuilder) |
|
||||
{ |
|
||||
migrationBuilder.AddColumn<Guid>( |
|
||||
name: "TenantId", |
|
||||
table: "DataDictionary", |
|
||||
type: "char(36)", |
|
||||
nullable: true); |
|
||||
} |
|
||||
|
|
||||
protected override void Down(MigrationBuilder migrationBuilder) |
|
||||
{ |
|
||||
migrationBuilder.DropColumn( |
|
||||
name: "TenantId", |
|
||||
table: "DataDictionary"); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,155 +0,0 @@ |
|||||
// <auto-generated />
|
|
||||
using System; |
|
||||
using CompanyName.ProjectName.DataDictionaryManagement.EntityFrameworkCore; |
|
||||
using Microsoft.EntityFrameworkCore; |
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure; |
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion; |
|
||||
using Volo.Abp.EntityFrameworkCore; |
|
||||
|
|
||||
namespace CompanyName.ProjectName.DataDictionaryManagement.Migrations |
|
||||
{ |
|
||||
[DbContext(typeof(DataDictionaryManagementHttpApiHostMigrationsDbContext))] |
|
||||
partial class DataDictionaryManagementHttpApiHostMigrationsDbContextModelSnapshot : ModelSnapshot |
|
||||
{ |
|
||||
protected override void BuildModel(ModelBuilder modelBuilder) |
|
||||
{ |
|
||||
#pragma warning disable 612, 618
|
|
||||
modelBuilder |
|
||||
.HasAnnotation("_Abp_DatabaseProvider", EfCoreDatabaseProvider.MySql) |
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 64) |
|
||||
.HasAnnotation("ProductVersion", "5.0.7"); |
|
||||
|
|
||||
modelBuilder.Entity("CompanyName.ProjectName.DataDictionaryManagement.DataDictionaries.Aggregates.DataDictionary", b => |
|
||||
{ |
|
||||
b.Property<Guid>("Id") |
|
||||
.ValueGeneratedOnAdd() |
|
||||
.HasColumnType("char(36)"); |
|
||||
|
|
||||
b.Property<string>("Code") |
|
||||
.IsRequired() |
|
||||
.HasMaxLength(64) |
|
||||
.HasColumnType("varchar(64) CHARACTER SET utf8mb4"); |
|
||||
|
|
||||
b.Property<string>("ConcurrencyStamp") |
|
||||
.IsConcurrencyToken() |
|
||||
.HasMaxLength(40) |
|
||||
.HasColumnType("varchar(40) CHARACTER SET utf8mb4") |
|
||||
.HasColumnName("ConcurrencyStamp"); |
|
||||
|
|
||||
b.Property<DateTime>("CreationTime") |
|
||||
.HasColumnType("datetime(6)") |
|
||||
.HasColumnName("CreationTime"); |
|
||||
|
|
||||
b.Property<Guid?>("CreatorId") |
|
||||
.HasColumnType("char(36)") |
|
||||
.HasColumnName("CreatorId"); |
|
||||
|
|
||||
b.Property<Guid?>("DeleterId") |
|
||||
.HasColumnType("char(36)") |
|
||||
.HasColumnName("DeleterId"); |
|
||||
|
|
||||
b.Property<DateTime?>("DeletionTime") |
|
||||
.HasColumnType("datetime(6)") |
|
||||
.HasColumnName("DeletionTime"); |
|
||||
|
|
||||
b.Property<string>("Description") |
|
||||
.IsRequired() |
|
||||
.HasMaxLength(1024) |
|
||||
.HasColumnType("varchar(1024) CHARACTER SET utf8mb4"); |
|
||||
|
|
||||
b.Property<string>("DisplayText") |
|
||||
.IsRequired() |
|
||||
.HasMaxLength(64) |
|
||||
.HasColumnType("varchar(64) CHARACTER SET utf8mb4"); |
|
||||
|
|
||||
b.Property<string>("ExtraProperties") |
|
||||
.HasColumnType("longtext CHARACTER SET utf8mb4") |
|
||||
.HasColumnName("ExtraProperties"); |
|
||||
|
|
||||
b.Property<bool>("IsDeleted") |
|
||||
.ValueGeneratedOnAdd() |
|
||||
.HasColumnType("tinyint(1)") |
|
||||
.HasDefaultValue(false) |
|
||||
.HasColumnName("IsDeleted"); |
|
||||
|
|
||||
b.Property<DateTime?>("LastModificationTime") |
|
||||
.HasColumnType("datetime(6)") |
|
||||
.HasColumnName("LastModificationTime"); |
|
||||
|
|
||||
b.Property<Guid?>("LastModifierId") |
|
||||
.HasColumnType("char(36)") |
|
||||
.HasColumnName("LastModifierId"); |
|
||||
|
|
||||
b.Property<Guid?>("TenantId") |
|
||||
.HasColumnType("char(36)") |
|
||||
.HasColumnName("TenantId"); |
|
||||
|
|
||||
b.HasKey("Id"); |
|
||||
|
|
||||
b.ToTable("DataDictionary"); |
|
||||
}); |
|
||||
|
|
||||
modelBuilder.Entity("CompanyName.ProjectName.DataDictionaryManagement.DataDictionaries.Aggregates.DataDictionaryDetail", b => |
|
||||
{ |
|
||||
b.Property<Guid>("Id") |
|
||||
.ValueGeneratedOnAdd() |
|
||||
.HasColumnType("char(36)"); |
|
||||
|
|
||||
b.Property<string>("Code") |
|
||||
.HasColumnType("longtext CHARACTER SET utf8mb4"); |
|
||||
|
|
||||
b.Property<DateTime>("CreationTime") |
|
||||
.HasColumnType("datetime(6)") |
|
||||
.HasColumnName("CreationTime"); |
|
||||
|
|
||||
b.Property<Guid?>("CreatorId") |
|
||||
.HasColumnType("char(36)") |
|
||||
.HasColumnName("CreatorId"); |
|
||||
|
|
||||
b.Property<Guid>("DataDictionaryId") |
|
||||
.HasColumnType("char(36)"); |
|
||||
|
|
||||
b.Property<string>("Description") |
|
||||
.HasColumnType("longtext CHARACTER SET utf8mb4"); |
|
||||
|
|
||||
b.Property<string>("DisplayText") |
|
||||
.HasColumnType("longtext CHARACTER SET utf8mb4"); |
|
||||
|
|
||||
b.Property<bool>("IsEnabled") |
|
||||
.HasColumnType("tinyint(1)"); |
|
||||
|
|
||||
b.Property<DateTime?>("LastModificationTime") |
|
||||
.HasColumnType("datetime(6)") |
|
||||
.HasColumnName("LastModificationTime"); |
|
||||
|
|
||||
b.Property<Guid?>("LastModifierId") |
|
||||
.HasColumnType("char(36)") |
|
||||
.HasColumnName("LastModifierId"); |
|
||||
|
|
||||
b.Property<int>("Order") |
|
||||
.HasColumnType("int"); |
|
||||
|
|
||||
b.HasKey("Id"); |
|
||||
|
|
||||
b.HasIndex("DataDictionaryId"); |
|
||||
|
|
||||
b.ToTable("DataDictionaryDetail"); |
|
||||
}); |
|
||||
|
|
||||
modelBuilder.Entity("CompanyName.ProjectName.DataDictionaryManagement.DataDictionaries.Aggregates.DataDictionaryDetail", b => |
|
||||
{ |
|
||||
b.HasOne("CompanyName.ProjectName.DataDictionaryManagement.DataDictionaries.Aggregates.DataDictionary", null) |
|
||||
.WithMany("Details") |
|
||||
.HasForeignKey("DataDictionaryId") |
|
||||
.OnDelete(DeleteBehavior.Cascade) |
|
||||
.IsRequired(); |
|
||||
}); |
|
||||
|
|
||||
modelBuilder.Entity("CompanyName.ProjectName.DataDictionaryManagement.DataDictionaries.Aggregates.DataDictionary", b => |
|
||||
{ |
|
||||
b.Navigation("Details"); |
|
||||
}); |
|
||||
#pragma warning restore 612, 618
|
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,54 +0,0 @@ |
|||||
using System; |
|
||||
using System.IO; |
|
||||
using Microsoft.AspNetCore.Hosting; |
|
||||
using Microsoft.Extensions.Hosting; |
|
||||
using Serilog; |
|
||||
using Serilog.Events; |
|
||||
|
|
||||
namespace CompanyName.ProjectName.DataDictionaryManagement |
|
||||
{ |
|
||||
public class Program |
|
||||
{ |
|
||||
public static int Main(string[] args) |
|
||||
{ |
|
||||
Log.Logger = new LoggerConfiguration() |
|
||||
#if DEBUG
|
|
||||
.MinimumLevel.Debug() |
|
||||
#else
|
|
||||
.MinimumLevel.Information() |
|
||||
#endif
|
|
||||
.MinimumLevel.Override("Microsoft", LogEventLevel.Information) |
|
||||
.Enrich.FromLogContext() |
|
||||
.WriteTo.Async(c => c.File("Logs/logs.txt")) |
|
||||
#if DEBUG
|
|
||||
.WriteTo.Async(c => c.Console()) |
|
||||
#endif
|
|
||||
.CreateLogger(); |
|
||||
|
|
||||
try |
|
||||
{ |
|
||||
Log.Information("Starting web host."); |
|
||||
CreateHostBuilder(args).Build().Run(); |
|
||||
return 0; |
|
||||
} |
|
||||
catch (Exception ex) |
|
||||
{ |
|
||||
Log.Fatal(ex, "Host terminated unexpectedly!"); |
|
||||
return 1; |
|
||||
} |
|
||||
finally |
|
||||
{ |
|
||||
Log.CloseAndFlush(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
internal static IHostBuilder CreateHostBuilder(string[] args) => |
|
||||
Host.CreateDefaultBuilder(args) |
|
||||
.ConfigureWebHostDefaults(webBuilder => |
|
||||
{ |
|
||||
webBuilder.UseStartup<Startup>(); |
|
||||
}) |
|
||||
.UseAutofac() |
|
||||
.UseSerilog(); |
|
||||
} |
|
||||
} |
|
||||
@ -1,27 +0,0 @@ |
|||||
{ |
|
||||
"iisSettings": { |
|
||||
"windowsAuthentication": false, |
|
||||
"anonymousAuthentication": true, |
|
||||
"iisExpress": { |
|
||||
"applicationUrl": "https://localhost:44333", |
|
||||
"sslPort": 44333 |
|
||||
} |
|
||||
}, |
|
||||
"profiles": { |
|
||||
"IIS Express": { |
|
||||
"commandName": "IISExpress", |
|
||||
"launchBrowser": true, |
|
||||
"environmentVariables": { |
|
||||
"ASPNETCORE_ENVIRONMENT": "Development" |
|
||||
} |
|
||||
}, |
|
||||
"CompanyName.ProjectName.DataDictionaryManagement.HttpApi.Host": { |
|
||||
"commandName": "Project", |
|
||||
"launchBrowser": true, |
|
||||
"applicationUrl": "https://localhost:44333", |
|
||||
"environmentVariables": { |
|
||||
"ASPNETCORE_ENVIRONMENT": "Development" |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,21 +0,0 @@ |
|||||
using System; |
|
||||
using Microsoft.AspNetCore.Builder; |
|
||||
using Microsoft.AspNetCore.Hosting; |
|
||||
using Microsoft.Extensions.DependencyInjection; |
|
||||
using Microsoft.Extensions.Logging; |
|
||||
|
|
||||
namespace CompanyName.ProjectName.DataDictionaryManagement |
|
||||
{ |
|
||||
public class Startup |
|
||||
{ |
|
||||
public void ConfigureServices(IServiceCollection services) |
|
||||
{ |
|
||||
services.AddApplication<DataDictionaryManagementHttpApiHostModule>(); |
|
||||
} |
|
||||
|
|
||||
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory) |
|
||||
{ |
|
||||
app.InitializeApplication(); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,13 +0,0 @@ |
|||||
{ |
|
||||
"App": { |
|
||||
"CorsOrigins": "https://*.DataDictionaryManagement.com,http://localhost:4200,http://localhost:44307,https://localhost:44307" |
|
||||
}, |
|
||||
"ConnectionStrings": { |
|
||||
"Default": "Data Source=localhost;Database=CompanyNameProjectNameDB;uid=root;pwd=mypassword;charset=utf8mb4;Allow User Variables=true;AllowLoadLocalInfile=true", |
|
||||
"DataDictionaryManagement": "Data Source=localhost;Database=DataDictionaryManagement;uid=root;pwd=mypassword;charset=utf8mb4;Allow User Variables=true;AllowLoadLocalInfile=true" |
|
||||
}, |
|
||||
"Redis": { |
|
||||
"Configuration": "localhost,password=mypassword", |
|
||||
"DatabaseId": 1 |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,13 @@ |
|||||
|
using Microsoft.AspNetCore.Mvc; |
||||
|
using Volo.Abp.AspNetCore.Mvc; |
||||
|
|
||||
|
namespace Lion.AbpPro.DataDictionaryManagement.Controllers |
||||
|
{ |
||||
|
public class HomeController : AbpController |
||||
|
{ |
||||
|
public ActionResult Index() |
||||
|
{ |
||||
|
return Redirect("~/swagger"); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,232 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using Microsoft.AspNetCore.Authentication.JwtBearer; |
||||
|
using Microsoft.AspNetCore.Builder; |
||||
|
using Microsoft.AspNetCore.Cors; |
||||
|
using Microsoft.AspNetCore.DataProtection; |
||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
using Microsoft.Extensions.Hosting; |
||||
|
using Lion.AbpPro.DataDictionaryManagement.EntityFrameworkCore; |
||||
|
using StackExchange.Redis; |
||||
|
using Microsoft.OpenApi.Models; |
||||
|
using Volo.Abp; |
||||
|
using Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy; |
||||
|
using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared; |
||||
|
using Volo.Abp.AspNetCore.Serilog; |
||||
|
using Volo.Abp.AuditLogging.EntityFrameworkCore; |
||||
|
using Volo.Abp.Autofac; |
||||
|
using Volo.Abp.Caching; |
||||
|
using Volo.Abp.Caching.StackExchangeRedis; |
||||
|
using Volo.Abp.EntityFrameworkCore; |
||||
|
using Volo.Abp.EntityFrameworkCore.MySQL; |
||||
|
using Volo.Abp.Localization; |
||||
|
using Volo.Abp.Modularity; |
||||
|
using Volo.Abp.PermissionManagement.EntityFrameworkCore; |
||||
|
using Volo.Abp.SettingManagement.EntityFrameworkCore; |
||||
|
using Volo.Abp.Swashbuckle; |
||||
|
using Volo.Abp.VirtualFileSystem; |
||||
|
|
||||
|
namespace Lion.AbpPro.DataDictionaryManagement |
||||
|
{ |
||||
|
[DependsOn( |
||||
|
typeof(DataDictionaryManagementApplicationModule), |
||||
|
typeof(DataDictionaryManagementEntityFrameworkCoreModule), |
||||
|
typeof(DataDictionaryManagementHttpApiModule), |
||||
|
typeof(AbpAspNetCoreMvcUiMultiTenancyModule), |
||||
|
typeof(AbpAutofacModule), |
||||
|
typeof(AbpCachingStackExchangeRedisModule), |
||||
|
typeof(AbpEntityFrameworkCoreMySQLModule), |
||||
|
typeof(AbpAuditLoggingEntityFrameworkCoreModule), |
||||
|
typeof(AbpPermissionManagementEntityFrameworkCoreModule), |
||||
|
typeof(AbpSettingManagementEntityFrameworkCoreModule), |
||||
|
typeof(AbpAspNetCoreSerilogModule), |
||||
|
typeof(AbpSwashbuckleModule) |
||||
|
)] |
||||
|
public class DataDictionaryManagementHttpApiHostModule : AbpModule |
||||
|
{ |
||||
|
private const string DefaultCorsPolicyName = "Default"; |
||||
|
|
||||
|
public override void ConfigureServices(ServiceConfigurationContext context) |
||||
|
{ |
||||
|
|
||||
|
// Configure<AbpMultiTenancyOptions>(options =>
|
||||
|
// {
|
||||
|
// options.IsEnabled = MultiTenancyConsts.IsEnabled;
|
||||
|
// });
|
||||
|
|
||||
|
ConfigureSwaggerServices(context); |
||||
|
ConfigureCache(context); |
||||
|
ConfigureCors(context); |
||||
|
ConfigureDB(); |
||||
|
ConfigureLocalization(); |
||||
|
ConfigureVirtualFileSystem(context); |
||||
|
} |
||||
|
|
||||
|
public override void OnApplicationInitialization(ApplicationInitializationContext context) |
||||
|
{ |
||||
|
var app = context.GetApplicationBuilder(); |
||||
|
var env = context.GetEnvironment(); |
||||
|
|
||||
|
if (env.IsDevelopment()) |
||||
|
{ |
||||
|
app.UseDeveloperExceptionPage(); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
app.UseErrorPage(); |
||||
|
app.UseHsts(); |
||||
|
} |
||||
|
|
||||
|
app.UseHttpsRedirection(); |
||||
|
app.UseCorrelationId(); |
||||
|
app.UseStaticFiles(); |
||||
|
app.UseRouting(); |
||||
|
app.UseCors(DefaultCorsPolicyName); |
||||
|
app.UseAuthentication(); |
||||
|
// if (MultiTenancyConsts.IsEnabled)
|
||||
|
// {
|
||||
|
// app.UseMultiTenancy();
|
||||
|
// }
|
||||
|
app.UseAbpRequestLocalization(); |
||||
|
app.UseAuthorization(); |
||||
|
app.UseSwagger(); |
||||
|
app.UseAbpSwaggerUI(options => |
||||
|
{ |
||||
|
options.SwaggerEndpoint("/swagger/v1/swagger.json", "Support APP API"); |
||||
|
|
||||
|
var configuration = context.GetConfiguration(); |
||||
|
options.OAuthClientId(configuration["AuthServer:SwaggerClientId"]); |
||||
|
options.OAuthClientSecret(configuration["AuthServer:SwaggerClientSecret"]); |
||||
|
options.OAuthScopes("DataDictionaryManagement"); |
||||
|
}); |
||||
|
app.UseAuditing(); |
||||
|
app.UseAbpSerilogEnrichers(); |
||||
|
app.UseConfiguredEndpoints(); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 配置跨域
|
||||
|
/// </summary>
|
||||
|
/// <param name="context"></param>
|
||||
|
private void ConfigureCors(ServiceConfigurationContext context) |
||||
|
{ |
||||
|
var configuration = context.Services.GetConfiguration(); |
||||
|
context.Services.AddCors(options => |
||||
|
{ |
||||
|
options.AddPolicy(DefaultCorsPolicyName, builder => |
||||
|
{ |
||||
|
builder |
||||
|
.WithOrigins( |
||||
|
configuration["App:CorsOrigins"] |
||||
|
.Split(",", StringSplitOptions.RemoveEmptyEntries) |
||||
|
.Select(o => o.RemovePostFix("/")) |
||||
|
.ToArray() |
||||
|
) |
||||
|
.WithAbpExposedHeaders() |
||||
|
.SetIsOriginAllowedToAllowWildcardSubdomains() |
||||
|
.AllowAnyHeader() |
||||
|
.AllowAnyMethod() |
||||
|
.AllowCredentials(); |
||||
|
}); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 配置SwaggerUI
|
||||
|
/// </summary>
|
||||
|
/// <param name="context"></param>
|
||||
|
private static void ConfigureSwaggerServices(ServiceConfigurationContext context) |
||||
|
{ |
||||
|
context.Services.AddSwaggerGen( |
||||
|
options => |
||||
|
{ |
||||
|
options.SwaggerDoc("v1", new OpenApiInfo {Title = "DataDictionaryManagement API", Version = "v1"}); |
||||
|
|
||||
|
options.DocInclusionPredicate((docName, description) => true); |
||||
|
|
||||
|
#region 添加token
|
||||
|
|
||||
|
options.AddSecurityDefinition(JwtBearerDefaults.AuthenticationScheme, new OpenApiSecurityScheme() |
||||
|
{ |
||||
|
Description = "请输入Token", |
||||
|
Name = "Authorization", |
||||
|
In = ParameterLocation.Header, |
||||
|
Type = SecuritySchemeType.Http, |
||||
|
Scheme = JwtBearerDefaults.AuthenticationScheme, |
||||
|
BearerFormat = "JWT" |
||||
|
}); |
||||
|
options.AddSecurityRequirement(new OpenApiSecurityRequirement |
||||
|
{ |
||||
|
{ |
||||
|
new OpenApiSecurityScheme |
||||
|
{ |
||||
|
Reference = new OpenApiReference |
||||
|
{ |
||||
|
Type = ReferenceType.SecurityScheme, Id = "Bearer" |
||||
|
} |
||||
|
}, |
||||
|
new List<string>() |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
#endregion
|
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Redis缓存
|
||||
|
/// </summary>
|
||||
|
/// <param name="context"></param>
|
||||
|
private void ConfigureCache(ServiceConfigurationContext context) |
||||
|
{ |
||||
|
var hostingEnvironment = context.Services.GetHostingEnvironment(); |
||||
|
var configuration = context.Services.GetConfiguration(); |
||||
|
Configure<AbpDistributedCacheOptions>(options => { options.KeyPrefix = "DataDictionaryManagement:"; }); |
||||
|
|
||||
|
if (!hostingEnvironment.IsDevelopment()) |
||||
|
{ |
||||
|
var redis = ConnectionMultiplexer.Connect(configuration["Redis:Configuration"]); |
||||
|
context.Services |
||||
|
.AddDataProtection() |
||||
|
.PersistKeysToStackExchangeRedis(redis, "DataDictionaryManagement-Protection-Keys"); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private void ConfigureDB() |
||||
|
{ |
||||
|
Configure<AbpDbContextOptions>(options => { options.UseMySQL(); }); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
///配置本地化
|
||||
|
/// </summary>
|
||||
|
private void ConfigureLocalization() |
||||
|
{ |
||||
|
Configure<AbpLocalizationOptions>(options => |
||||
|
{ |
||||
|
options.Languages.Add(new LanguageInfo("cs", "cs", "Čeština")); |
||||
|
options.Languages.Add(new LanguageInfo("en", "en", "English")); |
||||
|
options.Languages.Add(new LanguageInfo("en-GB", "en-GB", "English (UK)")); |
||||
|
options.Languages.Add(new LanguageInfo("fr", "fr", "Français")); |
||||
|
options.Languages.Add(new LanguageInfo("hu", "hu", "Magyar")); |
||||
|
options.Languages.Add(new LanguageInfo("pt-BR", "pt-BR", "Português")); |
||||
|
options.Languages.Add(new LanguageInfo("ru", "ru", "Русский")); |
||||
|
options.Languages.Add(new LanguageInfo("tr", "tr", "Türkçe")); |
||||
|
options.Languages.Add(new LanguageInfo("zh-Hans", "zh-Hans", "简体中文")); |
||||
|
options.Languages.Add(new LanguageInfo("zh-Hant", "zh-Hant", "繁體中文")); |
||||
|
}); |
||||
|
} |
||||
|
/// <summary>
|
||||
|
/// 配置虚拟文件系统
|
||||
|
/// </summary>
|
||||
|
/// <param name="context"></param>
|
||||
|
private void ConfigureVirtualFileSystem(ServiceConfigurationContext context) |
||||
|
{ |
||||
|
Configure<AbpVirtualFileSystemOptions>(options => |
||||
|
{ |
||||
|
options.FileSets.AddEmbedded<DataDictionaryManagementHttpApiHostModule>(); |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,18 @@ |
|||||
|
FROM mcr.microsoft.com/dotnet/core/aspnet:3.0-buster-slim AS base |
||||
|
WORKDIR /app |
||||
|
EXPOSE 80 |
||||
|
|
||||
|
FROM mcr.microsoft.com/dotnet/core/sdk:3.0-buster AS build |
||||
|
WORKDIR /src |
||||
|
COPY . . |
||||
|
WORKDIR /src/templates/service/host/Lion.AbpPro.DataDictionaryManagement.HttpApi.Host |
||||
|
RUN dotnet restore -nowarn:msb3202,nu1503 |
||||
|
RUN dotnet build --no-restore -c Release -o /app |
||||
|
|
||||
|
FROM build AS publish |
||||
|
RUN dotnet publish --no-restore -c Release -o /app |
||||
|
|
||||
|
FROM base AS final |
||||
|
WORKDIR /app |
||||
|
COPY --from=publish /app . |
||||
|
ENTRYPOINT ["dotnet", "Lion.AbpPro.DataDictionaryManagement.HttpApi.Host.dll"] |
||||
@ -0,0 +1,21 @@ |
|||||
|
using Microsoft.EntityFrameworkCore; |
||||
|
using Volo.Abp.EntityFrameworkCore; |
||||
|
|
||||
|
namespace Lion.AbpPro.DataDictionaryManagement.EntityFrameworkCore |
||||
|
{ |
||||
|
public class DataDictionaryManagementHttpApiHostMigrationsDbContext : AbpDbContext<DataDictionaryManagementHttpApiHostMigrationsDbContext> |
||||
|
{ |
||||
|
public DataDictionaryManagementHttpApiHostMigrationsDbContext(DbContextOptions<DataDictionaryManagementHttpApiHostMigrationsDbContext> options) |
||||
|
: base(options) |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
protected override void OnModelCreating(ModelBuilder modelBuilder) |
||||
|
{ |
||||
|
base.OnModelCreating(modelBuilder); |
||||
|
|
||||
|
modelBuilder.ConfigureDataDictionaryManagement(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,28 @@ |
|||||
|
using System.IO; |
||||
|
using Microsoft.EntityFrameworkCore; |
||||
|
using Microsoft.EntityFrameworkCore.Design; |
||||
|
using Microsoft.Extensions.Configuration; |
||||
|
|
||||
|
namespace Lion.AbpPro.DataDictionaryManagement.EntityFrameworkCore |
||||
|
{ |
||||
|
public class DataDictionaryManagementHttpApiHostMigrationsDbContextFactory : IDesignTimeDbContextFactory<DataDictionaryManagementHttpApiHostMigrationsDbContext> |
||||
|
{ |
||||
|
public DataDictionaryManagementHttpApiHostMigrationsDbContext CreateDbContext(string[] args) |
||||
|
{ |
||||
|
var configuration = BuildConfiguration(); |
||||
|
|
||||
|
var builder = new DbContextOptionsBuilder<DataDictionaryManagementHttpApiHostMigrationsDbContext>() |
||||
|
.UseMySql(configuration.GetConnectionString("DataDictionaryManagement"), MySqlServerVersion.LatestSupportedServerVersion); |
||||
|
return new DataDictionaryManagementHttpApiHostMigrationsDbContext(builder.Options); |
||||
|
} |
||||
|
|
||||
|
private static IConfigurationRoot BuildConfiguration() |
||||
|
{ |
||||
|
var builder = new ConfigurationBuilder() |
||||
|
.SetBasePath(Directory.GetCurrentDirectory()) |
||||
|
.AddJsonFile("appsettings.json", optional: false); |
||||
|
|
||||
|
return builder.Build(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,41 @@ |
|||||
|
<Project Sdk="Microsoft.NET.Sdk.Web"> |
||||
|
|
||||
|
<Import Project="../../../../common.props" /> |
||||
|
|
||||
|
<PropertyGroup> |
||||
|
<TargetFramework>net6.0</TargetFramework> |
||||
|
<RootNamespace>Lion.AbpPro.DataDictionaryManagement</RootNamespace> |
||||
|
<PreserveCompilationReferences>true</PreserveCompilationReferences> |
||||
|
<UserSecretsId>Lion.AbpPro.DataDictionaryManagement-c2d31439-b723-48e2-b061-5ebd7aeb6010</UserSecretsId> |
||||
|
</PropertyGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<PackageReference Include="Serilog.AspNetCore" Version="$(SerilogAspNetCoreVersion)" /> |
||||
|
<PackageReference Include="Serilog.Sinks.Async" Version="$(SerilogSinksAsyncVersion)" /> |
||||
|
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="$(MicrosoftVersion)" /> |
||||
|
<PackageReference Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" Version="$(MicrosoftVersion)" /> |
||||
|
<PackageReference Include="Volo.Abp.Autofac" Version="$(AbpPackageVersion)" /> |
||||
|
<PackageReference Include="Volo.Abp.Caching.StackExchangeRedis" Version="$(AbpPackageVersion)" /> |
||||
|
<PackageReference Include="Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy" Version="$(AbpPackageVersion)" /> |
||||
|
<PackageReference Include="Volo.Abp.EntityFrameworkCore.MySQL" Version="$(AbpPackageVersion)" /> |
||||
|
<PackageReference Include="Volo.Abp.AspNetCore.Serilog" Version="$(AbpPackageVersion)" /> |
||||
|
<PackageReference Include="Volo.Abp.Swashbuckle" Version="$(AbpPackageVersion)" /> |
||||
|
<PackageReference Include="Volo.Abp.PermissionManagement.EntityFrameworkCore" Version="$(AbpPackageVersion)" /> |
||||
|
<PackageReference Include="Volo.Abp.SettingManagement.EntityFrameworkCore" Version="$(AbpPackageVersion)" /> |
||||
|
<PackageReference Include="Volo.Abp.AuditLogging.EntityFrameworkCore" Version="$(AbpPackageVersion)" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<ProjectReference Include="..\..\src\Lion.AbpPro.DataDictionaryManagement.HttpApi\Lion.AbpPro.DataDictionaryManagement.HttpApi.csproj" /> |
||||
|
<ProjectReference Include="..\..\src\Lion.AbpPro.DataDictionaryManagement.Application\Lion.AbpPro.DataDictionaryManagement.Application.csproj" /> |
||||
|
<ProjectReference Include="..\..\src\Lion.AbpPro.DataDictionaryManagement.EntityFrameworkCore\Lion.AbpPro.DataDictionaryManagement.EntityFrameworkCore.csproj" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<Compile Remove="Logs\**" /> |
||||
|
<Content Remove="Logs\**" /> |
||||
|
<EmbeddedResource Remove="Logs\**" /> |
||||
|
<None Remove="Logs\**" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
</Project> |
||||
@ -0,0 +1,153 @@ |
|||||
|
// <auto-generated />
|
||||
|
using System; |
||||
|
using Lion.AbpPro.DataDictionaryManagement.EntityFrameworkCore; |
||||
|
using Microsoft.EntityFrameworkCore; |
||||
|
using Microsoft.EntityFrameworkCore.Infrastructure; |
||||
|
using Microsoft.EntityFrameworkCore.Migrations; |
||||
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion; |
||||
|
using Volo.Abp.EntityFrameworkCore; |
||||
|
|
||||
|
namespace Lion.AbpPro.DataDictionaryManagement.Migrations |
||||
|
{ |
||||
|
[DbContext(typeof(DataDictionaryManagementHttpApiHostMigrationsDbContext))] |
||||
|
[Migration("20210812130334_Init")] |
||||
|
partial class Init |
||||
|
{ |
||||
|
protected override void BuildTargetModel(ModelBuilder modelBuilder) |
||||
|
{ |
||||
|
#pragma warning disable 612, 618
|
||||
|
modelBuilder |
||||
|
.HasAnnotation("_Abp_DatabaseProvider", EfCoreDatabaseProvider.MySql) |
||||
|
.HasAnnotation("Relational:MaxIdentifierLength", 64) |
||||
|
.HasAnnotation("ProductVersion", "5.0.7"); |
||||
|
|
||||
|
modelBuilder.Entity("Lion.AbpPro.DataDictionaryManagement.DataDictionaries.Aggregates.DataDictionary", b => |
||||
|
{ |
||||
|
b.Property<Guid>("Id") |
||||
|
.ValueGeneratedOnAdd() |
||||
|
.HasColumnType("char(36)"); |
||||
|
|
||||
|
b.Property<string>("Code") |
||||
|
.IsRequired() |
||||
|
.HasMaxLength(64) |
||||
|
.HasColumnType("varchar(64) CHARACTER SET utf8mb4"); |
||||
|
|
||||
|
b.Property<string>("ConcurrencyStamp") |
||||
|
.IsConcurrencyToken() |
||||
|
.HasMaxLength(40) |
||||
|
.HasColumnType("varchar(40) CHARACTER SET utf8mb4") |
||||
|
.HasColumnName("ConcurrencyStamp"); |
||||
|
|
||||
|
b.Property<DateTime>("CreationTime") |
||||
|
.HasColumnType("datetime(6)") |
||||
|
.HasColumnName("CreationTime"); |
||||
|
|
||||
|
b.Property<Guid?>("CreatorId") |
||||
|
.HasColumnType("char(36)") |
||||
|
.HasColumnName("CreatorId"); |
||||
|
|
||||
|
b.Property<Guid?>("DeleterId") |
||||
|
.HasColumnType("char(36)") |
||||
|
.HasColumnName("DeleterId"); |
||||
|
|
||||
|
b.Property<DateTime?>("DeletionTime") |
||||
|
.HasColumnType("datetime(6)") |
||||
|
.HasColumnName("DeletionTime"); |
||||
|
|
||||
|
b.Property<string>("Description") |
||||
|
.IsRequired() |
||||
|
.HasMaxLength(1024) |
||||
|
.HasColumnType("varchar(1024) CHARACTER SET utf8mb4"); |
||||
|
|
||||
|
b.Property<string>("DisplayText") |
||||
|
.IsRequired() |
||||
|
.HasMaxLength(64) |
||||
|
.HasColumnType("varchar(64) CHARACTER SET utf8mb4"); |
||||
|
|
||||
|
b.Property<string>("ExtraProperties") |
||||
|
.HasColumnType("longtext CHARACTER SET utf8mb4") |
||||
|
.HasColumnName("ExtraProperties"); |
||||
|
|
||||
|
b.Property<bool>("IsDeleted") |
||||
|
.ValueGeneratedOnAdd() |
||||
|
.HasColumnType("tinyint(1)") |
||||
|
.HasDefaultValue(false) |
||||
|
.HasColumnName("IsDeleted"); |
||||
|
|
||||
|
b.Property<DateTime?>("LastModificationTime") |
||||
|
.HasColumnType("datetime(6)") |
||||
|
.HasColumnName("LastModificationTime"); |
||||
|
|
||||
|
b.Property<Guid?>("LastModifierId") |
||||
|
.HasColumnType("char(36)") |
||||
|
.HasColumnName("LastModifierId"); |
||||
|
|
||||
|
b.HasKey("Id"); |
||||
|
|
||||
|
b.ToTable("DataDictionary"); |
||||
|
}); |
||||
|
|
||||
|
modelBuilder.Entity("Lion.AbpPro.DataDictionaryManagement.DataDictionaries.Aggregates.DataDictionaryDetail", b => |
||||
|
{ |
||||
|
b.Property<Guid>("Id") |
||||
|
.ValueGeneratedOnAdd() |
||||
|
.HasColumnType("char(36)"); |
||||
|
|
||||
|
b.Property<string>("Code") |
||||
|
.HasColumnType("longtext CHARACTER SET utf8mb4"); |
||||
|
|
||||
|
b.Property<DateTime>("CreationTime") |
||||
|
.HasColumnType("datetime(6)") |
||||
|
.HasColumnName("CreationTime"); |
||||
|
|
||||
|
b.Property<Guid?>("CreatorId") |
||||
|
.HasColumnType("char(36)") |
||||
|
.HasColumnName("CreatorId"); |
||||
|
|
||||
|
b.Property<Guid>("DataDictionaryId") |
||||
|
.HasColumnType("char(36)"); |
||||
|
|
||||
|
b.Property<string>("Description") |
||||
|
.HasColumnType("longtext CHARACTER SET utf8mb4"); |
||||
|
|
||||
|
b.Property<string>("DisplayText") |
||||
|
.HasColumnType("longtext CHARACTER SET utf8mb4"); |
||||
|
|
||||
|
b.Property<bool>("IsEnabled") |
||||
|
.HasColumnType("tinyint(1)"); |
||||
|
|
||||
|
b.Property<DateTime?>("LastModificationTime") |
||||
|
.HasColumnType("datetime(6)") |
||||
|
.HasColumnName("LastModificationTime"); |
||||
|
|
||||
|
b.Property<Guid?>("LastModifierId") |
||||
|
.HasColumnType("char(36)") |
||||
|
.HasColumnName("LastModifierId"); |
||||
|
|
||||
|
b.Property<int>("Order") |
||||
|
.HasColumnType("int"); |
||||
|
|
||||
|
b.HasKey("Id"); |
||||
|
|
||||
|
b.HasIndex("DataDictionaryId"); |
||||
|
|
||||
|
b.ToTable("DataDictionaryDetail"); |
||||
|
}); |
||||
|
|
||||
|
modelBuilder.Entity("Lion.AbpPro.DataDictionaryManagement.DataDictionaries.Aggregates.DataDictionaryDetail", b => |
||||
|
{ |
||||
|
b.HasOne("Lion.AbpPro.DataDictionaryManagement.DataDictionaries.Aggregates.DataDictionary", null) |
||||
|
.WithMany("Details") |
||||
|
.HasForeignKey("DataDictionaryId") |
||||
|
.OnDelete(DeleteBehavior.Cascade) |
||||
|
.IsRequired(); |
||||
|
}); |
||||
|
|
||||
|
modelBuilder.Entity("Lion.AbpPro.DataDictionaryManagement.DataDictionaries.Aggregates.DataDictionary", b => |
||||
|
{ |
||||
|
b.Navigation("Details"); |
||||
|
}); |
||||
|
#pragma warning restore 612, 618
|
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,75 @@ |
|||||
|
using System; |
||||
|
using Microsoft.EntityFrameworkCore.Migrations; |
||||
|
|
||||
|
namespace Lion.AbpPro.DataDictionaryManagement.Migrations |
||||
|
{ |
||||
|
public partial class Init : Migration |
||||
|
{ |
||||
|
protected override void Up(MigrationBuilder migrationBuilder) |
||||
|
{ |
||||
|
migrationBuilder.CreateTable( |
||||
|
name: "DataDictionary", |
||||
|
columns: table => new |
||||
|
{ |
||||
|
Id = table.Column<Guid>(type: "char(36)", nullable: false), |
||||
|
Code = table.Column<string>(type: "varchar(64) CHARACTER SET utf8mb4", maxLength: 64, nullable: false), |
||||
|
DisplayText = table.Column<string>(type: "varchar(64) CHARACTER SET utf8mb4", maxLength: 64, nullable: false), |
||||
|
Description = table.Column<string>(type: "varchar(1024) CHARACTER SET utf8mb4", maxLength: 1024, nullable: false), |
||||
|
ExtraProperties = table.Column<string>(type: "longtext CHARACTER SET utf8mb4", nullable: true), |
||||
|
ConcurrencyStamp = table.Column<string>(type: "varchar(40) CHARACTER SET utf8mb4", maxLength: 40, nullable: true), |
||||
|
CreationTime = table.Column<DateTime>(type: "datetime(6)", nullable: false), |
||||
|
CreatorId = table.Column<Guid>(type: "char(36)", nullable: true), |
||||
|
LastModificationTime = table.Column<DateTime>(type: "datetime(6)", nullable: true), |
||||
|
LastModifierId = table.Column<Guid>(type: "char(36)", nullable: true), |
||||
|
IsDeleted = table.Column<bool>(type: "tinyint(1)", nullable: false, defaultValue: false), |
||||
|
DeleterId = table.Column<Guid>(type: "char(36)", nullable: true), |
||||
|
DeletionTime = table.Column<DateTime>(type: "datetime(6)", nullable: true) |
||||
|
}, |
||||
|
constraints: table => |
||||
|
{ |
||||
|
table.PrimaryKey("PK_DataDictionary", x => x.Id); |
||||
|
}); |
||||
|
|
||||
|
migrationBuilder.CreateTable( |
||||
|
name: "DataDictionaryDetail", |
||||
|
columns: table => new |
||||
|
{ |
||||
|
Id = table.Column<Guid>(type: "char(36)", nullable: false), |
||||
|
DataDictionaryId = table.Column<Guid>(type: "char(36)", nullable: false), |
||||
|
Code = table.Column<string>(type: "longtext CHARACTER SET utf8mb4", nullable: true), |
||||
|
Order = table.Column<int>(type: "int", nullable: false), |
||||
|
DisplayText = table.Column<string>(type: "longtext CHARACTER SET utf8mb4", nullable: true), |
||||
|
Description = table.Column<string>(type: "longtext CHARACTER SET utf8mb4", nullable: true), |
||||
|
IsEnabled = table.Column<bool>(type: "tinyint(1)", nullable: false), |
||||
|
CreationTime = table.Column<DateTime>(type: "datetime(6)", nullable: false), |
||||
|
CreatorId = table.Column<Guid>(type: "char(36)", nullable: true), |
||||
|
LastModificationTime = table.Column<DateTime>(type: "datetime(6)", nullable: true), |
||||
|
LastModifierId = table.Column<Guid>(type: "char(36)", nullable: true) |
||||
|
}, |
||||
|
constraints: table => |
||||
|
{ |
||||
|
table.PrimaryKey("PK_DataDictionaryDetail", x => x.Id); |
||||
|
table.ForeignKey( |
||||
|
name: "FK_DataDictionaryDetail_DataDictionary_DataDictionaryId", |
||||
|
column: x => x.DataDictionaryId, |
||||
|
principalTable: "DataDictionary", |
||||
|
principalColumn: "Id", |
||||
|
onDelete: ReferentialAction.Cascade); |
||||
|
}); |
||||
|
|
||||
|
migrationBuilder.CreateIndex( |
||||
|
name: "IX_DataDictionaryDetail_DataDictionaryId", |
||||
|
table: "DataDictionaryDetail", |
||||
|
column: "DataDictionaryId"); |
||||
|
} |
||||
|
|
||||
|
protected override void Down(MigrationBuilder migrationBuilder) |
||||
|
{ |
||||
|
migrationBuilder.DropTable( |
||||
|
name: "DataDictionaryDetail"); |
||||
|
|
||||
|
migrationBuilder.DropTable( |
||||
|
name: "DataDictionary"); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue