From 35c1d810c4e4dc4b9aef2db5baf23bf474181f7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mehmet=20Tu=CC=88ken?= Date: Wed, 18 Dec 2019 02:22:08 +0300 Subject: [PATCH 001/334] [framework] fix mongo.exe dispose --- .../Volo/Abp/MongoDB/AbpMongoDbTestModule.cs | 7 ++---- .../Abp/MongoDB/Auditing/Auditing_Tests.cs | 2 ++ .../MultiTenant_Creation_Tests.cs | 2 ++ .../DataFiltering/MultiTenant_Filter_Tests.cs | 2 ++ .../DataFiltering/SoftDelete_Filter_Tests.cs | 2 ++ .../MongoDB/DataFiltering/SoftDelete_Tests.cs | 2 ++ .../MongoDB/Domain/ConcurrencyStamp_Tests.cs | 2 ++ .../MongoDB/Domain/ExtraProperties_Tests.cs | 2 ++ .../DomainEvents/DomainEvents_Tests.cs | 2 ++ .../DomainEvents/EntityChangeEvents_Tests.cs | 2 ++ .../Volo/Abp/MongoDB/MongoDbFixture.cs | 25 +++++++++++++++++++ .../Volo/Abp/MongoDB/MongoTestCollection.cs | 10 ++++++++ .../Repositories/Repository_Basic_Tests.cs | 1 + .../Repository_Basic_Tests_With_Int_Pk.cs | 1 + .../Repository_Queryable_Tests.cs | 2 ++ .../Repository_Specifications_Tests.cs | 2 ++ .../Abp/MongoDB/Uow/Uow_Completed_Tests.cs | 3 ++- 17 files changed, 63 insertions(+), 6 deletions(-) create mode 100644 framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/MongoDbFixture.cs create mode 100644 framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/MongoTestCollection.cs diff --git a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/AbpMongoDbTestModule.cs b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/AbpMongoDbTestModule.cs index 86620366b3..112ecaf34d 100644 --- a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/AbpMongoDbTestModule.cs +++ b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/AbpMongoDbTestModule.cs @@ -1,6 +1,5 @@ using System; using Microsoft.Extensions.DependencyInjection; -using Mongo2Go; using Volo.Abp.Data; using Volo.Abp.Modularity; using Volo.Abp.TestApp; @@ -15,13 +14,11 @@ namespace Volo.Abp.MongoDB )] public class AbpMongoDbTestModule : AbpModule { - private static readonly MongoDbRunner MongoDbRunner = MongoDbRunner.Start(); - public override void ConfigureServices(ServiceConfigurationContext context) { - var connectionString = MongoDbRunner.ConnectionString.EnsureEndsWith('/') + + var connectionString = MongoDbFixture.GetConnectionString().EnsureEndsWith('/') + "Db_" + - Guid.NewGuid().ToString("N"); + Guid.NewGuid().ToString("N"); Configure(options => { diff --git a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Auditing/Auditing_Tests.cs b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Auditing/Auditing_Tests.cs index c5d7b87752..e20cceaf0e 100644 --- a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Auditing/Auditing_Tests.cs +++ b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Auditing/Auditing_Tests.cs @@ -1,7 +1,9 @@ using Volo.Abp.TestApp.Testing; +using Xunit; namespace Volo.Abp.MongoDB.Auditing { + [Collection("MongoDB Collection")] public class Auditing_Tests : Auditing_Tests { diff --git a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/DataFiltering/MultiTenant_Creation_Tests.cs b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/DataFiltering/MultiTenant_Creation_Tests.cs index a1ee94a943..3e4e532f5a 100644 --- a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/DataFiltering/MultiTenant_Creation_Tests.cs +++ b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/DataFiltering/MultiTenant_Creation_Tests.cs @@ -1,7 +1,9 @@ using Volo.Abp.TestApp.Testing; +using Xunit; namespace Volo.Abp.MongoDB.DataFiltering { + [Collection("MongoDB Collection")] public class MultiTenant_Creation_Tests : MultiTenant_Creation_Tests { diff --git a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/DataFiltering/MultiTenant_Filter_Tests.cs b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/DataFiltering/MultiTenant_Filter_Tests.cs index c23761a05c..c4ace6f1fe 100644 --- a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/DataFiltering/MultiTenant_Filter_Tests.cs +++ b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/DataFiltering/MultiTenant_Filter_Tests.cs @@ -1,7 +1,9 @@ using Volo.Abp.TestApp.Testing; +using Xunit; namespace Volo.Abp.MongoDB.DataFiltering { + [Collection("MongoDB Collection")] public class MultiTenant_Filter_Tests : MultiTenant_Filter_Tests { diff --git a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/DataFiltering/SoftDelete_Filter_Tests.cs b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/DataFiltering/SoftDelete_Filter_Tests.cs index 3636b998bb..6a6167133b 100644 --- a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/DataFiltering/SoftDelete_Filter_Tests.cs +++ b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/DataFiltering/SoftDelete_Filter_Tests.cs @@ -1,7 +1,9 @@ using Volo.Abp.TestApp.Testing; +using Xunit; namespace Volo.Abp.MongoDB.DataFiltering { + [Collection("MongoDB Collection")] public class SoftDelete_Filter_Tests : SoftDelete_Filter_Tests { diff --git a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/DataFiltering/SoftDelete_Tests.cs b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/DataFiltering/SoftDelete_Tests.cs index fdd8ec1a5e..f3d9d75c9e 100644 --- a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/DataFiltering/SoftDelete_Tests.cs +++ b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/DataFiltering/SoftDelete_Tests.cs @@ -1,7 +1,9 @@ using Volo.Abp.TestApp.Testing; +using Xunit; namespace Volo.Abp.MongoDB.DataFiltering { + [Collection("MongoDB Collection")] public class SoftDelete_Tests : SoftDelete_Tests { diff --git a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Domain/ConcurrencyStamp_Tests.cs b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Domain/ConcurrencyStamp_Tests.cs index 117cd5dde1..4882e43c13 100644 --- a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Domain/ConcurrencyStamp_Tests.cs +++ b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Domain/ConcurrencyStamp_Tests.cs @@ -1,7 +1,9 @@ using Volo.Abp.TestApp.Testing; +using Xunit; namespace Volo.Abp.MongoDB.Domain { + [Collection("MongoDB Collection")] public class ConcurrencyStamp_Tests : ConcurrencyStamp_Tests { diff --git a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Domain/ExtraProperties_Tests.cs b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Domain/ExtraProperties_Tests.cs index b389ad61b9..9a4675e24f 100644 --- a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Domain/ExtraProperties_Tests.cs +++ b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Domain/ExtraProperties_Tests.cs @@ -1,7 +1,9 @@ using Volo.Abp.TestApp.Testing; +using Xunit; namespace Volo.Abp.MongoDB.Domain { + [Collection("MongoDB Collection")] public class ExtraProperties_Tests : ExtraProperties_Tests { diff --git a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/DomainEvents/DomainEvents_Tests.cs b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/DomainEvents/DomainEvents_Tests.cs index b01cb690f6..a9f232b989 100644 --- a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/DomainEvents/DomainEvents_Tests.cs +++ b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/DomainEvents/DomainEvents_Tests.cs @@ -1,7 +1,9 @@ using Volo.Abp.TestApp.Testing; +using Xunit; namespace Volo.Abp.MongoDB.DomainEvents { + [Collection("MongoDB Collection")] public class DomainEvents_Tests : DomainEvents_Tests { } diff --git a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/DomainEvents/EntityChangeEvents_Tests.cs b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/DomainEvents/EntityChangeEvents_Tests.cs index 0df187f34e..3f4882b524 100644 --- a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/DomainEvents/EntityChangeEvents_Tests.cs +++ b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/DomainEvents/EntityChangeEvents_Tests.cs @@ -1,7 +1,9 @@ using Volo.Abp.TestApp.Testing; +using Xunit; namespace Volo.Abp.MongoDB.DomainEvents { + [Collection("MongoDB Collection")] public class EntityChangeEvents_Tests : EntityChangeEvents_Tests { diff --git a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/MongoDbFixture.cs b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/MongoDbFixture.cs new file mode 100644 index 0000000000..0e483febab --- /dev/null +++ b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/MongoDbFixture.cs @@ -0,0 +1,25 @@ +using System; +using Mongo2Go; + +namespace Volo.Abp.MongoDB +{ + public class MongoDbFixture : IDisposable + { + public static MongoDbRunner MongoDbRunner; + + public MongoDbFixture() + { + MongoDbRunner = MongoDbRunner.Start(); + } + + public static string GetConnectionString() + { + return MongoDbRunner.ConnectionString; + } + + public void Dispose() + { + MongoDbRunner?.Dispose(); + } + } +} \ No newline at end of file diff --git a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/MongoTestCollection.cs b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/MongoTestCollection.cs new file mode 100644 index 0000000000..2d57ed24fa --- /dev/null +++ b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/MongoTestCollection.cs @@ -0,0 +1,10 @@ +using Xunit; + +namespace Volo.Abp.MongoDB +{ + [CollectionDefinition("MongoDB Collection")] + public class MongoTestCollection : ICollectionFixture + { + + } +} \ No newline at end of file diff --git a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Repositories/Repository_Basic_Tests.cs b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Repositories/Repository_Basic_Tests.cs index 72774be545..112044d22d 100644 --- a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Repositories/Repository_Basic_Tests.cs +++ b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Repositories/Repository_Basic_Tests.cs @@ -9,6 +9,7 @@ using Xunit; namespace Volo.Abp.MongoDB.Repositories { + [Collection("MongoDB Collection")] public class Repository_Basic_Tests : Repository_Basic_Tests { [Fact] diff --git a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Repositories/Repository_Basic_Tests_With_Int_Pk.cs b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Repositories/Repository_Basic_Tests_With_Int_Pk.cs index 58914e8e50..a3ae87cf58 100644 --- a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Repositories/Repository_Basic_Tests_With_Int_Pk.cs +++ b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Repositories/Repository_Basic_Tests_With_Int_Pk.cs @@ -3,6 +3,7 @@ using Xunit; namespace Volo.Abp.MongoDB.Repositories { + [Collection("MongoDB Collection")] public class Repository_Basic_Tests_With_Int_Pk : Repository_Basic_Tests_With_Int_Pk { [Fact(Skip = "Int PKs are not working for MongoDb")] diff --git a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Repositories/Repository_Queryable_Tests.cs b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Repositories/Repository_Queryable_Tests.cs index d396471bed..f75a5b4a34 100644 --- a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Repositories/Repository_Queryable_Tests.cs +++ b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Repositories/Repository_Queryable_Tests.cs @@ -1,7 +1,9 @@ using Volo.Abp.TestApp.Testing; +using Xunit; namespace Volo.Abp.MongoDB.Repositories { + [Collection("MongoDB Collection")] public class Repository_Queryable_Tests : Repository_Queryable_Tests { diff --git a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Repositories/Repository_Specifications_Tests.cs b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Repositories/Repository_Specifications_Tests.cs index 6529b4c5a9..c0a4439f09 100644 --- a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Repositories/Repository_Specifications_Tests.cs +++ b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Repositories/Repository_Specifications_Tests.cs @@ -1,7 +1,9 @@ using Volo.Abp.TestApp.Testing; +using Xunit; namespace Volo.Abp.MongoDB.Repositories { + [Collection("MongoDB Collection")] public class Repository_Specifications_Tests : Repository_Specifications_Tests { } diff --git a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Uow/Uow_Completed_Tests.cs b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Uow/Uow_Completed_Tests.cs index 4773644885..00bae8dc12 100644 --- a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Uow/Uow_Completed_Tests.cs +++ b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Uow/Uow_Completed_Tests.cs @@ -1,9 +1,10 @@ using Volo.Abp.TestApp.Testing; +using Xunit; namespace Volo.Abp.MongoDB.Uow { + [Collection("MongoDB Collection")] public class Uow_Completed_Tests : Uow_Completed_Tests { - } } \ No newline at end of file From ca57cf3ea70fa551026d8de09bb115da26e63d3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mehmet=20Tu=CC=88ken?= Date: Wed, 18 Dec 2019 02:39:10 +0300 Subject: [PATCH 002/334] refactor --- .../Volo/Abp/MongoDB/AbpMongoDbTestModule.cs | 2 +- .../Volo/Abp/MongoDB/Auditing/Auditing_Tests.cs | 2 +- .../DataFiltering/MultiTenant_Creation_Tests.cs | 2 +- .../DataFiltering/MultiTenant_Filter_Tests.cs | 2 +- .../DataFiltering/SoftDelete_Filter_Tests.cs | 2 +- .../Abp/MongoDB/DataFiltering/SoftDelete_Tests.cs | 2 +- .../Abp/MongoDB/Domain/ConcurrencyStamp_Tests.cs | 2 +- .../Abp/MongoDB/Domain/ExtraProperties_Tests.cs | 2 +- .../Abp/MongoDB/DomainEvents/DomainEvents_Tests.cs | 2 +- .../DomainEvents/EntityChangeEvents_Tests.cs | 2 +- .../Volo/Abp/MongoDB/MongoDbFixture.cs | 13 ++----------- .../Volo/Abp/MongoDB/MongoTestCollection.cs | 4 ++-- .../MongoDB/Repositories/Repository_Basic_Tests.cs | 2 +- .../Repository_Basic_Tests_With_Int_Pk.cs | 2 +- .../Repositories/Repository_Queryable_Tests.cs | 2 +- .../Repositories/Repository_Specifications_Tests.cs | 2 +- .../Volo/Abp/MongoDB/Uow/Uow_Completed_Tests.cs | 2 +- .../Volo/Abp/AuditLogging/MongoDB/MongoDbFixture.cs | 7 +++++++ .../Abp/AuditLogging/MongoDB/MongoTestCollection.cs | 7 +++++++ 19 files changed, 33 insertions(+), 28 deletions(-) create mode 100644 modules/audit-logging/test/Volo.Abp.AuditLogging.MongoDB.Tests/Volo/Abp/AuditLogging/MongoDB/MongoDbFixture.cs create mode 100644 modules/audit-logging/test/Volo.Abp.AuditLogging.MongoDB.Tests/Volo/Abp/AuditLogging/MongoDB/MongoTestCollection.cs diff --git a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/AbpMongoDbTestModule.cs b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/AbpMongoDbTestModule.cs index 112ecaf34d..cfa7b033b7 100644 --- a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/AbpMongoDbTestModule.cs +++ b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/AbpMongoDbTestModule.cs @@ -16,7 +16,7 @@ namespace Volo.Abp.MongoDB { public override void ConfigureServices(ServiceConfigurationContext context) { - var connectionString = MongoDbFixture.GetConnectionString().EnsureEndsWith('/') + + var connectionString = MongoDbFixture.ConnectionString.EnsureEndsWith('/') + "Db_" + Guid.NewGuid().ToString("N"); diff --git a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Auditing/Auditing_Tests.cs b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Auditing/Auditing_Tests.cs index e20cceaf0e..b08c2120a4 100644 --- a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Auditing/Auditing_Tests.cs +++ b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Auditing/Auditing_Tests.cs @@ -3,7 +3,7 @@ using Xunit; namespace Volo.Abp.MongoDB.Auditing { - [Collection("MongoDB Collection")] + [Collection(MongoTestCollection.Name)] public class Auditing_Tests : Auditing_Tests { diff --git a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/DataFiltering/MultiTenant_Creation_Tests.cs b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/DataFiltering/MultiTenant_Creation_Tests.cs index 3e4e532f5a..0ab365a568 100644 --- a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/DataFiltering/MultiTenant_Creation_Tests.cs +++ b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/DataFiltering/MultiTenant_Creation_Tests.cs @@ -3,7 +3,7 @@ using Xunit; namespace Volo.Abp.MongoDB.DataFiltering { - [Collection("MongoDB Collection")] + [Collection(MongoTestCollection.Name)] public class MultiTenant_Creation_Tests : MultiTenant_Creation_Tests { diff --git a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/DataFiltering/MultiTenant_Filter_Tests.cs b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/DataFiltering/MultiTenant_Filter_Tests.cs index c4ace6f1fe..c32b640e03 100644 --- a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/DataFiltering/MultiTenant_Filter_Tests.cs +++ b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/DataFiltering/MultiTenant_Filter_Tests.cs @@ -3,7 +3,7 @@ using Xunit; namespace Volo.Abp.MongoDB.DataFiltering { - [Collection("MongoDB Collection")] + [Collection(MongoTestCollection.Name)] public class MultiTenant_Filter_Tests : MultiTenant_Filter_Tests { diff --git a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/DataFiltering/SoftDelete_Filter_Tests.cs b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/DataFiltering/SoftDelete_Filter_Tests.cs index 6a6167133b..5de6caf661 100644 --- a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/DataFiltering/SoftDelete_Filter_Tests.cs +++ b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/DataFiltering/SoftDelete_Filter_Tests.cs @@ -3,7 +3,7 @@ using Xunit; namespace Volo.Abp.MongoDB.DataFiltering { - [Collection("MongoDB Collection")] + [Collection(MongoTestCollection.Name)] public class SoftDelete_Filter_Tests : SoftDelete_Filter_Tests { diff --git a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/DataFiltering/SoftDelete_Tests.cs b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/DataFiltering/SoftDelete_Tests.cs index f3d9d75c9e..bffb38f858 100644 --- a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/DataFiltering/SoftDelete_Tests.cs +++ b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/DataFiltering/SoftDelete_Tests.cs @@ -3,7 +3,7 @@ using Xunit; namespace Volo.Abp.MongoDB.DataFiltering { - [Collection("MongoDB Collection")] + [Collection(MongoTestCollection.Name)] public class SoftDelete_Tests : SoftDelete_Tests { diff --git a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Domain/ConcurrencyStamp_Tests.cs b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Domain/ConcurrencyStamp_Tests.cs index 4882e43c13..88bf889b7c 100644 --- a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Domain/ConcurrencyStamp_Tests.cs +++ b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Domain/ConcurrencyStamp_Tests.cs @@ -3,7 +3,7 @@ using Xunit; namespace Volo.Abp.MongoDB.Domain { - [Collection("MongoDB Collection")] + [Collection(MongoTestCollection.Name)] public class ConcurrencyStamp_Tests : ConcurrencyStamp_Tests { diff --git a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Domain/ExtraProperties_Tests.cs b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Domain/ExtraProperties_Tests.cs index 9a4675e24f..5f8f8784c3 100644 --- a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Domain/ExtraProperties_Tests.cs +++ b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Domain/ExtraProperties_Tests.cs @@ -3,7 +3,7 @@ using Xunit; namespace Volo.Abp.MongoDB.Domain { - [Collection("MongoDB Collection")] + [Collection(MongoTestCollection.Name)] public class ExtraProperties_Tests : ExtraProperties_Tests { diff --git a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/DomainEvents/DomainEvents_Tests.cs b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/DomainEvents/DomainEvents_Tests.cs index a9f232b989..ed480a229e 100644 --- a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/DomainEvents/DomainEvents_Tests.cs +++ b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/DomainEvents/DomainEvents_Tests.cs @@ -3,7 +3,7 @@ using Xunit; namespace Volo.Abp.MongoDB.DomainEvents { - [Collection("MongoDB Collection")] + [Collection(MongoTestCollection.Name)] public class DomainEvents_Tests : DomainEvents_Tests { } diff --git a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/DomainEvents/EntityChangeEvents_Tests.cs b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/DomainEvents/EntityChangeEvents_Tests.cs index 3f4882b524..184142d77c 100644 --- a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/DomainEvents/EntityChangeEvents_Tests.cs +++ b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/DomainEvents/EntityChangeEvents_Tests.cs @@ -3,7 +3,7 @@ using Xunit; namespace Volo.Abp.MongoDB.DomainEvents { - [Collection("MongoDB Collection")] + [Collection(MongoTestCollection.Name)] public class EntityChangeEvents_Tests : EntityChangeEvents_Tests { diff --git a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/MongoDbFixture.cs b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/MongoDbFixture.cs index 0e483febab..f401d0d6d4 100644 --- a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/MongoDbFixture.cs +++ b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/MongoDbFixture.cs @@ -5,18 +5,9 @@ namespace Volo.Abp.MongoDB { public class MongoDbFixture : IDisposable { - public static MongoDbRunner MongoDbRunner; + private static readonly MongoDbRunner MongoDbRunner = MongoDbRunner.Start(); + public static readonly string ConnectionString = MongoDbRunner.ConnectionString; - public MongoDbFixture() - { - MongoDbRunner = MongoDbRunner.Start(); - } - - public static string GetConnectionString() - { - return MongoDbRunner.ConnectionString; - } - public void Dispose() { MongoDbRunner?.Dispose(); diff --git a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/MongoTestCollection.cs b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/MongoTestCollection.cs index 2d57ed24fa..ae23dc9450 100644 --- a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/MongoTestCollection.cs +++ b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/MongoTestCollection.cs @@ -2,9 +2,9 @@ using Xunit; namespace Volo.Abp.MongoDB { - [CollectionDefinition("MongoDB Collection")] + [CollectionDefinition(Name)] public class MongoTestCollection : ICollectionFixture { - + public const string Name = "MongoDB Collection"; } } \ No newline at end of file diff --git a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Repositories/Repository_Basic_Tests.cs b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Repositories/Repository_Basic_Tests.cs index 112044d22d..64af3aa855 100644 --- a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Repositories/Repository_Basic_Tests.cs +++ b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Repositories/Repository_Basic_Tests.cs @@ -9,7 +9,7 @@ using Xunit; namespace Volo.Abp.MongoDB.Repositories { - [Collection("MongoDB Collection")] + [Collection(MongoTestCollection.Name)] public class Repository_Basic_Tests : Repository_Basic_Tests { [Fact] diff --git a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Repositories/Repository_Basic_Tests_With_Int_Pk.cs b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Repositories/Repository_Basic_Tests_With_Int_Pk.cs index a3ae87cf58..2b8be02617 100644 --- a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Repositories/Repository_Basic_Tests_With_Int_Pk.cs +++ b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Repositories/Repository_Basic_Tests_With_Int_Pk.cs @@ -3,7 +3,7 @@ using Xunit; namespace Volo.Abp.MongoDB.Repositories { - [Collection("MongoDB Collection")] + [Collection(MongoTestCollection.Name)] public class Repository_Basic_Tests_With_Int_Pk : Repository_Basic_Tests_With_Int_Pk { [Fact(Skip = "Int PKs are not working for MongoDb")] diff --git a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Repositories/Repository_Queryable_Tests.cs b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Repositories/Repository_Queryable_Tests.cs index f75a5b4a34..05ffb6ae27 100644 --- a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Repositories/Repository_Queryable_Tests.cs +++ b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Repositories/Repository_Queryable_Tests.cs @@ -3,7 +3,7 @@ using Xunit; namespace Volo.Abp.MongoDB.Repositories { - [Collection("MongoDB Collection")] + [Collection(MongoTestCollection.Name)] public class Repository_Queryable_Tests : Repository_Queryable_Tests { diff --git a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Repositories/Repository_Specifications_Tests.cs b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Repositories/Repository_Specifications_Tests.cs index c0a4439f09..4670ac5d00 100644 --- a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Repositories/Repository_Specifications_Tests.cs +++ b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Repositories/Repository_Specifications_Tests.cs @@ -3,7 +3,7 @@ using Xunit; namespace Volo.Abp.MongoDB.Repositories { - [Collection("MongoDB Collection")] + [Collection(MongoTestCollection.Name)] public class Repository_Specifications_Tests : Repository_Specifications_Tests { } diff --git a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Uow/Uow_Completed_Tests.cs b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Uow/Uow_Completed_Tests.cs index 00bae8dc12..cef724b9bd 100644 --- a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Uow/Uow_Completed_Tests.cs +++ b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Uow/Uow_Completed_Tests.cs @@ -3,7 +3,7 @@ using Xunit; namespace Volo.Abp.MongoDB.Uow { - [Collection("MongoDB Collection")] + [Collection(MongoTestCollection.Name)] public class Uow_Completed_Tests : Uow_Completed_Tests { } diff --git a/modules/audit-logging/test/Volo.Abp.AuditLogging.MongoDB.Tests/Volo/Abp/AuditLogging/MongoDB/MongoDbFixture.cs b/modules/audit-logging/test/Volo.Abp.AuditLogging.MongoDB.Tests/Volo/Abp/AuditLogging/MongoDB/MongoDbFixture.cs new file mode 100644 index 0000000000..cc2f90e01d --- /dev/null +++ b/modules/audit-logging/test/Volo.Abp.AuditLogging.MongoDB.Tests/Volo/Abp/AuditLogging/MongoDB/MongoDbFixture.cs @@ -0,0 +1,7 @@ +namespace Volo.Abp.AuditLogging.MongoDB +{ + public class MongoDbFixture + { + + } +} \ No newline at end of file diff --git a/modules/audit-logging/test/Volo.Abp.AuditLogging.MongoDB.Tests/Volo/Abp/AuditLogging/MongoDB/MongoTestCollection.cs b/modules/audit-logging/test/Volo.Abp.AuditLogging.MongoDB.Tests/Volo/Abp/AuditLogging/MongoDB/MongoTestCollection.cs new file mode 100644 index 0000000000..4ed185cb9c --- /dev/null +++ b/modules/audit-logging/test/Volo.Abp.AuditLogging.MongoDB.Tests/Volo/Abp/AuditLogging/MongoDB/MongoTestCollection.cs @@ -0,0 +1,7 @@ +namespace Volo.Abp.AuditLogging.MongoDB +{ + public class MongoTestCollection + { + + } +} \ No newline at end of file From 1645483bd0b2cce12eb53934c2728184d49e2f3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mehmet=20Tu=CC=88ken?= Date: Wed, 18 Dec 2019 02:40:06 +0300 Subject: [PATCH 003/334] [modules/auditlogging] fix mongo.exe dispose --- .../MongoDB/AbpAuditLoggingMongoDbTestModule.cs | 4 +--- .../AuditLogging/MongoDB/AuditLogRepository_Tests.cs | 2 ++ .../AuditLogging/MongoDB/AuditStore_Basic_Tests.cs | 5 ++++- .../Volo/Abp/AuditLogging/MongoDB/MongoDbFixture.cs | 11 ++++++++++- .../Abp/AuditLogging/MongoDB/MongoTestCollection.cs | 7 +++++-- 5 files changed, 22 insertions(+), 7 deletions(-) diff --git a/modules/audit-logging/test/Volo.Abp.AuditLogging.MongoDB.Tests/Volo/Abp/AuditLogging/MongoDB/AbpAuditLoggingMongoDbTestModule.cs b/modules/audit-logging/test/Volo.Abp.AuditLogging.MongoDB.Tests/Volo/Abp/AuditLogging/MongoDB/AbpAuditLoggingMongoDbTestModule.cs index 7c70d720ec..b57c204818 100644 --- a/modules/audit-logging/test/Volo.Abp.AuditLogging.MongoDB.Tests/Volo/Abp/AuditLogging/MongoDB/AbpAuditLoggingMongoDbTestModule.cs +++ b/modules/audit-logging/test/Volo.Abp.AuditLogging.MongoDB.Tests/Volo/Abp/AuditLogging/MongoDB/AbpAuditLoggingMongoDbTestModule.cs @@ -12,11 +12,9 @@ namespace Volo.Abp.AuditLogging.MongoDB )] public class AbpAuditLoggingMongoDbTestModule : AbpModule { - private static readonly MongoDbRunner MongoDbRunner = MongoDbRunner.Start(); - public override void ConfigureServices(ServiceConfigurationContext context) { - var connectionString = MongoDbRunner.ConnectionString.EnsureEndsWith('/') + + var connectionString = MongoDbFixture.ConnectionString.EnsureEndsWith('/') + "Db_" + Guid.NewGuid().ToString("N"); diff --git a/modules/audit-logging/test/Volo.Abp.AuditLogging.MongoDB.Tests/Volo/Abp/AuditLogging/MongoDB/AuditLogRepository_Tests.cs b/modules/audit-logging/test/Volo.Abp.AuditLogging.MongoDB.Tests/Volo/Abp/AuditLogging/MongoDB/AuditLogRepository_Tests.cs index ffcc2094ab..a0edd58a45 100644 --- a/modules/audit-logging/test/Volo.Abp.AuditLogging.MongoDB.Tests/Volo/Abp/AuditLogging/MongoDB/AuditLogRepository_Tests.cs +++ b/modules/audit-logging/test/Volo.Abp.AuditLogging.MongoDB.Tests/Volo/Abp/AuditLogging/MongoDB/AuditLogRepository_Tests.cs @@ -1,9 +1,11 @@ using System; using System.Collections.Generic; using System.Text; +using Xunit; namespace Volo.Abp.AuditLogging.MongoDB { + [Collection(MongoTestCollection.Name)] public class AuditLogRepository_Tests : AuditLogRepository_Tests { diff --git a/modules/audit-logging/test/Volo.Abp.AuditLogging.MongoDB.Tests/Volo/Abp/AuditLogging/MongoDB/AuditStore_Basic_Tests.cs b/modules/audit-logging/test/Volo.Abp.AuditLogging.MongoDB.Tests/Volo/Abp/AuditLogging/MongoDB/AuditStore_Basic_Tests.cs index fa7a41ecfd..ad590c61e1 100644 --- a/modules/audit-logging/test/Volo.Abp.AuditLogging.MongoDB.Tests/Volo/Abp/AuditLogging/MongoDB/AuditStore_Basic_Tests.cs +++ b/modules/audit-logging/test/Volo.Abp.AuditLogging.MongoDB.Tests/Volo/Abp/AuditLogging/MongoDB/AuditStore_Basic_Tests.cs @@ -1,5 +1,8 @@ -namespace Volo.Abp.AuditLogging.MongoDB +using Xunit; + +namespace Volo.Abp.AuditLogging.MongoDB { + [Collection(MongoTestCollection.Name)] public class AuditStore_Basic_Tests : AuditStore_Basic_Tests { diff --git a/modules/audit-logging/test/Volo.Abp.AuditLogging.MongoDB.Tests/Volo/Abp/AuditLogging/MongoDB/MongoDbFixture.cs b/modules/audit-logging/test/Volo.Abp.AuditLogging.MongoDB.Tests/Volo/Abp/AuditLogging/MongoDB/MongoDbFixture.cs index cc2f90e01d..33803c1af4 100644 --- a/modules/audit-logging/test/Volo.Abp.AuditLogging.MongoDB.Tests/Volo/Abp/AuditLogging/MongoDB/MongoDbFixture.cs +++ b/modules/audit-logging/test/Volo.Abp.AuditLogging.MongoDB.Tests/Volo/Abp/AuditLogging/MongoDB/MongoDbFixture.cs @@ -1,7 +1,16 @@ +using System; +using Mongo2Go; + namespace Volo.Abp.AuditLogging.MongoDB { - public class MongoDbFixture + public class MongoDbFixture : IDisposable { + private static readonly MongoDbRunner MongoDbRunner = MongoDbRunner.Start(); + public static readonly string ConnectionString = MongoDbRunner.ConnectionString; + public void Dispose() + { + MongoDbRunner?.Dispose(); + } } } \ No newline at end of file diff --git a/modules/audit-logging/test/Volo.Abp.AuditLogging.MongoDB.Tests/Volo/Abp/AuditLogging/MongoDB/MongoTestCollection.cs b/modules/audit-logging/test/Volo.Abp.AuditLogging.MongoDB.Tests/Volo/Abp/AuditLogging/MongoDB/MongoTestCollection.cs index 4ed185cb9c..1d89caa8b0 100644 --- a/modules/audit-logging/test/Volo.Abp.AuditLogging.MongoDB.Tests/Volo/Abp/AuditLogging/MongoDB/MongoTestCollection.cs +++ b/modules/audit-logging/test/Volo.Abp.AuditLogging.MongoDB.Tests/Volo/Abp/AuditLogging/MongoDB/MongoTestCollection.cs @@ -1,7 +1,10 @@ +using Xunit; + namespace Volo.Abp.AuditLogging.MongoDB { - public class MongoTestCollection + [CollectionDefinition(Name)] + public class MongoTestCollection : ICollectionFixture { - + public const string Name = "MongoDB Collection"; } } \ No newline at end of file From 734059d9ff727aec681fe5693be6beddbab1ef9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mehmet=20Tu=CC=88ken?= Date: Wed, 18 Dec 2019 02:46:26 +0300 Subject: [PATCH 004/334] [modules/backgroundjobs] fix mongo.exe dispose --- .../AbpBackgroundJobsMongoDbTestModule.cs | 6 +----- .../MongoDB/BackgroundJobRepositoryTests.cs | 5 ++++- .../Abp/BackgroundJobs/MongoDB/MongoDbFixture.cs | 16 ++++++++++++++++ .../MongoDB/MongoTestCollection.cs | 10 ++++++++++ 4 files changed, 31 insertions(+), 6 deletions(-) create mode 100644 modules/background-jobs/test/Volo.Abp.BackgroundJobs.MongoDB.Tests/Volo/Abp/BackgroundJobs/MongoDB/MongoDbFixture.cs create mode 100644 modules/background-jobs/test/Volo.Abp.BackgroundJobs.MongoDB.Tests/Volo/Abp/BackgroundJobs/MongoDB/MongoTestCollection.cs diff --git a/modules/background-jobs/test/Volo.Abp.BackgroundJobs.MongoDB.Tests/Volo/Abp/BackgroundJobs/MongoDB/AbpBackgroundJobsMongoDbTestModule.cs b/modules/background-jobs/test/Volo.Abp.BackgroundJobs.MongoDB.Tests/Volo/Abp/BackgroundJobs/MongoDB/AbpBackgroundJobsMongoDbTestModule.cs index 4147917829..07be76b792 100644 --- a/modules/background-jobs/test/Volo.Abp.BackgroundJobs.MongoDB.Tests/Volo/Abp/BackgroundJobs/MongoDB/AbpBackgroundJobsMongoDbTestModule.cs +++ b/modules/background-jobs/test/Volo.Abp.BackgroundJobs.MongoDB.Tests/Volo/Abp/BackgroundJobs/MongoDB/AbpBackgroundJobsMongoDbTestModule.cs @@ -1,6 +1,4 @@ using System; -using Microsoft.Extensions.DependencyInjection; -using Mongo2Go; using Volo.Abp.Data; using Volo.Abp.Modularity; @@ -12,11 +10,9 @@ namespace Volo.Abp.BackgroundJobs.MongoDB )] public class AbpBackgroundJobsMongoDbTestModule : AbpModule { - private static readonly MongoDbRunner MongoDbRunner = MongoDbRunner.Start(); - public override void ConfigureServices(ServiceConfigurationContext context) { - var connectionString = MongoDbRunner.ConnectionString.EnsureEndsWith('/') + + var connectionString = MongoDbFixture.ConnectionString.EnsureEndsWith('/') + "Db_" + Guid.NewGuid().ToString("N"); diff --git a/modules/background-jobs/test/Volo.Abp.BackgroundJobs.MongoDB.Tests/Volo/Abp/BackgroundJobs/MongoDB/BackgroundJobRepositoryTests.cs b/modules/background-jobs/test/Volo.Abp.BackgroundJobs.MongoDB.Tests/Volo/Abp/BackgroundJobs/MongoDB/BackgroundJobRepositoryTests.cs index 429cf4821f..f3827c50e2 100644 --- a/modules/background-jobs/test/Volo.Abp.BackgroundJobs.MongoDB.Tests/Volo/Abp/BackgroundJobs/MongoDB/BackgroundJobRepositoryTests.cs +++ b/modules/background-jobs/test/Volo.Abp.BackgroundJobs.MongoDB.Tests/Volo/Abp/BackgroundJobs/MongoDB/BackgroundJobRepositoryTests.cs @@ -1,5 +1,8 @@ -namespace Volo.Abp.BackgroundJobs.MongoDB +using Xunit; + +namespace Volo.Abp.BackgroundJobs.MongoDB { + [Collection((MongoTestCollection.Name))] public class BackgroundJobRepositoryTests : BackgroundJobRepository_Tests { diff --git a/modules/background-jobs/test/Volo.Abp.BackgroundJobs.MongoDB.Tests/Volo/Abp/BackgroundJobs/MongoDB/MongoDbFixture.cs b/modules/background-jobs/test/Volo.Abp.BackgroundJobs.MongoDB.Tests/Volo/Abp/BackgroundJobs/MongoDB/MongoDbFixture.cs new file mode 100644 index 0000000000..3ae1d8fc10 --- /dev/null +++ b/modules/background-jobs/test/Volo.Abp.BackgroundJobs.MongoDB.Tests/Volo/Abp/BackgroundJobs/MongoDB/MongoDbFixture.cs @@ -0,0 +1,16 @@ +using System; +using Mongo2Go; + +namespace Volo.Abp.BackgroundJobs.MongoDB +{ + public class MongoDbFixture : IDisposable + { + private static readonly MongoDbRunner MongoDbRunner = MongoDbRunner.Start(); + public static readonly string ConnectionString = MongoDbRunner.ConnectionString; + + public void Dispose() + { + MongoDbRunner?.Dispose(); + } + } +} \ No newline at end of file diff --git a/modules/background-jobs/test/Volo.Abp.BackgroundJobs.MongoDB.Tests/Volo/Abp/BackgroundJobs/MongoDB/MongoTestCollection.cs b/modules/background-jobs/test/Volo.Abp.BackgroundJobs.MongoDB.Tests/Volo/Abp/BackgroundJobs/MongoDB/MongoTestCollection.cs new file mode 100644 index 0000000000..0096ae6f10 --- /dev/null +++ b/modules/background-jobs/test/Volo.Abp.BackgroundJobs.MongoDB.Tests/Volo/Abp/BackgroundJobs/MongoDB/MongoTestCollection.cs @@ -0,0 +1,10 @@ +using Xunit; + +namespace Volo.Abp.BackgroundJobs.MongoDB +{ + [CollectionDefinition(Name)] + public class MongoTestCollection : ICollectionFixture + { + public const string Name = "MongoDB Collection"; + } +} \ No newline at end of file From db4a558f064113306872643fa967fd73410b987d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mehmet=20Tu=CC=88ken?= Date: Wed, 18 Dec 2019 02:48:07 +0300 Subject: [PATCH 005/334] remove unused usings --- .../AuditLogging/MongoDB/AbpAuditLoggingMongoDbTestModule.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/modules/audit-logging/test/Volo.Abp.AuditLogging.MongoDB.Tests/Volo/Abp/AuditLogging/MongoDB/AbpAuditLoggingMongoDbTestModule.cs b/modules/audit-logging/test/Volo.Abp.AuditLogging.MongoDB.Tests/Volo/Abp/AuditLogging/MongoDB/AbpAuditLoggingMongoDbTestModule.cs index b57c204818..5cac32faae 100644 --- a/modules/audit-logging/test/Volo.Abp.AuditLogging.MongoDB.Tests/Volo/Abp/AuditLogging/MongoDB/AbpAuditLoggingMongoDbTestModule.cs +++ b/modules/audit-logging/test/Volo.Abp.AuditLogging.MongoDB.Tests/Volo/Abp/AuditLogging/MongoDB/AbpAuditLoggingMongoDbTestModule.cs @@ -1,6 +1,4 @@ using System; -using Microsoft.Extensions.DependencyInjection; -using Mongo2Go; using Volo.Abp.Data; using Volo.Abp.Modularity; From 4adaf68123aa4d86db728b4755575db64a7e22dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mehmet=20Tu=CC=88ken?= Date: Wed, 18 Dec 2019 02:55:26 +0300 Subject: [PATCH 006/334] [modules/blogging] fix mongo.exe dispose --- .../Volo/Blogging/Blogs/BlogRepository_Tests.cs | 2 ++ .../Blogging/Comments/CommentRepository_Tests.cs | 2 ++ .../MongoDB/BloggingMongoDBTestModule.cs | 6 +----- .../Volo/Blogging/MongoDB/MongoDbFixture.cs | 16 ++++++++++++++++ .../Volo/Blogging/MongoDB/MongoTestCollection.cs | 10 ++++++++++ .../Volo/Blogging/Posts/PostRepository_Tests.cs | 2 ++ .../Volo/Blogging/Tagging/TagRepository_Tests.cs | 2 ++ 7 files changed, 35 insertions(+), 5 deletions(-) create mode 100644 modules/blogging/test/Volo.Blogging.MongoDB.Tests/Volo/Blogging/MongoDB/MongoDbFixture.cs create mode 100644 modules/blogging/test/Volo.Blogging.MongoDB.Tests/Volo/Blogging/MongoDB/MongoTestCollection.cs diff --git a/modules/blogging/test/Volo.Blogging.MongoDB.Tests/Volo/Blogging/Blogs/BlogRepository_Tests.cs b/modules/blogging/test/Volo.Blogging.MongoDB.Tests/Volo/Blogging/Blogs/BlogRepository_Tests.cs index 76044f257c..060d3b86fc 100644 --- a/modules/blogging/test/Volo.Blogging.MongoDB.Tests/Volo/Blogging/Blogs/BlogRepository_Tests.cs +++ b/modules/blogging/test/Volo.Blogging.MongoDB.Tests/Volo/Blogging/Blogs/BlogRepository_Tests.cs @@ -1,8 +1,10 @@ using Volo.Blogging.Blogs; using Volo.Blogging.MongoDB; +using Xunit; namespace Volo.Blogging { + [Collection(MongoTestCollection.Name)] public class BlogRepository_Tests : BlogRepository_Tests { } diff --git a/modules/blogging/test/Volo.Blogging.MongoDB.Tests/Volo/Blogging/Comments/CommentRepository_Tests.cs b/modules/blogging/test/Volo.Blogging.MongoDB.Tests/Volo/Blogging/Comments/CommentRepository_Tests.cs index a001f9b0d9..d956cf1b15 100644 --- a/modules/blogging/test/Volo.Blogging.MongoDB.Tests/Volo/Blogging/Comments/CommentRepository_Tests.cs +++ b/modules/blogging/test/Volo.Blogging.MongoDB.Tests/Volo/Blogging/Comments/CommentRepository_Tests.cs @@ -1,8 +1,10 @@ using Volo.Blogging.Comments; using Volo.Blogging.MongoDB; +using Xunit; namespace Volo.Blogging { + [Collection(MongoTestCollection.Name)] public class CommentRepository_Tests : CommentRepository_Tests { } diff --git a/modules/blogging/test/Volo.Blogging.MongoDB.Tests/Volo/Blogging/MongoDB/BloggingMongoDBTestModule.cs b/modules/blogging/test/Volo.Blogging.MongoDB.Tests/Volo/Blogging/MongoDB/BloggingMongoDBTestModule.cs index 4c4b34ef54..1e68cebf21 100644 --- a/modules/blogging/test/Volo.Blogging.MongoDB.Tests/Volo/Blogging/MongoDB/BloggingMongoDBTestModule.cs +++ b/modules/blogging/test/Volo.Blogging.MongoDB.Tests/Volo/Blogging/MongoDB/BloggingMongoDBTestModule.cs @@ -1,6 +1,4 @@ using System; -using Mongo2Go; -using Volo.Abp; using Volo.Abp.Data; using Volo.Abp.Modularity; @@ -12,11 +10,9 @@ namespace Volo.Blogging.MongoDB )] public class BloggingMongoDbTestModule : AbpModule { - private static readonly MongoDbRunner MongoDbRunner = MongoDbRunner.Start(); - public override void ConfigureServices(ServiceConfigurationContext context) { - var connectionString = MongoDbRunner.ConnectionString.EnsureEndsWith('/') + + var connectionString = MongoDbFixture.ConnectionString.EnsureEndsWith('/') + "Db_" + Guid.NewGuid().ToString("N"); diff --git a/modules/blogging/test/Volo.Blogging.MongoDB.Tests/Volo/Blogging/MongoDB/MongoDbFixture.cs b/modules/blogging/test/Volo.Blogging.MongoDB.Tests/Volo/Blogging/MongoDB/MongoDbFixture.cs new file mode 100644 index 0000000000..d5fbfb4451 --- /dev/null +++ b/modules/blogging/test/Volo.Blogging.MongoDB.Tests/Volo/Blogging/MongoDB/MongoDbFixture.cs @@ -0,0 +1,16 @@ +using System; +using Mongo2Go; + +namespace Volo.Blogging.MongoDB +{ + public class MongoDbFixture : IDisposable + { + private static readonly MongoDbRunner MongoDbRunner = MongoDbRunner.Start(); + public static readonly string ConnectionString = MongoDbRunner.ConnectionString; + + public void Dispose() + { + MongoDbRunner?.Dispose(); + } + } +} \ No newline at end of file diff --git a/modules/blogging/test/Volo.Blogging.MongoDB.Tests/Volo/Blogging/MongoDB/MongoTestCollection.cs b/modules/blogging/test/Volo.Blogging.MongoDB.Tests/Volo/Blogging/MongoDB/MongoTestCollection.cs new file mode 100644 index 0000000000..f075e5dd07 --- /dev/null +++ b/modules/blogging/test/Volo.Blogging.MongoDB.Tests/Volo/Blogging/MongoDB/MongoTestCollection.cs @@ -0,0 +1,10 @@ +using Xunit; + +namespace Volo.Blogging.MongoDB +{ + [CollectionDefinition(Name)] + public class MongoTestCollection : ICollectionFixture + { + public const string Name = "MongoDB Collection"; + } +} \ No newline at end of file diff --git a/modules/blogging/test/Volo.Blogging.MongoDB.Tests/Volo/Blogging/Posts/PostRepository_Tests.cs b/modules/blogging/test/Volo.Blogging.MongoDB.Tests/Volo/Blogging/Posts/PostRepository_Tests.cs index d0e13ba403..814f0d206e 100644 --- a/modules/blogging/test/Volo.Blogging.MongoDB.Tests/Volo/Blogging/Posts/PostRepository_Tests.cs +++ b/modules/blogging/test/Volo.Blogging.MongoDB.Tests/Volo/Blogging/Posts/PostRepository_Tests.cs @@ -1,8 +1,10 @@ using Volo.Blogging.Posts; using Volo.Blogging.MongoDB; +using Xunit; namespace Volo.Blogging { + [Collection(MongoTestCollection.Name)] public class PostRepository_Tests : PostRepository_Tests { } diff --git a/modules/blogging/test/Volo.Blogging.MongoDB.Tests/Volo/Blogging/Tagging/TagRepository_Tests.cs b/modules/blogging/test/Volo.Blogging.MongoDB.Tests/Volo/Blogging/Tagging/TagRepository_Tests.cs index 8f13c6c6b0..66cb0d52c5 100644 --- a/modules/blogging/test/Volo.Blogging.MongoDB.Tests/Volo/Blogging/Tagging/TagRepository_Tests.cs +++ b/modules/blogging/test/Volo.Blogging.MongoDB.Tests/Volo/Blogging/Tagging/TagRepository_Tests.cs @@ -1,8 +1,10 @@ using Volo.Blogging.Tagging; using Volo.Blogging.MongoDB; +using Xunit; namespace Volo.Blogging { + [Collection(MongoTestCollection.Name)] public class TagRepository_Tests : TagRepository_Tests { } From 8bf5a24fbc40e01ebc8fd56bc7d17557cfd1168e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mehmet=20Tu=CC=88ken?= Date: Wed, 18 Dec 2019 03:14:34 +0300 Subject: [PATCH 007/334] [modules/docs] fix mongo.exe dispose --- .../Volo/Docs/MongoDB/DocsMongoDBTestModule.cs | 6 +----- .../Volo/Docs/MongoDB/MongoDbFixture.cs | 16 ++++++++++++++++ .../Volo/Docs/MongoDB/MongoTestCollection.cs | 10 ++++++++++ .../Volo/Docs/Project/ProjectRepository_Tests.cs | 2 ++ 4 files changed, 29 insertions(+), 5 deletions(-) create mode 100644 modules/docs/test/Volo.Docs.MongoDB.Tests/Volo/Docs/MongoDB/MongoDbFixture.cs create mode 100644 modules/docs/test/Volo.Docs.MongoDB.Tests/Volo/Docs/MongoDB/MongoTestCollection.cs diff --git a/modules/docs/test/Volo.Docs.MongoDB.Tests/Volo/Docs/MongoDB/DocsMongoDBTestModule.cs b/modules/docs/test/Volo.Docs.MongoDB.Tests/Volo/Docs/MongoDB/DocsMongoDBTestModule.cs index c5fef83ddb..b31f9b5acd 100644 --- a/modules/docs/test/Volo.Docs.MongoDB.Tests/Volo/Docs/MongoDB/DocsMongoDBTestModule.cs +++ b/modules/docs/test/Volo.Docs.MongoDB.Tests/Volo/Docs/MongoDB/DocsMongoDBTestModule.cs @@ -1,6 +1,4 @@ using System; -using Mongo2Go; -using Volo.Abp; using Volo.Abp.Data; using Volo.Abp.Modularity; @@ -12,11 +10,9 @@ namespace Volo.Docs.MongoDB )] public class DocsMongoDBTestModule : AbpModule { - private static readonly MongoDbRunner MongoDbRunner = MongoDbRunner.Start(); - public override void ConfigureServices(ServiceConfigurationContext context) { - var connectionString = MongoDbRunner.ConnectionString.EnsureEndsWith('/') + + var connectionString = MongoDbFixture.ConnectionString.EnsureEndsWith('/') + "Db_" + Guid.NewGuid().ToString("N"); diff --git a/modules/docs/test/Volo.Docs.MongoDB.Tests/Volo/Docs/MongoDB/MongoDbFixture.cs b/modules/docs/test/Volo.Docs.MongoDB.Tests/Volo/Docs/MongoDB/MongoDbFixture.cs new file mode 100644 index 0000000000..fc920813ab --- /dev/null +++ b/modules/docs/test/Volo.Docs.MongoDB.Tests/Volo/Docs/MongoDB/MongoDbFixture.cs @@ -0,0 +1,16 @@ +using System; +using Mongo2Go; + +namespace Volo.Docs.MongoDB +{ + public class MongoDbFixture : IDisposable + { + private static readonly MongoDbRunner MongoDbRunner = MongoDbRunner.Start(); + public static readonly string ConnectionString = MongoDbRunner.ConnectionString; + + public void Dispose() + { + MongoDbRunner?.Dispose(); + } + } +} \ No newline at end of file diff --git a/modules/docs/test/Volo.Docs.MongoDB.Tests/Volo/Docs/MongoDB/MongoTestCollection.cs b/modules/docs/test/Volo.Docs.MongoDB.Tests/Volo/Docs/MongoDB/MongoTestCollection.cs new file mode 100644 index 0000000000..86505c5a73 --- /dev/null +++ b/modules/docs/test/Volo.Docs.MongoDB.Tests/Volo/Docs/MongoDB/MongoTestCollection.cs @@ -0,0 +1,10 @@ +using Xunit; + +namespace Volo.Docs.MongoDB +{ + [CollectionDefinition(Name)] + public class MongoTestCollection : ICollectionFixture + { + public const string Name = "MongoDB Collection"; + } +} \ No newline at end of file diff --git a/modules/docs/test/Volo.Docs.MongoDB.Tests/Volo/Docs/Project/ProjectRepository_Tests.cs b/modules/docs/test/Volo.Docs.MongoDB.Tests/Volo/Docs/Project/ProjectRepository_Tests.cs index 6f2df01a11..696dd31185 100644 --- a/modules/docs/test/Volo.Docs.MongoDB.Tests/Volo/Docs/Project/ProjectRepository_Tests.cs +++ b/modules/docs/test/Volo.Docs.MongoDB.Tests/Volo/Docs/Project/ProjectRepository_Tests.cs @@ -1,7 +1,9 @@ using Volo.Docs.MongoDB; +using Xunit; namespace Volo.Docs.Project { + [Collection(MongoTestCollection.Name)] public class ProjectRepository_Tests : ProjectRepository_Tests { } From 993d5c5a09320c92a9c4fa8bbf7bd0c22e385943 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mehmet=20Tu=CC=88ken?= Date: Wed, 18 Dec 2019 03:24:53 +0300 Subject: [PATCH 008/334] [modules/featuremanagement] fix mongo.exe dispose --- .../AbpFeatureManagementMongoDbTestModule.cs | 5 +---- .../MongoDB/FeatureManagementStore_Tests.cs | 5 ++--- .../MongoDB/FeatureValueRepositoryTests.cs | 5 ++++- .../FeatureManagement/MongoDB/MongoDbFixture.cs | 16 ++++++++++++++++ .../MongoDB/MongoTestCollection.cs | 10 ++++++++++ 5 files changed, 33 insertions(+), 8 deletions(-) create mode 100644 modules/feature-management/test/Volo.Abp.FeatureManagement.MongoDB.Tests/Volo/Abp/FeatureManagement/MongoDB/MongoDbFixture.cs create mode 100644 modules/feature-management/test/Volo.Abp.FeatureManagement.MongoDB.Tests/Volo/Abp/FeatureManagement/MongoDB/MongoTestCollection.cs diff --git a/modules/feature-management/test/Volo.Abp.FeatureManagement.MongoDB.Tests/Volo/Abp/FeatureManagement/MongoDB/AbpFeatureManagementMongoDbTestModule.cs b/modules/feature-management/test/Volo.Abp.FeatureManagement.MongoDB.Tests/Volo/Abp/FeatureManagement/MongoDB/AbpFeatureManagementMongoDbTestModule.cs index 00b5b22871..04d4ac916f 100644 --- a/modules/feature-management/test/Volo.Abp.FeatureManagement.MongoDB.Tests/Volo/Abp/FeatureManagement/MongoDB/AbpFeatureManagementMongoDbTestModule.cs +++ b/modules/feature-management/test/Volo.Abp.FeatureManagement.MongoDB.Tests/Volo/Abp/FeatureManagement/MongoDB/AbpFeatureManagementMongoDbTestModule.cs @@ -1,5 +1,4 @@ using System; -using Mongo2Go; using Volo.Abp.Data; using Volo.Abp.Modularity; @@ -11,11 +10,9 @@ namespace Volo.Abp.FeatureManagement.MongoDB )] public class AbpFeatureManagementMongoDbTestModule : AbpModule { - private static readonly MongoDbRunner MongoDbRunner = MongoDbRunner.Start(); - public override void ConfigureServices(ServiceConfigurationContext context) { - var connectionString = MongoDbRunner.ConnectionString.EnsureEndsWith('/') + + var connectionString = MongoDbFixture.ConnectionString.EnsureEndsWith('/') + "Db_" + Guid.NewGuid().ToString("N"); diff --git a/modules/feature-management/test/Volo.Abp.FeatureManagement.MongoDB.Tests/Volo/Abp/FeatureManagement/MongoDB/FeatureManagementStore_Tests.cs b/modules/feature-management/test/Volo.Abp.FeatureManagement.MongoDB.Tests/Volo/Abp/FeatureManagement/MongoDB/FeatureManagementStore_Tests.cs index 7df6e3516b..0337bc8822 100644 --- a/modules/feature-management/test/Volo.Abp.FeatureManagement.MongoDB.Tests/Volo/Abp/FeatureManagement/MongoDB/FeatureManagementStore_Tests.cs +++ b/modules/feature-management/test/Volo.Abp.FeatureManagement.MongoDB.Tests/Volo/Abp/FeatureManagement/MongoDB/FeatureManagementStore_Tests.cs @@ -1,9 +1,8 @@ -using System; -using System.Collections.Generic; -using System.Text; +using Xunit; namespace Volo.Abp.FeatureManagement.MongoDB { + [Collection(MongoTestCollection.Name)] public class FeatureManagementStore_Tests : FeatureManagementStore_Tests { diff --git a/modules/feature-management/test/Volo.Abp.FeatureManagement.MongoDB.Tests/Volo/Abp/FeatureManagement/MongoDB/FeatureValueRepositoryTests.cs b/modules/feature-management/test/Volo.Abp.FeatureManagement.MongoDB.Tests/Volo/Abp/FeatureManagement/MongoDB/FeatureValueRepositoryTests.cs index 6184e4c90f..9654d8ab27 100644 --- a/modules/feature-management/test/Volo.Abp.FeatureManagement.MongoDB.Tests/Volo/Abp/FeatureManagement/MongoDB/FeatureValueRepositoryTests.cs +++ b/modules/feature-management/test/Volo.Abp.FeatureManagement.MongoDB.Tests/Volo/Abp/FeatureManagement/MongoDB/FeatureValueRepositoryTests.cs @@ -1,5 +1,8 @@ -namespace Volo.Abp.FeatureManagement.MongoDB +using Xunit; + +namespace Volo.Abp.FeatureManagement.MongoDB { + [Collection(MongoTestCollection.Name)] public class FeatureValueRepositoryTests : FeatureValueRepository_Tests { diff --git a/modules/feature-management/test/Volo.Abp.FeatureManagement.MongoDB.Tests/Volo/Abp/FeatureManagement/MongoDB/MongoDbFixture.cs b/modules/feature-management/test/Volo.Abp.FeatureManagement.MongoDB.Tests/Volo/Abp/FeatureManagement/MongoDB/MongoDbFixture.cs new file mode 100644 index 0000000000..bfd7fa9c04 --- /dev/null +++ b/modules/feature-management/test/Volo.Abp.FeatureManagement.MongoDB.Tests/Volo/Abp/FeatureManagement/MongoDB/MongoDbFixture.cs @@ -0,0 +1,16 @@ +using System; +using Mongo2Go; + +namespace Volo.Abp.FeatureManagement.MongoDB +{ + public class MongoDbFixture : IDisposable + { + private static readonly MongoDbRunner MongoDbRunner = MongoDbRunner.Start(); + public static readonly string ConnectionString = MongoDbRunner.ConnectionString; + + public void Dispose() + { + MongoDbRunner?.Dispose(); + } + } +} \ No newline at end of file diff --git a/modules/feature-management/test/Volo.Abp.FeatureManagement.MongoDB.Tests/Volo/Abp/FeatureManagement/MongoDB/MongoTestCollection.cs b/modules/feature-management/test/Volo.Abp.FeatureManagement.MongoDB.Tests/Volo/Abp/FeatureManagement/MongoDB/MongoTestCollection.cs new file mode 100644 index 0000000000..c8a6e1c58c --- /dev/null +++ b/modules/feature-management/test/Volo.Abp.FeatureManagement.MongoDB.Tests/Volo/Abp/FeatureManagement/MongoDB/MongoTestCollection.cs @@ -0,0 +1,10 @@ +using Xunit; + +namespace Volo.Abp.FeatureManagement.MongoDB +{ + [CollectionDefinition(Name)] + public class MongoTestCollection : ICollectionFixture + { + public const string Name = "MongoDB Collection"; + } +} \ No newline at end of file From 96f7b57ab73611c1eec297329d1042808a21d7a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mehmet=20Tu=CC=88ken?= Date: Wed, 18 Dec 2019 03:28:49 +0300 Subject: [PATCH 009/334] [modules/identity] fix mongo.exe dispose --- .../MongoDB/AbpIdentityMongoDbTestModule.cs | 6 +----- .../MongoDB/IdentityClaimTypeRepository_Tests.cs | 5 ++++- .../Identity/MongoDB/IdentityDataSeeder_Tests.cs | 5 ++++- .../MongoDB/IdentityRoleRepository_Tests.cs | 5 ++++- .../MongoDB/IdentityUserRepository_Tests.cs | 5 ++++- .../MongoDB/Identity_Repository_Resolve_Tests.cs | 5 ++++- .../Volo/Abp/Identity/MongoDB/MongoDbFixture.cs | 16 ++++++++++++++++ .../Abp/Identity/MongoDB/MongoTestCollection.cs | 10 ++++++++++ 8 files changed, 47 insertions(+), 10 deletions(-) create mode 100644 modules/identity/test/Volo.Abp.Identity.MongoDB.Tests/Volo/Abp/Identity/MongoDB/MongoDbFixture.cs create mode 100644 modules/identity/test/Volo.Abp.Identity.MongoDB.Tests/Volo/Abp/Identity/MongoDB/MongoTestCollection.cs diff --git a/modules/identity/test/Volo.Abp.Identity.MongoDB.Tests/Volo/Abp/Identity/MongoDB/AbpIdentityMongoDbTestModule.cs b/modules/identity/test/Volo.Abp.Identity.MongoDB.Tests/Volo/Abp/Identity/MongoDB/AbpIdentityMongoDbTestModule.cs index 6e9f3806a2..f730e5f445 100644 --- a/modules/identity/test/Volo.Abp.Identity.MongoDB.Tests/Volo/Abp/Identity/MongoDB/AbpIdentityMongoDbTestModule.cs +++ b/modules/identity/test/Volo.Abp.Identity.MongoDB.Tests/Volo/Abp/Identity/MongoDB/AbpIdentityMongoDbTestModule.cs @@ -1,6 +1,4 @@ using System; -using Microsoft.Extensions.DependencyInjection; -using Mongo2Go; using Volo.Abp.Data; using Volo.Abp.Modularity; using Volo.Abp.PermissionManagement.MongoDB; @@ -14,11 +12,9 @@ namespace Volo.Abp.Identity.MongoDB )] public class AbpIdentityMongoDbTestModule : AbpModule { - private static readonly MongoDbRunner MongoDbRunner = MongoDbRunner.Start(); - public override void ConfigureServices(ServiceConfigurationContext context) { - var connectionString = MongoDbRunner.ConnectionString.EnsureEndsWith('/') + + var connectionString = MongoDbFixture.ConnectionString.EnsureEndsWith('/') + "Db_" + Guid.NewGuid().ToString("N"); diff --git a/modules/identity/test/Volo.Abp.Identity.MongoDB.Tests/Volo/Abp/Identity/MongoDB/IdentityClaimTypeRepository_Tests.cs b/modules/identity/test/Volo.Abp.Identity.MongoDB.Tests/Volo/Abp/Identity/MongoDB/IdentityClaimTypeRepository_Tests.cs index b7926aae00..cc66856c06 100644 --- a/modules/identity/test/Volo.Abp.Identity.MongoDB.Tests/Volo/Abp/Identity/MongoDB/IdentityClaimTypeRepository_Tests.cs +++ b/modules/identity/test/Volo.Abp.Identity.MongoDB.Tests/Volo/Abp/Identity/MongoDB/IdentityClaimTypeRepository_Tests.cs @@ -1,5 +1,8 @@ -namespace Volo.Abp.Identity.MongoDB +using Xunit; + +namespace Volo.Abp.Identity.MongoDB { + [Collection(MongoTestCollection.Name)] public class IdentityClaimTypeRepository_Tests : IdentityClaimTypeRepository_Tests { diff --git a/modules/identity/test/Volo.Abp.Identity.MongoDB.Tests/Volo/Abp/Identity/MongoDB/IdentityDataSeeder_Tests.cs b/modules/identity/test/Volo.Abp.Identity.MongoDB.Tests/Volo/Abp/Identity/MongoDB/IdentityDataSeeder_Tests.cs index e97269c7e2..d614807395 100644 --- a/modules/identity/test/Volo.Abp.Identity.MongoDB.Tests/Volo/Abp/Identity/MongoDB/IdentityDataSeeder_Tests.cs +++ b/modules/identity/test/Volo.Abp.Identity.MongoDB.Tests/Volo/Abp/Identity/MongoDB/IdentityDataSeeder_Tests.cs @@ -1,5 +1,8 @@ -namespace Volo.Abp.Identity.MongoDB +using Xunit; + +namespace Volo.Abp.Identity.MongoDB { + [Collection(MongoTestCollection.Name)] public class IdentityDataSeeder_Tests : IdentityDataSeeder_Tests { diff --git a/modules/identity/test/Volo.Abp.Identity.MongoDB.Tests/Volo/Abp/Identity/MongoDB/IdentityRoleRepository_Tests.cs b/modules/identity/test/Volo.Abp.Identity.MongoDB.Tests/Volo/Abp/Identity/MongoDB/IdentityRoleRepository_Tests.cs index 4873aa7298..8fde9dbb2c 100644 --- a/modules/identity/test/Volo.Abp.Identity.MongoDB.Tests/Volo/Abp/Identity/MongoDB/IdentityRoleRepository_Tests.cs +++ b/modules/identity/test/Volo.Abp.Identity.MongoDB.Tests/Volo/Abp/Identity/MongoDB/IdentityRoleRepository_Tests.cs @@ -1,5 +1,8 @@ -namespace Volo.Abp.Identity.MongoDB +using Xunit; + +namespace Volo.Abp.Identity.MongoDB { + [Collection(MongoTestCollection.Name)] public class IdentityRoleRepository_Tests : IdentityRoleRepository_Tests { diff --git a/modules/identity/test/Volo.Abp.Identity.MongoDB.Tests/Volo/Abp/Identity/MongoDB/IdentityUserRepository_Tests.cs b/modules/identity/test/Volo.Abp.Identity.MongoDB.Tests/Volo/Abp/Identity/MongoDB/IdentityUserRepository_Tests.cs index 214d8f6986..e29a216ca7 100644 --- a/modules/identity/test/Volo.Abp.Identity.MongoDB.Tests/Volo/Abp/Identity/MongoDB/IdentityUserRepository_Tests.cs +++ b/modules/identity/test/Volo.Abp.Identity.MongoDB.Tests/Volo/Abp/Identity/MongoDB/IdentityUserRepository_Tests.cs @@ -1,5 +1,8 @@ -namespace Volo.Abp.Identity.MongoDB +using Xunit; + +namespace Volo.Abp.Identity.MongoDB { + [Collection(MongoTestCollection.Name)] public class IdentityUserRepository_Tests : IdentityUserRepository_Tests { diff --git a/modules/identity/test/Volo.Abp.Identity.MongoDB.Tests/Volo/Abp/Identity/MongoDB/Identity_Repository_Resolve_Tests.cs b/modules/identity/test/Volo.Abp.Identity.MongoDB.Tests/Volo/Abp/Identity/MongoDB/Identity_Repository_Resolve_Tests.cs index 5d6742adef..42020a4170 100644 --- a/modules/identity/test/Volo.Abp.Identity.MongoDB.Tests/Volo/Abp/Identity/MongoDB/Identity_Repository_Resolve_Tests.cs +++ b/modules/identity/test/Volo.Abp.Identity.MongoDB.Tests/Volo/Abp/Identity/MongoDB/Identity_Repository_Resolve_Tests.cs @@ -1,5 +1,8 @@ -namespace Volo.Abp.Identity.MongoDB +using Xunit; + +namespace Volo.Abp.Identity.MongoDB { + [Collection(MongoTestCollection.Name)] public class Identity_Repository_Resolve_Tests : Identity_Repository_Resolve_Tests { } diff --git a/modules/identity/test/Volo.Abp.Identity.MongoDB.Tests/Volo/Abp/Identity/MongoDB/MongoDbFixture.cs b/modules/identity/test/Volo.Abp.Identity.MongoDB.Tests/Volo/Abp/Identity/MongoDB/MongoDbFixture.cs new file mode 100644 index 0000000000..26de0a9399 --- /dev/null +++ b/modules/identity/test/Volo.Abp.Identity.MongoDB.Tests/Volo/Abp/Identity/MongoDB/MongoDbFixture.cs @@ -0,0 +1,16 @@ +using System; +using Mongo2Go; + +namespace Volo.Abp.Identity.MongoDB +{ + public class MongoDbFixture : IDisposable + { + private static readonly MongoDbRunner MongoDbRunner = MongoDbRunner.Start(); + public static readonly string ConnectionString = MongoDbRunner.ConnectionString; + + public void Dispose() + { + MongoDbRunner?.Dispose(); + } + } +} \ No newline at end of file diff --git a/modules/identity/test/Volo.Abp.Identity.MongoDB.Tests/Volo/Abp/Identity/MongoDB/MongoTestCollection.cs b/modules/identity/test/Volo.Abp.Identity.MongoDB.Tests/Volo/Abp/Identity/MongoDB/MongoTestCollection.cs new file mode 100644 index 0000000000..ae01262908 --- /dev/null +++ b/modules/identity/test/Volo.Abp.Identity.MongoDB.Tests/Volo/Abp/Identity/MongoDB/MongoTestCollection.cs @@ -0,0 +1,10 @@ +using Xunit; + +namespace Volo.Abp.Identity.MongoDB +{ + [CollectionDefinition(Name)] + public class MongoTestCollection : ICollectionFixture + { + public const string Name = "MongoDB Collection"; + } +} \ No newline at end of file From 18344cbdae4780a372b083dbc4f3129aaef15eeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mehmet=20Tu=CC=88ken?= Date: Wed, 18 Dec 2019 03:37:57 +0300 Subject: [PATCH 010/334] [modules/identityserver] fix mongo.exe dispose --- .../AbpIdentityServerMongoDbTestModule.cs | 5 +---- .../ApiResourceRepository_Tests.cs | 4 +++- .../Abp/IdentityServer/ClientRepository_Tests.cs | 5 ++--- .../IdentityResourceRepository_Tests.cs | 5 ++--- .../Volo/Abp/IdentityServer/MongoDbFixture.cs | 16 ++++++++++++++++ .../Abp/IdentityServer/MongoTestCollection.cs | 10 ++++++++++ .../PersistentGrantRepository_Tests.cs | 5 ++--- 7 files changed, 36 insertions(+), 14 deletions(-) create mode 100644 modules/identityserver/test/Volo.Abp.IdentityServer.MongoDB.Tests/Volo/Abp/IdentityServer/MongoDbFixture.cs create mode 100644 modules/identityserver/test/Volo.Abp.IdentityServer.MongoDB.Tests/Volo/Abp/IdentityServer/MongoTestCollection.cs diff --git a/modules/identityserver/test/Volo.Abp.IdentityServer.MongoDB.Tests/Volo/Abp/IdentityServer/AbpIdentityServerMongoDbTestModule.cs b/modules/identityserver/test/Volo.Abp.IdentityServer.MongoDB.Tests/Volo/Abp/IdentityServer/AbpIdentityServerMongoDbTestModule.cs index ebfa34404d..d1721c720f 100644 --- a/modules/identityserver/test/Volo.Abp.IdentityServer.MongoDB.Tests/Volo/Abp/IdentityServer/AbpIdentityServerMongoDbTestModule.cs +++ b/modules/identityserver/test/Volo.Abp.IdentityServer.MongoDB.Tests/Volo/Abp/IdentityServer/AbpIdentityServerMongoDbTestModule.cs @@ -1,5 +1,4 @@ using System; -using Mongo2Go; using Volo.Abp.Data; using Volo.Abp.Identity.MongoDB; using Volo.Abp.IdentityServer.MongoDB; @@ -15,11 +14,9 @@ namespace Volo.Abp.IdentityServer )] public class AbpIdentityServerMongoDbTestModule : AbpModule { - private static readonly MongoDbRunner MongoDbRunner = MongoDbRunner.Start(); - public override void ConfigureServices(ServiceConfigurationContext context) { - var connectionString = MongoDbRunner.ConnectionString.EnsureEndsWith('/') + + var connectionString = MongoDbFixture.ConnectionString.EnsureEndsWith('/') + "Db_" + Guid.NewGuid().ToString("N"); diff --git a/modules/identityserver/test/Volo.Abp.IdentityServer.MongoDB.Tests/Volo/Abp/IdentityServer/ApiResourceRepository_Tests.cs b/modules/identityserver/test/Volo.Abp.IdentityServer.MongoDB.Tests/Volo/Abp/IdentityServer/ApiResourceRepository_Tests.cs index 032505266d..dfe00ab4dd 100644 --- a/modules/identityserver/test/Volo.Abp.IdentityServer.MongoDB.Tests/Volo/Abp/IdentityServer/ApiResourceRepository_Tests.cs +++ b/modules/identityserver/test/Volo.Abp.IdentityServer.MongoDB.Tests/Volo/Abp/IdentityServer/ApiResourceRepository_Tests.cs @@ -1,6 +1,8 @@ - +using Xunit; + namespace Volo.Abp.IdentityServer { + [Collection(MongoTestCollection.Name)] public class ApiResourceRepository_Tests : ApiResourceRepository_Tests { } diff --git a/modules/identityserver/test/Volo.Abp.IdentityServer.MongoDB.Tests/Volo/Abp/IdentityServer/ClientRepository_Tests.cs b/modules/identityserver/test/Volo.Abp.IdentityServer.MongoDB.Tests/Volo/Abp/IdentityServer/ClientRepository_Tests.cs index 29b006cd99..766448daeb 100644 --- a/modules/identityserver/test/Volo.Abp.IdentityServer.MongoDB.Tests/Volo/Abp/IdentityServer/ClientRepository_Tests.cs +++ b/modules/identityserver/test/Volo.Abp.IdentityServer.MongoDB.Tests/Volo/Abp/IdentityServer/ClientRepository_Tests.cs @@ -1,9 +1,8 @@ -using System; -using System.Collections.Generic; -using System.Text; +using Xunit; namespace Volo.Abp.IdentityServer { + [Collection(MongoTestCollection.Name)] public class ClientRepository_Tests : ClientRepository_Tests { diff --git a/modules/identityserver/test/Volo.Abp.IdentityServer.MongoDB.Tests/Volo/Abp/IdentityServer/IdentityResourceRepository_Tests.cs b/modules/identityserver/test/Volo.Abp.IdentityServer.MongoDB.Tests/Volo/Abp/IdentityServer/IdentityResourceRepository_Tests.cs index 2b44b2c6a0..36ca210b36 100644 --- a/modules/identityserver/test/Volo.Abp.IdentityServer.MongoDB.Tests/Volo/Abp/IdentityServer/IdentityResourceRepository_Tests.cs +++ b/modules/identityserver/test/Volo.Abp.IdentityServer.MongoDB.Tests/Volo/Abp/IdentityServer/IdentityResourceRepository_Tests.cs @@ -1,9 +1,8 @@ -using System; -using System.Collections.Generic; -using System.Text; +using Xunit; namespace Volo.Abp.IdentityServer { + [Collection(MongoTestCollection.Name)] public class IdentityResourceRepository_Tests : IdentityResourceRepository_Tests { } diff --git a/modules/identityserver/test/Volo.Abp.IdentityServer.MongoDB.Tests/Volo/Abp/IdentityServer/MongoDbFixture.cs b/modules/identityserver/test/Volo.Abp.IdentityServer.MongoDB.Tests/Volo/Abp/IdentityServer/MongoDbFixture.cs new file mode 100644 index 0000000000..22bbf08ef4 --- /dev/null +++ b/modules/identityserver/test/Volo.Abp.IdentityServer.MongoDB.Tests/Volo/Abp/IdentityServer/MongoDbFixture.cs @@ -0,0 +1,16 @@ +using System; +using Mongo2Go; + +namespace Volo.Abp.IdentityServer +{ + public class MongoDbFixture : IDisposable + { + private static readonly MongoDbRunner MongoDbRunner = MongoDbRunner.Start(); + public static readonly string ConnectionString = MongoDbRunner.ConnectionString; + + public void Dispose() + { + MongoDbRunner?.Dispose(); + } + } +} \ No newline at end of file diff --git a/modules/identityserver/test/Volo.Abp.IdentityServer.MongoDB.Tests/Volo/Abp/IdentityServer/MongoTestCollection.cs b/modules/identityserver/test/Volo.Abp.IdentityServer.MongoDB.Tests/Volo/Abp/IdentityServer/MongoTestCollection.cs new file mode 100644 index 0000000000..8ac0a73624 --- /dev/null +++ b/modules/identityserver/test/Volo.Abp.IdentityServer.MongoDB.Tests/Volo/Abp/IdentityServer/MongoTestCollection.cs @@ -0,0 +1,10 @@ +using Xunit; + +namespace Volo.Abp.IdentityServer +{ + [CollectionDefinition(Name)] + public class MongoTestCollection : ICollectionFixture + { + public const string Name = "MongoDB Collection"; + } +} \ No newline at end of file diff --git a/modules/identityserver/test/Volo.Abp.IdentityServer.MongoDB.Tests/Volo/Abp/IdentityServer/PersistentGrantRepository_Tests.cs b/modules/identityserver/test/Volo.Abp.IdentityServer.MongoDB.Tests/Volo/Abp/IdentityServer/PersistentGrantRepository_Tests.cs index fd2763dc6c..834d18fcf9 100644 --- a/modules/identityserver/test/Volo.Abp.IdentityServer.MongoDB.Tests/Volo/Abp/IdentityServer/PersistentGrantRepository_Tests.cs +++ b/modules/identityserver/test/Volo.Abp.IdentityServer.MongoDB.Tests/Volo/Abp/IdentityServer/PersistentGrantRepository_Tests.cs @@ -1,9 +1,8 @@ -using System; -using System.Collections.Generic; -using System.Text; +using Xunit; namespace Volo.Abp.IdentityServer { + [Collection(MongoTestCollection.Name)] public class PersistentGrantRepository_Tests : PersistentGrantRepository_Tests { From cf995af8bf534a1ee329c620d5623c56a2406f26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mehmet=20Tu=CC=88ken?= Date: Wed, 18 Dec 2019 03:38:33 +0300 Subject: [PATCH 011/334] [modules/permissionmanagement] fix mongo.exe dispose --- .../AbpPermissionManagementMongoDbTestModule.cs | 5 +---- .../MongoDb/MongoDbFixture.cs | 16 ++++++++++++++++ .../MongoDb/MongoTestCollection.cs | 10 ++++++++++ .../MongoDb/PermissionGrantRepository_Tests.cs | 5 ++++- 4 files changed, 31 insertions(+), 5 deletions(-) create mode 100644 modules/permission-management/test/Volo.Abp.PermissionManagement.MongoDB.Tests/Volo/Abp/PermissionManagement/MongoDb/MongoDbFixture.cs create mode 100644 modules/permission-management/test/Volo.Abp.PermissionManagement.MongoDB.Tests/Volo/Abp/PermissionManagement/MongoDb/MongoTestCollection.cs diff --git a/modules/permission-management/test/Volo.Abp.PermissionManagement.MongoDB.Tests/Volo/Abp/PermissionManagement/MongoDb/AbpPermissionManagementMongoDbTestModule.cs b/modules/permission-management/test/Volo.Abp.PermissionManagement.MongoDB.Tests/Volo/Abp/PermissionManagement/MongoDb/AbpPermissionManagementMongoDbTestModule.cs index d3d4d5d6e9..8e3c7b2c22 100644 --- a/modules/permission-management/test/Volo.Abp.PermissionManagement.MongoDB.Tests/Volo/Abp/PermissionManagement/MongoDb/AbpPermissionManagementMongoDbTestModule.cs +++ b/modules/permission-management/test/Volo.Abp.PermissionManagement.MongoDB.Tests/Volo/Abp/PermissionManagement/MongoDb/AbpPermissionManagementMongoDbTestModule.cs @@ -1,5 +1,4 @@ using System; -using Mongo2Go; using Volo.Abp.Data; using Volo.Abp.Modularity; @@ -10,11 +9,9 @@ namespace Volo.Abp.PermissionManagement.MongoDB typeof(AbpPermissionManagementTestBaseModule))] public class AbpPermissionManagementMongoDbTestModule : AbpModule { - private static readonly MongoDbRunner MongoDbRunner = MongoDbRunner.Start(); - public override void ConfigureServices(ServiceConfigurationContext context) { - var connectionString = MongoDbRunner.ConnectionString.EnsureEndsWith('/') + + var connectionString = MongoDbFixture.ConnectionString.EnsureEndsWith('/') + "Db_" + Guid.NewGuid().ToString("N"); diff --git a/modules/permission-management/test/Volo.Abp.PermissionManagement.MongoDB.Tests/Volo/Abp/PermissionManagement/MongoDb/MongoDbFixture.cs b/modules/permission-management/test/Volo.Abp.PermissionManagement.MongoDB.Tests/Volo/Abp/PermissionManagement/MongoDb/MongoDbFixture.cs new file mode 100644 index 0000000000..3a09e6e1a4 --- /dev/null +++ b/modules/permission-management/test/Volo.Abp.PermissionManagement.MongoDB.Tests/Volo/Abp/PermissionManagement/MongoDb/MongoDbFixture.cs @@ -0,0 +1,16 @@ +using System; +using Mongo2Go; + +namespace Volo.Abp.PermissionManagement.MongoDB +{ + public class MongoDbFixture : IDisposable + { + private static readonly MongoDbRunner MongoDbRunner = MongoDbRunner.Start(); + public static readonly string ConnectionString = MongoDbRunner.ConnectionString; + + public void Dispose() + { + MongoDbRunner?.Dispose(); + } + } +} \ No newline at end of file diff --git a/modules/permission-management/test/Volo.Abp.PermissionManagement.MongoDB.Tests/Volo/Abp/PermissionManagement/MongoDb/MongoTestCollection.cs b/modules/permission-management/test/Volo.Abp.PermissionManagement.MongoDB.Tests/Volo/Abp/PermissionManagement/MongoDb/MongoTestCollection.cs new file mode 100644 index 0000000000..a1f2eb6558 --- /dev/null +++ b/modules/permission-management/test/Volo.Abp.PermissionManagement.MongoDB.Tests/Volo/Abp/PermissionManagement/MongoDb/MongoTestCollection.cs @@ -0,0 +1,10 @@ +using Xunit; + +namespace Volo.Abp.PermissionManagement.MongoDB +{ + [CollectionDefinition(Name)] + public class MongoTestCollection : ICollectionFixture + { + public const string Name = "MongoDB Collection"; + } +} \ No newline at end of file diff --git a/modules/permission-management/test/Volo.Abp.PermissionManagement.MongoDB.Tests/Volo/Abp/PermissionManagement/MongoDb/PermissionGrantRepository_Tests.cs b/modules/permission-management/test/Volo.Abp.PermissionManagement.MongoDB.Tests/Volo/Abp/PermissionManagement/MongoDb/PermissionGrantRepository_Tests.cs index 98db0640c5..dd3c42da15 100644 --- a/modules/permission-management/test/Volo.Abp.PermissionManagement.MongoDB.Tests/Volo/Abp/PermissionManagement/MongoDb/PermissionGrantRepository_Tests.cs +++ b/modules/permission-management/test/Volo.Abp.PermissionManagement.MongoDB.Tests/Volo/Abp/PermissionManagement/MongoDb/PermissionGrantRepository_Tests.cs @@ -1,5 +1,8 @@ -namespace Volo.Abp.PermissionManagement.MongoDB +using Xunit; + +namespace Volo.Abp.PermissionManagement.MongoDB { + [Collection(MongoTestCollection.Name)] public class PermissionGrantRepository_Tests : PermissionGrantRepository_Tests { From be9b73b83528a3e19964bae8940b2226d8092280 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mehmet=20Tu=CC=88ken?= Date: Wed, 18 Dec 2019 03:42:34 +0300 Subject: [PATCH 012/334] [modules/settingmanagement] fix mongo.exe dispose --- .../AbpSettingManagementMongoDbTestModule.cs | 5 +---- .../SettingManagement/MongoDB/MongoDbFixture.cs | 16 ++++++++++++++++ .../MongoDB/MongoTestCollection.cs | 10 ++++++++++ .../MongoDB/SettingRepository_Tests.cs | 5 ++++- 4 files changed, 31 insertions(+), 5 deletions(-) create mode 100644 modules/setting-management/test/Volo.Abp.SettingManagement.MongoDB.Tests/Volo/Abp/SettingManagement/MongoDB/MongoDbFixture.cs create mode 100644 modules/setting-management/test/Volo.Abp.SettingManagement.MongoDB.Tests/Volo/Abp/SettingManagement/MongoDB/MongoTestCollection.cs diff --git a/modules/setting-management/test/Volo.Abp.SettingManagement.MongoDB.Tests/Volo/Abp/SettingManagement/MongoDB/AbpSettingManagementMongoDbTestModule.cs b/modules/setting-management/test/Volo.Abp.SettingManagement.MongoDB.Tests/Volo/Abp/SettingManagement/MongoDB/AbpSettingManagementMongoDbTestModule.cs index 1b9faefdbd..ec221eba15 100644 --- a/modules/setting-management/test/Volo.Abp.SettingManagement.MongoDB.Tests/Volo/Abp/SettingManagement/MongoDB/AbpSettingManagementMongoDbTestModule.cs +++ b/modules/setting-management/test/Volo.Abp.SettingManagement.MongoDB.Tests/Volo/Abp/SettingManagement/MongoDB/AbpSettingManagementMongoDbTestModule.cs @@ -1,5 +1,4 @@ using System; -using Mongo2Go; using Volo.Abp.Data; using Volo.Abp.Modularity; @@ -11,11 +10,9 @@ namespace Volo.Abp.SettingManagement.MongoDB )] public class AbpSettingManagementMongoDbTestModule : AbpModule { - private static readonly MongoDbRunner MongoDbRunner = MongoDbRunner.Start(); - public override void ConfigureServices(ServiceConfigurationContext context) { - var connectionString = MongoDbRunner.ConnectionString.EnsureEndsWith('/') + + var connectionString = MongoDbFixture.ConnectionString.EnsureEndsWith('/') + "Db_" + Guid.NewGuid().ToString("N"); diff --git a/modules/setting-management/test/Volo.Abp.SettingManagement.MongoDB.Tests/Volo/Abp/SettingManagement/MongoDB/MongoDbFixture.cs b/modules/setting-management/test/Volo.Abp.SettingManagement.MongoDB.Tests/Volo/Abp/SettingManagement/MongoDB/MongoDbFixture.cs new file mode 100644 index 0000000000..31ccdcc4f7 --- /dev/null +++ b/modules/setting-management/test/Volo.Abp.SettingManagement.MongoDB.Tests/Volo/Abp/SettingManagement/MongoDB/MongoDbFixture.cs @@ -0,0 +1,16 @@ +using System; +using Mongo2Go; + +namespace Volo.Abp.SettingManagement.MongoDB +{ + public class MongoDbFixture : IDisposable + { + private static readonly MongoDbRunner MongoDbRunner = MongoDbRunner.Start(); + public static readonly string ConnectionString = MongoDbRunner.ConnectionString; + + public void Dispose() + { + MongoDbRunner?.Dispose(); + } + } +} \ No newline at end of file diff --git a/modules/setting-management/test/Volo.Abp.SettingManagement.MongoDB.Tests/Volo/Abp/SettingManagement/MongoDB/MongoTestCollection.cs b/modules/setting-management/test/Volo.Abp.SettingManagement.MongoDB.Tests/Volo/Abp/SettingManagement/MongoDB/MongoTestCollection.cs new file mode 100644 index 0000000000..11ed1cbb55 --- /dev/null +++ b/modules/setting-management/test/Volo.Abp.SettingManagement.MongoDB.Tests/Volo/Abp/SettingManagement/MongoDB/MongoTestCollection.cs @@ -0,0 +1,10 @@ +using Xunit; + +namespace Volo.Abp.SettingManagement.MongoDB +{ + [CollectionDefinition(Name)] + public class MongoTestCollection : ICollectionFixture + { + public const string Name = "MongoDB Collection"; + } +} \ No newline at end of file diff --git a/modules/setting-management/test/Volo.Abp.SettingManagement.MongoDB.Tests/Volo/Abp/SettingManagement/MongoDB/SettingRepository_Tests.cs b/modules/setting-management/test/Volo.Abp.SettingManagement.MongoDB.Tests/Volo/Abp/SettingManagement/MongoDB/SettingRepository_Tests.cs index 7e35eff799..a1a2d1428c 100644 --- a/modules/setting-management/test/Volo.Abp.SettingManagement.MongoDB.Tests/Volo/Abp/SettingManagement/MongoDB/SettingRepository_Tests.cs +++ b/modules/setting-management/test/Volo.Abp.SettingManagement.MongoDB.Tests/Volo/Abp/SettingManagement/MongoDB/SettingRepository_Tests.cs @@ -1,5 +1,8 @@ -namespace Volo.Abp.SettingManagement.MongoDB +using Xunit; + +namespace Volo.Abp.SettingManagement.MongoDB { + [Collection(MongoTestCollection.Name)] public class SettingRepository_Tests : SettingRepository_Tests { From 7fa2dbc886bf93b0e303f9257fd1766924749eb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mehmet=20Tu=CC=88ken?= Date: Wed, 18 Dec 2019 03:45:39 +0300 Subject: [PATCH 013/334] [modules/tenantmanagement] fix mongo.exe dispose --- .../AbpTenantManagementMongoDbTestModule.cs | 6 +----- .../TenantManagement/MongoDb/MongoDbFixture.cs | 16 ++++++++++++++++ .../MongoDb/MongoTestCollection.cs | 10 ++++++++++ .../MongoDb/TenantRepository_Tests.cs | 5 ++++- 4 files changed, 31 insertions(+), 6 deletions(-) create mode 100644 modules/tenant-management/test/Volo.Abp.TenantManagement.MongoDB.Tests/Volo/Abp/TenantManagement/MongoDb/MongoDbFixture.cs create mode 100644 modules/tenant-management/test/Volo.Abp.TenantManagement.MongoDB.Tests/Volo/Abp/TenantManagement/MongoDb/MongoTestCollection.cs diff --git a/modules/tenant-management/test/Volo.Abp.TenantManagement.MongoDB.Tests/Volo/Abp/TenantManagement/MongoDb/AbpTenantManagementMongoDbTestModule.cs b/modules/tenant-management/test/Volo.Abp.TenantManagement.MongoDB.Tests/Volo/Abp/TenantManagement/MongoDb/AbpTenantManagementMongoDbTestModule.cs index 911839d510..9584ec2d44 100644 --- a/modules/tenant-management/test/Volo.Abp.TenantManagement.MongoDB.Tests/Volo/Abp/TenantManagement/MongoDb/AbpTenantManagementMongoDbTestModule.cs +++ b/modules/tenant-management/test/Volo.Abp.TenantManagement.MongoDB.Tests/Volo/Abp/TenantManagement/MongoDb/AbpTenantManagementMongoDbTestModule.cs @@ -1,6 +1,4 @@ using System; -using Microsoft.Extensions.DependencyInjection; -using Mongo2Go; using Volo.Abp.Data; using Volo.Abp.Modularity; @@ -12,11 +10,9 @@ namespace Volo.Abp.TenantManagement.MongoDB )] public class AbpTenantManagementMongoDbTestModule : AbpModule { - private static readonly MongoDbRunner MongoDbRunner = MongoDbRunner.Start(); - public override void ConfigureServices(ServiceConfigurationContext context) { - var connectionString = MongoDbRunner.ConnectionString.EnsureEndsWith('/') + + var connectionString = MongoDbFixture.ConnectionString.EnsureEndsWith('/') + "Db_" + Guid.NewGuid().ToString("N"); diff --git a/modules/tenant-management/test/Volo.Abp.TenantManagement.MongoDB.Tests/Volo/Abp/TenantManagement/MongoDb/MongoDbFixture.cs b/modules/tenant-management/test/Volo.Abp.TenantManagement.MongoDB.Tests/Volo/Abp/TenantManagement/MongoDb/MongoDbFixture.cs new file mode 100644 index 0000000000..be115d9dff --- /dev/null +++ b/modules/tenant-management/test/Volo.Abp.TenantManagement.MongoDB.Tests/Volo/Abp/TenantManagement/MongoDb/MongoDbFixture.cs @@ -0,0 +1,16 @@ +using System; +using Mongo2Go; + +namespace Volo.Abp.TenantManagement.MongoDB +{ + public class MongoDbFixture : IDisposable + { + private static readonly MongoDbRunner MongoDbRunner = MongoDbRunner.Start(); + public static readonly string ConnectionString = MongoDbRunner.ConnectionString; + + public void Dispose() + { + MongoDbRunner?.Dispose(); + } + } +} \ No newline at end of file diff --git a/modules/tenant-management/test/Volo.Abp.TenantManagement.MongoDB.Tests/Volo/Abp/TenantManagement/MongoDb/MongoTestCollection.cs b/modules/tenant-management/test/Volo.Abp.TenantManagement.MongoDB.Tests/Volo/Abp/TenantManagement/MongoDb/MongoTestCollection.cs new file mode 100644 index 0000000000..1719b7dbdd --- /dev/null +++ b/modules/tenant-management/test/Volo.Abp.TenantManagement.MongoDB.Tests/Volo/Abp/TenantManagement/MongoDb/MongoTestCollection.cs @@ -0,0 +1,10 @@ +using Xunit; + +namespace Volo.Abp.TenantManagement.MongoDB +{ + [CollectionDefinition(Name)] + public class MongoTestCollection : ICollectionFixture + { + public const string Name = "MongoDB Collection"; + } +} \ No newline at end of file diff --git a/modules/tenant-management/test/Volo.Abp.TenantManagement.MongoDB.Tests/Volo/Abp/TenantManagement/MongoDb/TenantRepository_Tests.cs b/modules/tenant-management/test/Volo.Abp.TenantManagement.MongoDB.Tests/Volo/Abp/TenantManagement/MongoDb/TenantRepository_Tests.cs index b1ae97b021..0a980be37d 100644 --- a/modules/tenant-management/test/Volo.Abp.TenantManagement.MongoDB.Tests/Volo/Abp/TenantManagement/MongoDb/TenantRepository_Tests.cs +++ b/modules/tenant-management/test/Volo.Abp.TenantManagement.MongoDB.Tests/Volo/Abp/TenantManagement/MongoDb/TenantRepository_Tests.cs @@ -1,5 +1,8 @@ -namespace Volo.Abp.TenantManagement.MongoDB +using Xunit; + +namespace Volo.Abp.TenantManagement.MongoDB { + [Collection(MongoTestCollection.Name)] public class TenantRepository_Tests : TenantRepository_Tests { From 6f0db0b9b0a7d3734f72d1e79adffe710901d150 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mehmet=20Tu=CC=88ken?= Date: Wed, 18 Dec 2019 03:58:14 +0300 Subject: [PATCH 014/334] [templates/app] fix mongo.exe dispose --- .../MongoDb/MongoDbFixture.cs | 16 ++++++++++++++++ .../MongoDb/MongoTestCollection.cs | 10 ++++++++++ .../MongoDb/MyProjectNameMongoDbTestModule.cs | 5 +---- .../MongoDb/Samples/SampleRepositoryTests.cs | 1 + 4 files changed, 28 insertions(+), 4 deletions(-) create mode 100644 templates/app/aspnet-core/test/MyCompanyName.MyProjectName.MongoDB.Tests/MongoDb/MongoDbFixture.cs create mode 100644 templates/app/aspnet-core/test/MyCompanyName.MyProjectName.MongoDB.Tests/MongoDb/MongoTestCollection.cs diff --git a/templates/app/aspnet-core/test/MyCompanyName.MyProjectName.MongoDB.Tests/MongoDb/MongoDbFixture.cs b/templates/app/aspnet-core/test/MyCompanyName.MyProjectName.MongoDB.Tests/MongoDb/MongoDbFixture.cs new file mode 100644 index 0000000000..0feac4eebf --- /dev/null +++ b/templates/app/aspnet-core/test/MyCompanyName.MyProjectName.MongoDB.Tests/MongoDb/MongoDbFixture.cs @@ -0,0 +1,16 @@ +using System; +using Mongo2Go; + +namespace MyCompanyName.MyProjectName.MongoDB +{ + public class MongoDbFixture : IDisposable + { + private static readonly MongoDbRunner MongoDbRunner = MongoDbRunner.Start(); + public static readonly string ConnectionString = MongoDbRunner.ConnectionString; + + public void Dispose() + { + MongoDbRunner?.Dispose(); + } + } +} \ No newline at end of file diff --git a/templates/app/aspnet-core/test/MyCompanyName.MyProjectName.MongoDB.Tests/MongoDb/MongoTestCollection.cs b/templates/app/aspnet-core/test/MyCompanyName.MyProjectName.MongoDB.Tests/MongoDb/MongoTestCollection.cs new file mode 100644 index 0000000000..42c85760c3 --- /dev/null +++ b/templates/app/aspnet-core/test/MyCompanyName.MyProjectName.MongoDB.Tests/MongoDb/MongoTestCollection.cs @@ -0,0 +1,10 @@ +using Xunit; + +namespace MyCompanyName.MyProjectName.MongoDB +{ + [CollectionDefinition(Name)] + public class MongoTestCollection : ICollectionFixture + { + public const string Name = "MongoDB Collection"; + } +} \ No newline at end of file diff --git a/templates/app/aspnet-core/test/MyCompanyName.MyProjectName.MongoDB.Tests/MongoDb/MyProjectNameMongoDbTestModule.cs b/templates/app/aspnet-core/test/MyCompanyName.MyProjectName.MongoDB.Tests/MongoDb/MyProjectNameMongoDbTestModule.cs index 270ad2102c..bcaf7494a7 100644 --- a/templates/app/aspnet-core/test/MyCompanyName.MyProjectName.MongoDB.Tests/MongoDb/MyProjectNameMongoDbTestModule.cs +++ b/templates/app/aspnet-core/test/MyCompanyName.MyProjectName.MongoDB.Tests/MongoDb/MyProjectNameMongoDbTestModule.cs @@ -1,5 +1,4 @@ using System; -using Mongo2Go; using Volo.Abp.Data; using Volo.Abp.Modularity; @@ -11,11 +10,9 @@ namespace MyCompanyName.MyProjectName.MongoDB )] public class MyProjectNameMongoDbTestModule : AbpModule { - private static readonly MongoDbRunner MongoDbRunner = MongoDbRunner.Start(); - public override void ConfigureServices(ServiceConfigurationContext context) { - var connectionString = MongoDbRunner.ConnectionString.EnsureEndsWith('/') + + var connectionString = MongoDbFixture.ConnectionString.EnsureEndsWith('/') + "Db_" + Guid.NewGuid().ToString("N"); diff --git a/templates/app/aspnet-core/test/MyCompanyName.MyProjectName.MongoDB.Tests/MongoDb/Samples/SampleRepositoryTests.cs b/templates/app/aspnet-core/test/MyCompanyName.MyProjectName.MongoDB.Tests/MongoDb/Samples/SampleRepositoryTests.cs index 27095ec117..17d8007c16 100644 --- a/templates/app/aspnet-core/test/MyCompanyName.MyProjectName.MongoDB.Tests/MongoDb/Samples/SampleRepositoryTests.cs +++ b/templates/app/aspnet-core/test/MyCompanyName.MyProjectName.MongoDB.Tests/MongoDb/Samples/SampleRepositoryTests.cs @@ -13,6 +13,7 @@ namespace MyCompanyName.MyProjectName.MongoDB.Samples * (like default AppUser repository IRepository here). * Only test your custom repository methods. */ + [Collection(MongoTestCollection.Name)] public class SampleRepositoryTests : MyProjectNameMongoDbTestBase { private readonly IRepository _appUserRepository; From e44efcb803659f07001b648afe8c58334581e84f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mehmet=20Tu=CC=88ken?= Date: Wed, 18 Dec 2019 04:01:55 +0300 Subject: [PATCH 015/334] [templates/module] fix mongo.exe dispose --- .../MongoDB/MongoDbFixture.cs | 16 ++++++++++++++++ .../MongoDB/MongoTestCollection.cs | 10 ++++++++++ .../MongoDB/MyProjectNameMongoDbTestModule.cs | 6 +----- .../MongoDB/Samples/SampleRepository_Tests.cs | 2 ++ 4 files changed, 29 insertions(+), 5 deletions(-) create mode 100644 templates/module/aspnet-core/test/MyCompanyName.MyProjectName.MongoDB.Tests/MongoDB/MongoDbFixture.cs create mode 100644 templates/module/aspnet-core/test/MyCompanyName.MyProjectName.MongoDB.Tests/MongoDB/MongoTestCollection.cs diff --git a/templates/module/aspnet-core/test/MyCompanyName.MyProjectName.MongoDB.Tests/MongoDB/MongoDbFixture.cs b/templates/module/aspnet-core/test/MyCompanyName.MyProjectName.MongoDB.Tests/MongoDB/MongoDbFixture.cs new file mode 100644 index 0000000000..0feac4eebf --- /dev/null +++ b/templates/module/aspnet-core/test/MyCompanyName.MyProjectName.MongoDB.Tests/MongoDB/MongoDbFixture.cs @@ -0,0 +1,16 @@ +using System; +using Mongo2Go; + +namespace MyCompanyName.MyProjectName.MongoDB +{ + public class MongoDbFixture : IDisposable + { + private static readonly MongoDbRunner MongoDbRunner = MongoDbRunner.Start(); + public static readonly string ConnectionString = MongoDbRunner.ConnectionString; + + public void Dispose() + { + MongoDbRunner?.Dispose(); + } + } +} \ No newline at end of file diff --git a/templates/module/aspnet-core/test/MyCompanyName.MyProjectName.MongoDB.Tests/MongoDB/MongoTestCollection.cs b/templates/module/aspnet-core/test/MyCompanyName.MyProjectName.MongoDB.Tests/MongoDB/MongoTestCollection.cs new file mode 100644 index 0000000000..42c85760c3 --- /dev/null +++ b/templates/module/aspnet-core/test/MyCompanyName.MyProjectName.MongoDB.Tests/MongoDB/MongoTestCollection.cs @@ -0,0 +1,10 @@ +using Xunit; + +namespace MyCompanyName.MyProjectName.MongoDB +{ + [CollectionDefinition(Name)] + public class MongoTestCollection : ICollectionFixture + { + public const string Name = "MongoDB Collection"; + } +} \ No newline at end of file diff --git a/templates/module/aspnet-core/test/MyCompanyName.MyProjectName.MongoDB.Tests/MongoDB/MyProjectNameMongoDbTestModule.cs b/templates/module/aspnet-core/test/MyCompanyName.MyProjectName.MongoDB.Tests/MongoDB/MyProjectNameMongoDbTestModule.cs index 149db59bcc..f29c713c05 100644 --- a/templates/module/aspnet-core/test/MyCompanyName.MyProjectName.MongoDB.Tests/MongoDB/MyProjectNameMongoDbTestModule.cs +++ b/templates/module/aspnet-core/test/MyCompanyName.MyProjectName.MongoDB.Tests/MongoDB/MyProjectNameMongoDbTestModule.cs @@ -1,6 +1,4 @@ using System; -using Mongo2Go; -using Volo.Abp; using Volo.Abp.Data; using Volo.Abp.Modularity; @@ -12,11 +10,9 @@ namespace MyCompanyName.MyProjectName.MongoDB )] public class MyProjectNameMongoDbTestModule : AbpModule { - private static readonly MongoDbRunner MongoDbRunner = MongoDbRunner.Start(); - public override void ConfigureServices(ServiceConfigurationContext context) { - var connectionString = MongoDbRunner.ConnectionString.EnsureEndsWith('/') + + var connectionString = MongoDbFixture.ConnectionString.EnsureEndsWith('/') + "Db_" + Guid.NewGuid().ToString("N"); diff --git a/templates/module/aspnet-core/test/MyCompanyName.MyProjectName.MongoDB.Tests/MongoDB/Samples/SampleRepository_Tests.cs b/templates/module/aspnet-core/test/MyCompanyName.MyProjectName.MongoDB.Tests/MongoDB/Samples/SampleRepository_Tests.cs index 6522b9884e..c16c416b2c 100644 --- a/templates/module/aspnet-core/test/MyCompanyName.MyProjectName.MongoDB.Tests/MongoDB/Samples/SampleRepository_Tests.cs +++ b/templates/module/aspnet-core/test/MyCompanyName.MyProjectName.MongoDB.Tests/MongoDB/Samples/SampleRepository_Tests.cs @@ -1,7 +1,9 @@ using MyCompanyName.MyProjectName.Samples; +using Xunit; namespace MyCompanyName.MyProjectName.MongoDB.Samples { + [Collection(MongoTestCollection.Name)] public class SampleRepository_Tests : SampleRepository_Tests { /* Don't write custom repository tests here, instead write to From 623c5915c76d62230f70a5fae62b067416218164 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mehmet=20Tu=CC=88ken?= Date: Sat, 28 Dec 2019 01:30:28 +0300 Subject: [PATCH 016/334] Revert "Delete main.yml" This reverts commit a04fbeb1b52fa5e4d16880e58f78152b596e39c6. --- .github/workflows/main.yml | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 .github/workflows/main.yml diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 0000000000..123cc3ea62 --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,24 @@ +name: 'Main' +on: + pull_request: + paths: + - 'framework/**' + - 'modules/**' + branches: + - dev +jobs: + build-test: + runs-on: windows-latest + steps: + - uses: actions/checkout@v1 + - uses: actions/setup-dotnet@master + with: + dotnet-version: '3.0.100' + + - name: Build All + run: .\build-all.ps1 + shell: pwsh + + - name: Test All + run: .\test-all.ps1 + shell: pwsh From 505cd17467c006acfe835ae46545159245d2e8f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mehmet=20Tu=CC=88ken?= Date: Sat, 28 Dec 2019 01:31:10 +0300 Subject: [PATCH 017/334] ci check all push and pr --- .github/workflows/main.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 123cc3ea62..d2412d0b08 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -4,8 +4,12 @@ on: paths: - 'framework/**' - 'modules/**' - branches: - - dev + - 'templates/**' + push: + paths: + - 'framework/**' + - 'modules/**' + - 'templates/**' jobs: build-test: runs-on: windows-latest From c30c4aa603306fc8c857dec92af0dde9341e9c46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mehmet=20Tu=CC=88ken?= Date: Sat, 28 Dec 2019 06:59:10 +0300 Subject: [PATCH 018/334] update dotnet version --- .github/workflows/main.yml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index d2412d0b08..a75e3f2cf5 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,15 +1,15 @@ -name: 'Main' +name: "Main" on: pull_request: paths: - - 'framework/**' - - 'modules/**' - - 'templates/**' + - "framework/**" + - "modules/**" + - "templates/**" push: paths: - - 'framework/**' - - 'modules/**' - - 'templates/**' + - "framework/**" + - "modules/**" + - "templates/**" jobs: build-test: runs-on: windows-latest @@ -17,8 +17,8 @@ jobs: - uses: actions/checkout@v1 - uses: actions/setup-dotnet@master with: - dotnet-version: '3.0.100' - + dotnet-version: "3.1.100" + - name: Build All run: .\build-all.ps1 shell: pwsh From c0d6582986007fb20a9fbce5fb3f1c97a1ee8592 Mon Sep 17 00:00:00 2001 From: Mehmet Perk Date: Thu, 16 Jan 2020 22:35:07 +0300 Subject: [PATCH 019/334] MethodInvocationAuthorizationService should check Roles --- .../MethodInvocationAuthorizationService.cs | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/MethodInvocationAuthorizationService.cs b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/MethodInvocationAuthorizationService.cs index 1e063f1f0e..82a0f9c2d1 100644 --- a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/MethodInvocationAuthorizationService.cs +++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/MethodInvocationAuthorizationService.cs @@ -64,20 +64,26 @@ namespace Volo.Abp.Authorization protected async Task CheckAsync(IAuthorizeData authorizationAttribute) { - if (authorizationAttribute.Policy == null) + if (authorizationAttribute.Policy != null) { - //TODO: Can we find a better, unified, way of checking if current request has been authenticated - if (!_currentUser.IsAuthenticated && !_currentClient.IsAuthenticated) + await _authorizationService.CheckAsync(authorizationAttribute.Policy).ConfigureAwait(false); + } + else if (authorizationAttribute.Roles != null) + { + if(_currentUser.IsInRole(authorizationAttribute.Roles) == false) { - throw new AbpAuthorizationException("Authorization failed! User has not logged in."); + throw new AbpAuthorizationException("Authorization failed! Given roles has not granted: " + authorizationAttribute.Roles); } } else { - await _authorizationService.CheckAsync(authorizationAttribute.Policy).ConfigureAwait(false); + //TODO: Can we find a better, unified, way of checking if current request has been authenticated + if (!_currentUser.IsAuthenticated && !_currentClient.IsAuthenticated) + { + throw new AbpAuthorizationException("Authorization failed! User has not logged in."); + } } - //TODO: What about roles and other props? } } } \ No newline at end of file From 5016ba69a3cfc4e87e9db5fe651325cafcacc766 Mon Sep 17 00:00:00 2001 From: Mehmet Perk Date: Thu, 16 Jan 2020 23:33:05 +0300 Subject: [PATCH 020/334] authorization tests with role --- .../Volo/Abp/Authorization/Authorization_Tests.cs | 9 +++++++++ .../Authorization/TestServices/IMyAuthorizedService1.cs | 2 ++ .../Authorization/TestServices/MyAuthorizedService1.cs | 6 ++++++ 3 files changed, 17 insertions(+) diff --git a/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/Authorization_Tests.cs b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/Authorization_Tests.cs index 2950c7c92a..3968d1baf5 100644 --- a/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/Authorization_Tests.cs +++ b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/Authorization_Tests.cs @@ -52,5 +52,14 @@ namespace Volo.Abp.Authorization { _permissionDefinitionManager.GetGroups().Count.ShouldBe(1); } + + [Fact] + public async Task Should_Not_Allow_To_Call_Method_If_Has_No_Role_ProtectedByRole_Async() + { + await Assert.ThrowsAsync(async () => + { + await _myAuthorizedService1.ProtectedByRole().ConfigureAwait(false); + }).ConfigureAwait(false); + } } } \ No newline at end of file diff --git a/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/IMyAuthorizedService1.cs b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/IMyAuthorizedService1.cs index b3841c4fed..077934c0d2 100644 --- a/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/IMyAuthorizedService1.cs +++ b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/IMyAuthorizedService1.cs @@ -11,5 +11,7 @@ namespace Volo.Abp.Authorization.TestServices Task ProtectedByClass(); Task ProtectedByClassAsync(); + + Task ProtectedByRole(); } } \ No newline at end of file diff --git a/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/MyAuthorizedService1.cs b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/MyAuthorizedService1.cs index 6d64ed80dd..07ccfa7deb 100644 --- a/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/MyAuthorizedService1.cs +++ b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/MyAuthorizedService1.cs @@ -30,5 +30,11 @@ namespace Volo.Abp.Authorization.TestServices await Task.Delay(10).ConfigureAwait(false); return 42; } + + [Authorize(Roles = "MyRole")] + public virtual Task ProtectedByRole() + { + return Task.FromResult(42); + } } } \ No newline at end of file From 85f956f5aed8b50f5949fcd9ac325607f8a23d4d Mon Sep 17 00:00:00 2001 From: mperk Date: Sun, 19 Jan 2020 01:03:21 +0300 Subject: [PATCH 021/334] authorize check with combine --- .../MethodInvocationAuthorizationService.cs | 29 +++++-------------- .../Abp/Authorization/Authorization_Tests.cs | 16 ++++++++++ .../TestServices/IMyAuthorizedService1.cs | 2 ++ .../TestServices/MyAuthorizedService1.cs | 7 +++++ 4 files changed, 33 insertions(+), 21 deletions(-) diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/MethodInvocationAuthorizationService.cs b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/MethodInvocationAuthorizationService.cs index 82a0f9c2d1..b2e06c0207 100644 --- a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/MethodInvocationAuthorizationService.cs +++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/MethodInvocationAuthorizationService.cs @@ -14,15 +14,18 @@ namespace Volo.Abp.Authorization private readonly IAuthorizationService _authorizationService; private readonly ICurrentUser _currentUser; private readonly ICurrentClient _currentClient; + private readonly IAbpAuthorizationPolicyProvider _abpAuthorizationPolicyProvider; public MethodInvocationAuthorizationService( IAuthorizationService authorizationService, ICurrentUser currentUser, - ICurrentClient currentClient) + ICurrentClient currentClient, + IAbpAuthorizationPolicyProvider abpAuthorizationPolicyProvider) { _authorizationService = authorizationService; _currentUser = currentUser; _currentClient = currentClient; + _abpAuthorizationPolicyProvider = abpAuthorizationPolicyProvider; } public async Task CheckAsync(MethodInvocationAuthorizationContext context) @@ -64,26 +67,10 @@ namespace Volo.Abp.Authorization protected async Task CheckAsync(IAuthorizeData authorizationAttribute) { - if (authorizationAttribute.Policy != null) - { - await _authorizationService.CheckAsync(authorizationAttribute.Policy).ConfigureAwait(false); - } - else if (authorizationAttribute.Roles != null) - { - if(_currentUser.IsInRole(authorizationAttribute.Roles) == false) - { - throw new AbpAuthorizationException("Authorization failed! Given roles has not granted: " + authorizationAttribute.Roles); - } - } - else - { - //TODO: Can we find a better, unified, way of checking if current request has been authenticated - if (!_currentUser.IsAuthenticated && !_currentClient.IsAuthenticated) - { - throw new AbpAuthorizationException("Authorization failed! User has not logged in."); - } - } - + var authorizationPolicy = await AuthorizationPolicy.CombineAsync( + _abpAuthorizationPolicyProvider, + new List { authorizationAttribute }); + await _authorizationService.CheckAsync(authorizationPolicy).ConfigureAwait(false); } } } \ No newline at end of file diff --git a/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/Authorization_Tests.cs b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/Authorization_Tests.cs index 3968d1baf5..827f7b676e 100644 --- a/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/Authorization_Tests.cs +++ b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/Authorization_Tests.cs @@ -61,5 +61,21 @@ namespace Volo.Abp.Authorization await _myAuthorizedService1.ProtectedByRole().ConfigureAwait(false); }).ConfigureAwait(false); } + + [Fact] + public async Task Should_Allow_To_Call_Method_If_Has_No_Role_ProtectedByRole_Async() + { + int result = await _myAuthorizedService1.ProtectedByRole().ConfigureAwait(false); + result.ShouldBe(42); + } + + [Fact] + public async Task Should_Not_Allow_To_Call_Method_If_Has_No_Role_ProtectedByScheme_Async() + { + await Assert.ThrowsAsync(async () => + { + await _myAuthorizedService1.ProtectedByScheme().ConfigureAwait(false); + }).ConfigureAwait(false); + } } } \ No newline at end of file diff --git a/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/IMyAuthorizedService1.cs b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/IMyAuthorizedService1.cs index 077934c0d2..6c4042168c 100644 --- a/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/IMyAuthorizedService1.cs +++ b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/IMyAuthorizedService1.cs @@ -13,5 +13,7 @@ namespace Volo.Abp.Authorization.TestServices Task ProtectedByClassAsync(); Task ProtectedByRole(); + + Task ProtectedByScheme(); } } \ No newline at end of file diff --git a/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/MyAuthorizedService1.cs b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/MyAuthorizedService1.cs index 07ccfa7deb..a25227babf 100644 --- a/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/MyAuthorizedService1.cs +++ b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/MyAuthorizedService1.cs @@ -36,5 +36,12 @@ namespace Volo.Abp.Authorization.TestServices { return Task.FromResult(42); } + + [Authorize(AuthenticationSchemes = "Bearer")] + [Authorize(Roles = "MyRole")] + public virtual Task ProtectedByScheme() + { + return Task.FromResult(42); + } } } \ No newline at end of file From 9617efc5e977c1894aeff00f423643a53d0fda90 Mon Sep 17 00:00:00 2001 From: mperk Date: Mon, 20 Jan 2020 15:07:39 +0300 Subject: [PATCH 022/334] change authorization service to abpauthorization service --- .../MethodInvocationAuthorizationService.cs | 16 +++++----------- .../Abp/Authorization/Authorization_Tests.cs | 7 ------- 2 files changed, 5 insertions(+), 18 deletions(-) diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/MethodInvocationAuthorizationService.cs b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/MethodInvocationAuthorizationService.cs index b2e06c0207..4d0589486b 100644 --- a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/MethodInvocationAuthorizationService.cs +++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/MethodInvocationAuthorizationService.cs @@ -11,21 +11,15 @@ namespace Volo.Abp.Authorization { public class MethodInvocationAuthorizationService : IMethodInvocationAuthorizationService, ITransientDependency { - private readonly IAuthorizationService _authorizationService; - private readonly ICurrentUser _currentUser; - private readonly ICurrentClient _currentClient; private readonly IAbpAuthorizationPolicyProvider _abpAuthorizationPolicyProvider; + private readonly IAbpAuthorizationService _abpAuthorizationService; public MethodInvocationAuthorizationService( - IAuthorizationService authorizationService, - ICurrentUser currentUser, - ICurrentClient currentClient, - IAbpAuthorizationPolicyProvider abpAuthorizationPolicyProvider) + IAbpAuthorizationPolicyProvider abpAuthorizationPolicyProvider, + IAbpAuthorizationService abpAuthorizationService) { - _authorizationService = authorizationService; - _currentUser = currentUser; - _currentClient = currentClient; _abpAuthorizationPolicyProvider = abpAuthorizationPolicyProvider; + _abpAuthorizationService = abpAuthorizationService; } public async Task CheckAsync(MethodInvocationAuthorizationContext context) @@ -70,7 +64,7 @@ namespace Volo.Abp.Authorization var authorizationPolicy = await AuthorizationPolicy.CombineAsync( _abpAuthorizationPolicyProvider, new List { authorizationAttribute }); - await _authorizationService.CheckAsync(authorizationPolicy).ConfigureAwait(false); + await _abpAuthorizationService.CheckAsync(authorizationPolicy).ConfigureAwait(false); } } } \ No newline at end of file diff --git a/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/Authorization_Tests.cs b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/Authorization_Tests.cs index 827f7b676e..9be90dc045 100644 --- a/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/Authorization_Tests.cs +++ b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/Authorization_Tests.cs @@ -62,13 +62,6 @@ namespace Volo.Abp.Authorization }).ConfigureAwait(false); } - [Fact] - public async Task Should_Allow_To_Call_Method_If_Has_No_Role_ProtectedByRole_Async() - { - int result = await _myAuthorizedService1.ProtectedByRole().ConfigureAwait(false); - result.ShouldBe(42); - } - [Fact] public async Task Should_Not_Allow_To_Call_Method_If_Has_No_Role_ProtectedByScheme_Async() { From cfba92293294b523fe1683ab9c1d309d1a7e73f9 Mon Sep 17 00:00:00 2001 From: Mehmet Perk Date: Mon, 20 Jan 2020 21:04:31 +0300 Subject: [PATCH 023/334] authorization tests with role --- .../Authorization/AuthorizationTestBase.cs | 25 +++++++++++++++-- .../Abp/Authorization/Authorization_Tests.cs | 14 ++++++++-- .../TestServices/IMyAuthorizedService1.cs | 3 --- .../IMyAuthorizedServiceWithRole.cs | 13 +++++++++ .../TestServices/MyAuthorizedService1.cs | 15 +---------- .../MyAuthorizedServiceWithRole.cs | 27 +++++++++++++++++++ 6 files changed, 76 insertions(+), 21 deletions(-) create mode 100644 framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/IMyAuthorizedServiceWithRole.cs create mode 100644 framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/MyAuthorizedServiceWithRole.cs diff --git a/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/AuthorizationTestBase.cs b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/AuthorizationTestBase.cs index 8ab051d97e..5cf9976e46 100644 --- a/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/AuthorizationTestBase.cs +++ b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/AuthorizationTestBase.cs @@ -1,4 +1,10 @@ -using Volo.Abp.Testing; +using Microsoft.Extensions.DependencyInjection; +using NSubstitute; +using System.Collections.Generic; +using System.Security.Claims; +using System.Threading; +using Volo.Abp.Security.Claims; +using Volo.Abp.Testing; namespace Volo.Abp.Authorization { @@ -8,5 +14,20 @@ namespace Volo.Abp.Authorization { options.UseAutofac(); } + + protected override void AfterAddApplication(IServiceCollection services) + { + var claims = new List() { + new Claim(AbpClaimTypes.UserName, "Douglas"), + new Claim(AbpClaimTypes.UserId, "1fcf46b2-28c3-48d0-8bac-fa53268a2775"), + new Claim(AbpClaimTypes.Role, "MyRole") + }; + + var identity = new ClaimsIdentity(claims); + var claimsPrincipal = new ClaimsPrincipal(identity); + var principalAccessor = Substitute.For(); + principalAccessor.Principal.Returns(ci => claimsPrincipal); + Thread.CurrentPrincipal = claimsPrincipal; + } } -} \ No newline at end of file +} diff --git a/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/Authorization_Tests.cs b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/Authorization_Tests.cs index 9be90dc045..e886d2f1c4 100644 --- a/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/Authorization_Tests.cs +++ b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/Authorization_Tests.cs @@ -9,11 +9,13 @@ namespace Volo.Abp.Authorization public class Authorization_Tests : AuthorizationTestBase { private readonly IMyAuthorizedService1 _myAuthorizedService1; + private readonly IMyAuthorizedServiceWithRole _myAuthorizedServiceWithRole; private readonly IPermissionDefinitionManager _permissionDefinitionManager; public Authorization_Tests() { _myAuthorizedService1 = GetRequiredService(); + _myAuthorizedServiceWithRole = GetRequiredService(); _permissionDefinitionManager = GetRequiredService(); } @@ -58,16 +60,24 @@ namespace Volo.Abp.Authorization { await Assert.ThrowsAsync(async () => { - await _myAuthorizedService1.ProtectedByRole().ConfigureAwait(false); + await _myAuthorizedServiceWithRole.ProtectedByAnotherRole().ConfigureAwait(false); }).ConfigureAwait(false); } + [Fact] + public async Task Should_Allow_To_Call_Method_If_Has_No_Role_ProtectedByRole_Async() + { + int result = await _myAuthorizedServiceWithRole.ProtectedByRole().ConfigureAwait(false); + result.ShouldBe(42); + } + + [Fact] public async Task Should_Not_Allow_To_Call_Method_If_Has_No_Role_ProtectedByScheme_Async() { await Assert.ThrowsAsync(async () => { - await _myAuthorizedService1.ProtectedByScheme().ConfigureAwait(false); + await _myAuthorizedServiceWithRole.ProtectedByScheme().ConfigureAwait(false); }).ConfigureAwait(false); } } diff --git a/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/IMyAuthorizedService1.cs b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/IMyAuthorizedService1.cs index 6c4042168c..4c693993cf 100644 --- a/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/IMyAuthorizedService1.cs +++ b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/IMyAuthorizedService1.cs @@ -12,8 +12,5 @@ namespace Volo.Abp.Authorization.TestServices Task ProtectedByClassAsync(); - Task ProtectedByRole(); - - Task ProtectedByScheme(); } } \ No newline at end of file diff --git a/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/IMyAuthorizedServiceWithRole.cs b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/IMyAuthorizedServiceWithRole.cs new file mode 100644 index 0000000000..52b860d774 --- /dev/null +++ b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/IMyAuthorizedServiceWithRole.cs @@ -0,0 +1,13 @@ +using System.Threading.Tasks; + +namespace Volo.Abp.Authorization.TestServices +{ + public interface IMyAuthorizedServiceWithRole + { + Task ProtectedByRole(); + + Task ProtectedByScheme(); + + Task ProtectedByAnotherRole(); + } +} diff --git a/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/MyAuthorizedService1.cs b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/MyAuthorizedService1.cs index a25227babf..02f234fe99 100644 --- a/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/MyAuthorizedService1.cs +++ b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/MyAuthorizedService1.cs @@ -30,18 +30,5 @@ namespace Volo.Abp.Authorization.TestServices await Task.Delay(10).ConfigureAwait(false); return 42; } - - [Authorize(Roles = "MyRole")] - public virtual Task ProtectedByRole() - { - return Task.FromResult(42); - } - - [Authorize(AuthenticationSchemes = "Bearer")] - [Authorize(Roles = "MyRole")] - public virtual Task ProtectedByScheme() - { - return Task.FromResult(42); - } } -} \ No newline at end of file +} diff --git a/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/MyAuthorizedServiceWithRole.cs b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/MyAuthorizedServiceWithRole.cs new file mode 100644 index 0000000000..d660b040c1 --- /dev/null +++ b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/MyAuthorizedServiceWithRole.cs @@ -0,0 +1,27 @@ +using Microsoft.AspNetCore.Authorization; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.Authorization.TestServices +{ + [Authorize(Roles = "MyRole")] + public class MyAuthorizedServiceWithRole : IMyAuthorizedServiceWithRole, ITransientDependency + { + public virtual Task ProtectedByRole() + { + return Task.FromResult(42); + } + + [Authorize(Roles = "MyAnotherRole")] + public virtual Task ProtectedByAnotherRole() + { + return Task.FromResult(42); + } + + [Authorize(AuthenticationSchemes = "Bearer")] + public virtual Task ProtectedByScheme() + { + return Task.FromResult(42); + } + } +} From 583cdbac1cba2c7ad756200d469bb4470f97294c Mon Sep 17 00:00:00 2001 From: maliming Date: Tue, 21 Jan 2020 10:08:17 +0800 Subject: [PATCH 024/334] Check all authorization attributes at the same time. --- .../MethodInvocationAuthorizationService.cs | 20 +++++-------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/MethodInvocationAuthorizationService.cs b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/MethodInvocationAuthorizationService.cs index 4d0589486b..b0d53355fc 100644 --- a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/MethodInvocationAuthorizationService.cs +++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/MethodInvocationAuthorizationService.cs @@ -3,9 +3,7 @@ using System.Linq; using System.Reflection; using System.Threading.Tasks; using Microsoft.AspNetCore.Authorization; -using Volo.Abp.Clients; using Volo.Abp.DependencyInjection; -using Volo.Abp.Users; namespace Volo.Abp.Authorization { @@ -29,10 +27,10 @@ namespace Volo.Abp.Authorization return; } - foreach (var authorizationAttribute in GetAuthorizationDataAttributes(context.Method)) - { - await CheckAsync(authorizationAttribute).ConfigureAwait(false); - } + var authorizationPolicy = await AuthorizationPolicy.CombineAsync(_abpAuthorizationPolicyProvider, + GetAuthorizationDataAttributes(context.Method)).ConfigureAwait(false); + + await _abpAuthorizationService.CheckAsync(authorizationPolicy).ConfigureAwait(false); } protected virtual bool AllowAnonymous(MethodInvocationAuthorizationContext context) @@ -46,7 +44,7 @@ namespace Volo.Abp.Authorization .GetCustomAttributes(true) .OfType(); - if (methodInfo.IsPublic) + if (methodInfo.IsPublic && methodInfo.DeclaringType != null) { attributes = attributes .Union( @@ -58,13 +56,5 @@ namespace Volo.Abp.Authorization return attributes; } - - protected async Task CheckAsync(IAuthorizeData authorizationAttribute) - { - var authorizationPolicy = await AuthorizationPolicy.CombineAsync( - _abpAuthorizationPolicyProvider, - new List { authorizationAttribute }); - await _abpAuthorizationService.CheckAsync(authorizationPolicy).ConfigureAwait(false); - } } } \ No newline at end of file From 9f2b49c2d5a6c365845cf93e1e8caa13a610408d Mon Sep 17 00:00:00 2001 From: maliming Date: Wed, 19 Feb 2020 16:42:05 +0800 Subject: [PATCH 025/334] Fix build error. --- .../Abp/Authorization/MethodInvocationAuthorizationService.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/MethodInvocationAuthorizationService.cs b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/MethodInvocationAuthorizationService.cs index 6518b7ad75..32fd611b9a 100644 --- a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/MethodInvocationAuthorizationService.cs +++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/MethodInvocationAuthorizationService.cs @@ -27,7 +27,8 @@ namespace Volo.Abp.Authorization return; } - var authorizationPolicy = await AuthorizationPolicy.CombineAsync(_abpAuthorizationPolicyProvider, GetAuthorizationDataAttributes(context.Method)) + var authorizationPolicy = await AuthorizationPolicy.CombineAsync(_abpAuthorizationPolicyProvider, + GetAuthorizationDataAttributes(context.Method)); await _abpAuthorizationService.CheckAsync(authorizationPolicy); } From 88b8f6ed836f2675ad562c27cb759ee20848d824 Mon Sep 17 00:00:00 2001 From: maliming Date: Wed, 4 Mar 2020 09:18:39 +0800 Subject: [PATCH 026/334] Check if authorizationPolicy is null. --- .../Authorization/MethodInvocationAuthorizationService.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/MethodInvocationAuthorizationService.cs b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/MethodInvocationAuthorizationService.cs index 32fd611b9a..6293c0d034 100644 --- a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/MethodInvocationAuthorizationService.cs +++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/MethodInvocationAuthorizationService.cs @@ -29,6 +29,11 @@ namespace Volo.Abp.Authorization var authorizationPolicy = await AuthorizationPolicy.CombineAsync(_abpAuthorizationPolicyProvider, GetAuthorizationDataAttributes(context.Method)); + if (authorizationPolicy == null) + { + return; + } + await _abpAuthorizationService.CheckAsync(authorizationPolicy); } From ebe165ad1b3ba1502dddab04b759c74ed8edd239 Mon Sep 17 00:00:00 2001 From: Roman Rybalko Date: Fri, 6 Mar 2020 13:33:13 +0300 Subject: [PATCH 027/334] Create ru.json for Volo.Abp.Validation --- .../Volo/Abp/Validation/Localization/ru.json | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 framework/src/Volo.Abp.Validation/Volo/Abp/Validation/Localization/ru.json diff --git a/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/Localization/ru.json b/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/Localization/ru.json new file mode 100644 index 0000000000..a2023691a8 --- /dev/null +++ b/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/Localization/ru.json @@ -0,0 +1,34 @@ +{ + "culture": "ru", + "texts": { + "'{0}' and '{1}' do not match.": "'{0}' и '{1}' не совпадают.", + "The {0} field is not a valid credit card number.": "The {0} field is not a valid credit card number.", + "{0} is not valid.": "{0} is not valid.", + "The {0} field is not a valid e-mail address.": "The {0} field is not a valid e-mail address.", + "The {0} field only accepts files with the following extensions: {1}": "The {0} field only accepts files with the following extensions: {1}", + "The field {0} must be a string or array type with a maximum length of '{1}'.": "The field {0} must be a string or array type with a maximum length of '{1}'.", + "The field {0} must be a string or array type with a minimum length of '{1}'.": "The field {0} must be a string or array type with a minimum length of '{1}'.", + "The {0} field is not a valid phone number.": "The {0} field is not a valid phone number.", + "The field {0} must be between {1} and {2}.": "The field {0} must be between {1} and {2}.", + "The field {0} must match the regular expression '{1}'.": "The field {0} must match the regular expression '{1}'.", + "The {0} field is required.": "The {0} field is required.", + "The field {0} must be a string with a maximum length of {1}.": "The field {0} must be a string with a maximum length of {1}.", + "The field {0} must be a string with a minimum length of {2} and a maximum length of {1}.": "The field {0} must be a string with a minimum length of {2} and a maximum length of {1}.", + "The {0} field is not a valid fully-qualified http, https, or ftp URL.": "The {0} field is not a valid fully-qualified http, https, or ftp URL.", + "The field {0} is invalid.": "The field {0} is invalid.", + "ThisFieldIsNotAValidCreditCardNumber.": "This field is not a valid credit card number.", + "ThisFieldIsNotValid.": "This field is not valid.", + "ThisFieldIsNotAValidEmailAddress.": "This field is not a valid e-mail address.", + "ThisFieldOnlyAcceptsFilesWithTheFollowingExtensions:{0}": "This field only accepts files with the following extensions: {0}", + "ThisFieldMustBeAStringOrArrayTypeWithAMaximumLengthoOf{0}": "This field must be a string or array type with a maximum length of '{0}'.", + "ThisFieldMustBeAStringOrArrayTypeWithAMinimumLengthOf{0}": "This field must be a string or array type with a minimum length of '{0}'.", + "ThisFieldIsNotAValidPhoneNumber.": "This field is not a valid phone number.", + "ThisFieldMustBeBetween{0}And{1}": "This field must be between {0} and {1}.", + "ThisFieldMustMatchTheRegularExpression{0}": "This field must match the regular expression '{0}'.", + "ThisFieldIsRequired.": "This field is required.", + "ThisFieldMustBeAStringWithAMaximumLengthOf{0}": "This field must be a string with a maximum length of {0}.", + "ThisFieldMustBeAStringWithAMinimumLengthOf{1}AndAMaximumLengthOf{0}": "This field must be a string with a minimum length of {1} and a maximum length of {0}.", + "ThisFieldIsNotAValidFullyQualifiedHttpHttpsOrFtpUrl": "This field is not a valid fully-qualified http, https, or ftp URL.", + "ThisFieldIsInvalid.": "This field is invalid." + } +} From befca94445f2ad3f7abf83a6b7895484404f443e Mon Sep 17 00:00:00 2001 From: Roman Rybalko Date: Fri, 6 Mar 2020 14:44:25 +0300 Subject: [PATCH 028/334] Update ru.json for Volo.Abp.Validation --- .../Volo/Abp/Validation/Localization/ru.json | 56 +++++++++---------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/Localization/ru.json b/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/Localization/ru.json index a2023691a8..6272fdf534 100644 --- a/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/Localization/ru.json +++ b/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/Localization/ru.json @@ -2,33 +2,33 @@ "culture": "ru", "texts": { "'{0}' and '{1}' do not match.": "'{0}' и '{1}' не совпадают.", - "The {0} field is not a valid credit card number.": "The {0} field is not a valid credit card number.", - "{0} is not valid.": "{0} is not valid.", - "The {0} field is not a valid e-mail address.": "The {0} field is not a valid e-mail address.", - "The {0} field only accepts files with the following extensions: {1}": "The {0} field only accepts files with the following extensions: {1}", - "The field {0} must be a string or array type with a maximum length of '{1}'.": "The field {0} must be a string or array type with a maximum length of '{1}'.", - "The field {0} must be a string or array type with a minimum length of '{1}'.": "The field {0} must be a string or array type with a minimum length of '{1}'.", - "The {0} field is not a valid phone number.": "The {0} field is not a valid phone number.", - "The field {0} must be between {1} and {2}.": "The field {0} must be between {1} and {2}.", - "The field {0} must match the regular expression '{1}'.": "The field {0} must match the regular expression '{1}'.", - "The {0} field is required.": "The {0} field is required.", - "The field {0} must be a string with a maximum length of {1}.": "The field {0} must be a string with a maximum length of {1}.", - "The field {0} must be a string with a minimum length of {2} and a maximum length of {1}.": "The field {0} must be a string with a minimum length of {2} and a maximum length of {1}.", - "The {0} field is not a valid fully-qualified http, https, or ftp URL.": "The {0} field is not a valid fully-qualified http, https, or ftp URL.", - "The field {0} is invalid.": "The field {0} is invalid.", - "ThisFieldIsNotAValidCreditCardNumber.": "This field is not a valid credit card number.", - "ThisFieldIsNotValid.": "This field is not valid.", - "ThisFieldIsNotAValidEmailAddress.": "This field is not a valid e-mail address.", - "ThisFieldOnlyAcceptsFilesWithTheFollowingExtensions:{0}": "This field only accepts files with the following extensions: {0}", - "ThisFieldMustBeAStringOrArrayTypeWithAMaximumLengthoOf{0}": "This field must be a string or array type with a maximum length of '{0}'.", - "ThisFieldMustBeAStringOrArrayTypeWithAMinimumLengthOf{0}": "This field must be a string or array type with a minimum length of '{0}'.", - "ThisFieldIsNotAValidPhoneNumber.": "This field is not a valid phone number.", - "ThisFieldMustBeBetween{0}And{1}": "This field must be between {0} and {1}.", - "ThisFieldMustMatchTheRegularExpression{0}": "This field must match the regular expression '{0}'.", - "ThisFieldIsRequired.": "This field is required.", - "ThisFieldMustBeAStringWithAMaximumLengthOf{0}": "This field must be a string with a maximum length of {0}.", - "ThisFieldMustBeAStringWithAMinimumLengthOf{1}AndAMaximumLengthOf{0}": "This field must be a string with a minimum length of {1} and a maximum length of {0}.", - "ThisFieldIsNotAValidFullyQualifiedHttpHttpsOrFtpUrl": "This field is not a valid fully-qualified http, https, or ftp URL.", - "ThisFieldIsInvalid.": "This field is invalid." + "The {0} field is not a valid credit card number.": "Поле {0} не содержит действительный номер кредитной карты.", + "{0} is not valid.": "Значение {0} недействительно.", + "The {0} field is not a valid e-mail address.": "Поле {0} не содержит действительный адрес электронной почты.", + "The {0} field only accepts files with the following extensions: {1}": "В поле {0} вы можете загрузить файлы следующих форматов: {1}", + "The field {0} must be a string or array type with a maximum length of '{1}'.": "Поле {0} должно иметь тип строки или массива с максимальной длиной '{1}'.", + "The field {0} must be a string or array type with a minimum length of '{1}'.": "Поле {0} должно иметь тип строки или массива с минимальной длиной '{1}'.", + "The {0} field is not a valid phone number.": "Поле {0} не содержит действительный номер телефона.", + "The field {0} must be between {1} and {2}.": "Поле {0} должно находиться между {1} и {2}.", + "The field {0} must match the regular expression '{1}'.": "Поле {0} должно соответствовать регулярному выражению '{1}'.", + "The {0} field is required.": "Поле {0} необходимо заполнить.", + "The field {0} must be a string with a maximum length of {1}.": "Поле {0} должно быть строкой с максимальной длиной {1}.", + "The field {0} must be a string with a minimum length of {2} and a maximum length of {1}.": "Поле {0} должно быть строкой с минимальной длиной {2} и максимальной длиной {1}.", + "The {0} field is not a valid fully-qualified http, https, or ftp URL.": "Поле {0} не является действительным полным http, https или ftp адресом.", + "The field {0} is invalid.": "Значение в поле {0} недопустимо.", + "ThisFieldIsNotAValidCreditCardNumber.": "Это поле не содержит действительный номер кредитной карты.", + "ThisFieldIsNotValid.": "Значение в этом поле недействительно.", + "ThisFieldIsNotAValidEmailAddress.": "Это поле не содержит действительный адрес электронной почты.", + "ThisFieldOnlyAcceptsFilesWithTheFollowingExtensions:{0}": "Вы можете загрузить файлы только следующих форматов: {0}", + "ThisFieldMustBeAStringOrArrayTypeWithAMaximumLengthoOf{0}": "Это поле должно иметь тип строки или массива с максимальной длиной '{0}'.", + "ThisFieldMustBeAStringOrArrayTypeWithAMinimumLengthOf{0}": "Это поле должно иметь тип строки или массива с минимальной длиной '{0}'.", + "ThisFieldIsNotAValidPhoneNumber.": "Это поле не содержит действительный номер телефона.", + "ThisFieldMustBeBetween{0}And{1}": "Это поле должно быть между {0} и {1}.", + "ThisFieldMustMatchTheRegularExpression{0}": "Это поле должно соответствовать регулярному выражению '{0}'.", + "ThisFieldIsRequired.": "Это обязательное поле.", + "ThisFieldMustBeAStringWithAMaximumLengthOf{0}": "Это поле должно быть строкой с максимальной длиной {0}.", + "ThisFieldMustBeAStringWithAMinimumLengthOf{1}AndAMaximumLengthOf{0}": "Это поле должно быть строкой с минимальной длиной {1} и максимальной длиной {0}.", + "ThisFieldIsNotAValidFullyQualifiedHttpHttpsOrFtpUrl": "Значение в поле не является действительным полным http, https или ftp адресом.", + "ThisFieldIsInvalid.": "Значение в этом поле недопустимо." } } From 7c577d195ce7515fe10aad8b59032051bea64485 Mon Sep 17 00:00:00 2001 From: Roman Rybalko Date: Fri, 6 Mar 2020 15:27:18 +0300 Subject: [PATCH 029/334] Create ru.json for Volo.Abp.UI --- .../Localization/Resources/AbpUi/ru.json | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/ru.json diff --git a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/ru.json b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/ru.json new file mode 100644 index 0000000000..7b48db1a3a --- /dev/null +++ b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/ru.json @@ -0,0 +1,62 @@ +{ + "culture": "ru", + "texts": { + "InternalServerErrorMessage": "Во время запроса произошла внутренняя ошибка!", + "ValidationErrorMessage": "Ваш запрос недействителен!", + "ValidationNarrativeErrorMessageTitle": "При проверке были обнаружены следующие ошибки.", + "DefaultErrorMessage": "Произошла ошибка!", + "DefaultErrorMessageDetail": "Сведения об ошибке не были предоставлены сервером.", + "DefaultErrorMessage401": "Вы не авторизированы!", + "DefaultErrorMessage401Detail": "Вы должны Войти, чтобы выполнить эту операцию.", + "DefaultErrorMessage403": "Вы не авторизованы!", + "DefaultErrorMessage403Detail": "У вас нет доступа к выполнению этой операции!", + "DefaultErrorMessage404": "Ресурс не найден!", + "DefaultErrorMessage404Detail": "Запрошенный ресурс не удалось найти на сервере!", + "EntityNotFoundErrorMessage": "Нет объекта {0} с id = {1}!", + "Languages": "Языки", + "Error": "Ошибка", + "AreYouSure": "Вы уверены?", + "Cancel": "Отмена", + "Yes": "Да", + "No": "Нет", + "Ok": "ОК", + "Close": "Закрыть", + "Save": "Сохранить", + "SavingWithThreeDot": "Сохранение...", + "Actions": "Действия", + "Delete": "Удалить", + "Edit": "Редактировать", + "Refresh": "Обновить", + "Language": "Язык", + "LoadMore": "Загрузить еще", + "ProcessingWithThreeDot": "Обработка...", + "LoadingWithThreeDot": "Загрузка...", + "Welcome": "Добро пожаловать", + "Login": "Войти", + "Register": "Зарегистрироваться", + "Logout": "Выйти", + "Submit": "Подтвердить", + "Back": "Назад", + "PagerSearch": "Поиск", + "PagerNext": "Следующее", + "PagerPrevious": "Предыдущее", + "PagerFirst": "Первая", + "PagerLast": "Последняя", + "PagerInfo": "Записи с _START_ до _END_ из _TOTAL_ записей", + "PagerInfoEmpty": "Записи с 0 до 0 из 0 записей.", + "PagerInfoFiltered": "(отфильтровано из _MAX_ записей)", + "NoDataAvailableInDatatable": "Данные в таблице отсутствуют", + "PagerShowMenuEntries": "Показать _MENU_ записей", + "DatatableActionDropdownDefaultText": "Действия", + "ChangePassword": "Изменить пароль", + "PersonalInfo": "Мой профиль", + "AreYouSureYouWantToCancelEditingWarningMessage": "У вас есть несохраненные изменения.", + "UnhandledException": "Непредвиденная ошибка!", + "401Message": "Неавторизованный", + "403Message": "В доступе отказано", + "404Message": "Страница не найдена", + "500Message": "Внутренняя ошибка сервера", + "GoHomePage": "Вернуться на главную страницу", + "GoBack": "Вернуться назад" + } +} From 8b6969415658cae921768b3aa4c1c7118321af29 Mon Sep 17 00:00:00 2001 From: Roman Rybalko Date: Fri, 6 Mar 2020 15:55:59 +0300 Subject: [PATCH 030/334] Create ru.json for Volo.Abp.UI.Navigation --- .../Volo/Abp/Ui/Navigation/Localization/Resource/ru.json | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/Localization/Resource/ru.json diff --git a/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/Localization/Resource/ru.json b/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/Localization/Resource/ru.json new file mode 100644 index 0000000000..2a76578396 --- /dev/null +++ b/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/Localization/Resource/ru.json @@ -0,0 +1,6 @@ +{ + "culture": "ru", + "texts": { + "Menu:Administration": "Администрирование" + } +} From bc35b98ba0502b0c50db66f1336a75e43328d77b Mon Sep 17 00:00:00 2001 From: Roman Rybalko Date: Fri, 6 Mar 2020 16:18:32 +0300 Subject: [PATCH 031/334] Create ru.json for Volo.Abp.Localization --- .../Abp/Localization/Resources/AbpLocalization/ru.json | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 framework/src/Volo.Abp.Localization/Volo/Abp/Localization/Resources/AbpLocalization/ru.json diff --git a/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/Resources/AbpLocalization/ru.json b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/Resources/AbpLocalization/ru.json new file mode 100644 index 0000000000..3f00c8994b --- /dev/null +++ b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/Resources/AbpLocalization/ru.json @@ -0,0 +1,7 @@ +{ + "culture": "ru", + "texts": { + "DisplayName:Abp.Localization.DefaultLanguage": "Язык по умолчанию", + "Description:Abp.Localization.DefaultLanguage": "Язык приложения по умолчанию." + } +} From 653924c11087f628a6d81c5ef57c5fffb7ce3f1c Mon Sep 17 00:00:00 2001 From: Roman Rybalko Date: Fri, 6 Mar 2020 16:59:59 +0300 Subject: [PATCH 032/334] Create ru.json for Volo.Abp.Emailing --- .../Volo/Abp/Emailing/Localization/ru.json | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Localization/ru.json diff --git a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Localization/ru.json b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Localization/ru.json new file mode 100644 index 0000000000..249baa61b2 --- /dev/null +++ b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Localization/ru.json @@ -0,0 +1,23 @@ +{ + "culture": "ru", + "texts": { + "DisplayName:Abp.Mailing.DefaultFromAddress": "Адрес отправления по умолчанию", + "DisplayName:Abp.Mailing.DefaultFromDisplayName": "Имя отправителя по умолчанию", + "DisplayName:Abp.Mailing.Smtp.Host": "Сервер", + "DisplayName:Abp.Mailing.Smtp.Port": "Порт", + "DisplayName:Abp.Mailing.Smtp.UserName": "Имя пользователя", + "DisplayName:Abp.Mailing.Smtp.Password": "Пароль", + "DisplayName:Abp.Mailing.Smtp.Domain": "Домен", + "DisplayName:Abp.Mailing.Smtp.EnableSsl": "Включить SSL", + "DisplayName:Abp.Mailing.Smtp.UseDefaultCredentials": "Использовать учетные данные по умолчанию", + "Description:Abp.Mailing.DefaultFromAddress": "Отправление по умолчанию от адреса.", + "Description:Abp.Mailing.DefaultFromDisplayName": "Имя отправителя по умолчанию.", + "Description:Abp.Mailing.Smtp.Host": "Имя или IP- адрес сервера, используемого для отправки по протоколу SMTP.", + "Description:Abp.Mailing.Smtp.Port": "Порт, используемый для отправки по протоколу SMTP.", + "Description:Abp.Mailing.Smtp.UserName": "Имя пользователя для SMTP-сервера.", + "Description:Abp.Mailing.Smtp.Password": "Пароль для SMTP-сервера.", + "Description:Abp.Mailing.Smtp.Domain": "Домен или имя компьютера, от которого производится SMTP-запрос.", + "Description:Abp.Mailing.Smtp.EnableSsl": "Использовать SSL для подключения к SMTP-серверу.", + "Description:Abp.Mailing.Smtp.UseDefaultCredentials": "Использовать учетные данные для SMTP по умолчанию." + } +} From 9f86a1c6480a65b4f1a39afbd3335a57d7329940 Mon Sep 17 00:00:00 2001 From: Roman Rybalko Date: Fri, 6 Mar 2020 17:09:55 +0300 Subject: [PATCH 033/334] Added ru.json For Volo.Abp.Ddd.Application.Contracts --- .../Abp/Application/Localization/Resources/AbpDdd/ru.json | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Localization/Resources/AbpDdd/ru.json diff --git a/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Localization/Resources/AbpDdd/ru.json b/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Localization/Resources/AbpDdd/ru.json new file mode 100644 index 0000000000..b84f77f8b3 --- /dev/null +++ b/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Localization/Resources/AbpDdd/ru.json @@ -0,0 +1,6 @@ +{ + "culture": "ru", + "texts": { + "MaxResultCountExceededExceptionMessage": "{0} не может быть больше {1}! Увеличьте {2}.{3} на стороне сервера, чтобы получить больше результатов." + } +} From edd36dc240b1b559f60c2cf07dcd313cece95f66 Mon Sep 17 00:00:00 2001 From: Roman Rybalko Date: Fri, 6 Mar 2020 18:12:11 +0300 Subject: [PATCH 034/334] Create ru.json for Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy --- .../Mvc/UI/MultiTenancy/Localization/ru.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/ru.json diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/ru.json b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/ru.json new file mode 100644 index 0000000000..04b2e5cf85 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/ru.json @@ -0,0 +1,12 @@ +{ + "culture": "ru", + "texts": { + "GivenTenantIsNotAvailable": "Данный арендатор недоступен: {0}", + "Tenant": "Арендатор", + "Switch": "переключиться", + "Name": "Имя", + "SwitchTenantHint": "Оставьте поле Имя пустым, чтобы переключиться на администратора.", + "SwitchTenant": "Сменить арендатора", + "NotSelected": "Не выбрано" + } +} From 4d3ce4b7dbbffd56017f454a6bcc82f7bde17f0e Mon Sep 17 00:00:00 2001 From: Roman Rybalko Date: Fri, 6 Mar 2020 18:38:13 +0300 Subject: [PATCH 035/334] Create ru.json for Volo.Blogging.Domain.Shared --- .../Blogging/Localization/Resources/ru.json | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 modules/blogging/src/Volo.Blogging.Domain.Shared/Volo/Blogging/Localization/Resources/ru.json diff --git a/modules/blogging/src/Volo.Blogging.Domain.Shared/Volo/Blogging/Localization/Resources/ru.json b/modules/blogging/src/Volo.Blogging.Domain.Shared/Volo/Blogging/Localization/Resources/ru.json new file mode 100644 index 0000000000..898d363cef --- /dev/null +++ b/modules/blogging/src/Volo.Blogging.Domain.Shared/Volo/Blogging/Localization/Resources/ru.json @@ -0,0 +1,47 @@ +{ + "culture": "ru", + "texts": { + "Menu:Blogs": "Блоги", + "Menu:BlogManagement": "Управление блогом", + "Title": "Заголовок", + "Delete": "Удалить", + "Reply": "Ответить", + "ReplyTo": "Ответить {0}", + "ContinueReading": "Продолжить чтение", + "DaysAgo": "{0} дней назад", + "YearsAgo": "{0} лет назад", + "MonthsAgo": "{0} месяцев назад", + "WeeksAgo": "{0} недель назад", + "MinutesAgo": "{0} минут назад", + "SecondsAgo": "{0} секунд назад", + "HoursAgo": "{0} часов назад", + "Now": "сейчас", + "Content": "Содержание", + "SeeAll": "Увидеть все", + "PopularTags": "Популярные тэги", + "WiewsWithCount": "{0} просмотров", + "LastPosts": "Последние записи", + "LeaveComment": "Оставить комментарий", + "TagsInThisArticle": "Теги в этой статье", + "Posts": "Записи", + "Edit": "Редактировать", + "BLOG": "БЛОГ", + "CommentDeletionWarningMessage": "Комментарий будет удален.", + "PostDeletionWarningMessage": "Запись будет удалена.", + "BlogDeletionWarningMessage": "Блог будет удален.", + "AreYouSure": "Вы уверены?", + "CommentWithCount": "{0} комментариев", + "Comment": "Комментарий", + "ShareOnTwitter": "Поделиться в Twitter", + "CoverImage": "Обложка", + "CreateANewPost": "Создать новый пост", + "CreateANewBlog": "Создать новый блог", + "WhatIsNew": "Что нового?", + "Name": "Имя", + "ShortName": "Фамилия", + "CreationTime": "Время создания", + "Description": "Описание", + "Blogs": "Блоги", + "Tags": "Теги" + } +} From 7d60e9af3fbdf4bba2cd573a7b91b18d57acc86e Mon Sep 17 00:00:00 2001 From: Roman Rybalko Date: Fri, 6 Mar 2020 19:07:54 +0300 Subject: [PATCH 036/334] Added ru.json for Volo.Docs.Admin.Application.Contracts --- .../Docs/ApplicationContracts/ru.json | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Localization/Resources/Docs/ApplicationContracts/ru.json diff --git a/modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Localization/Resources/Docs/ApplicationContracts/ru.json b/modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Localization/Resources/Docs/ApplicationContracts/ru.json new file mode 100644 index 0000000000..ba2680892c --- /dev/null +++ b/modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Localization/Resources/Docs/ApplicationContracts/ru.json @@ -0,0 +1,37 @@ +{ + "culture": "ru", + "texts": { + "Permission:DocumentManagement": "Управление документацией", + "Permission:Projects": "Проекты", + "Permission:Edit": "Редактировать", + "Permission:Delete": "Удалить", + "Permission:Create": "Создать", + "Permission:Documents": "Документы", + "Menu:DocumentManagement": "Документы", + "Menu:ProjectManagement": "Проекты", + "CreateANewProject": "Создать проекты", + "Edit": "Редактировать", + "Create": "Создать", + "Pull": "Получить", + "Projects": "Проекты", + "Name": "Название", + "ShortName": "Сокращенное название", + "DocumentStoreType": "Тип системы хранения", + "Format": "Формат", + "ShortNameInfoText": "Будет использоваться для уникального URL.", + "DisplayName:Name": "Название", + "DisplayName:ShortName": "Сокращенное название", + "DisplayName:Format": "Формат", + "DisplayName:DefaultDocumentName": "Имя документа по умолчанию", + "DisplayName:NavigationDocumentName": "Имя документа для навигации", + "DisplayName:MinimumVersion": "Минимальная версия", + "DisplayName:MainWebsiteUrl": "URL основного веб-сайта", + "DisplayName:LatestVersionBranchName": "Название ветки последней версии", + "DisplayName:GitHubRootUrl": "Корневой URL-адрес GitHub", + "DisplayName:GitHubAccessToken": "Маркер доступа для GitHub", + "DisplayName:GitHubUserAgent": "Заголовок User-Agent для GitHub", + "DisplayName:All": "Получить все", + "DisplayName:LanguageCode": "Код языка", + "DisplayName:Version": "Версия" + } +} From 0f546ed8ef16c427ffeea8cbe2e3c83078284985 Mon Sep 17 00:00:00 2001 From: Roman Rybalko Date: Fri, 6 Mar 2020 19:24:34 +0300 Subject: [PATCH 037/334] Added ru.json for VoloDocs.Web --- .../Localization/Resources/VoloDocs/Web/ru.json | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 modules/docs/app/VoloDocs.Web/Localization/Resources/VoloDocs/Web/ru.json diff --git a/modules/docs/app/VoloDocs.Web/Localization/Resources/VoloDocs/Web/ru.json b/modules/docs/app/VoloDocs.Web/Localization/Resources/VoloDocs/Web/ru.json new file mode 100644 index 0000000000..e0e5094cc1 --- /dev/null +++ b/modules/docs/app/VoloDocs.Web/Localization/Resources/VoloDocs/Web/ru.json @@ -0,0 +1,10 @@ +{ + "culture": "ru", + "texts": { + "DocsTitle": "VoloDocs", + "WelcomeVoloDocs": "Добро пожаловать в VoloDocs!", + "NoProjectWarning": "Отсутствует определение проекта!", + "CreateYourFirstProject": "Нажмите здесь, чтобы добавить свой первый проект", + "NoProject": "Нет проекта!" + } +} From ef3d83fa47018c2a455156e6e526faf2c2a84ddc Mon Sep 17 00:00:00 2001 From: Roman Rybalko Date: Fri, 6 Mar 2020 19:28:54 +0300 Subject: [PATCH 038/334] Added ru.json for Volo.Abp.FeatureManagement.Domain.Shared --- .../Volo/Abp/FeatureManagement/Localization/Domain/ru.json | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/ru.json diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/ru.json b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/ru.json new file mode 100644 index 0000000000..3945762269 --- /dev/null +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/ru.json @@ -0,0 +1,7 @@ +{ + "culture": "ru", + "texts": { + "Features": "Функциональные возможности", + "NoFeatureFoundMessage": "Нет доступных функциональных возможностей." + } +} From a191a4a5f1eab99bb881f31a246653c8d5fb40e9 Mon Sep 17 00:00:00 2001 From: Roman Rybalko Date: Fri, 6 Mar 2020 21:04:22 +0300 Subject: [PATCH 039/334] Added ru.json for Volo.Abp.IdentityServer.Domain.Shared --- .../IdentityServer/Localization/Resources/ru.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 modules/identityserver/src/Volo.Abp.IdentityServer.Domain.Shared/Volo/Abp/IdentityServer/Localization/Resources/ru.json diff --git a/modules/identityserver/src/Volo.Abp.IdentityServer.Domain.Shared/Volo/Abp/IdentityServer/Localization/Resources/ru.json b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain.Shared/Volo/Abp/IdentityServer/Localization/Resources/ru.json new file mode 100644 index 0000000000..808962d8e5 --- /dev/null +++ b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain.Shared/Volo/Abp/IdentityServer/Localization/Resources/ru.json @@ -0,0 +1,12 @@ +{ + "culture": "ru", + "texts": { + "Volo.IdentityServer:DuplicateIdentityResourceName": "Имя ресурса идентификации уже существует: {Name}", + "Volo.IdentityServer:DuplicateApiResourceName": "Имя ресурса API уже существует: {Name}", + "Volo.IdentityServer:DuplicateClientId": "Параметр ClientID уже существует: {ClientId}", + "UserLockedOut": "Учетная запись пользователя была заблокирована из-за неудачных попыток входа в систему. Пожалуйста, попробуйте позже.", + "InvalidUserNameOrPassword": "Неверное имя пользователя или пароль!", + "LoginIsNotAllowed": "У вас нет разрешения на вход в систему. Необходимо подтвердить свой адрес электронной почты/номер телефона.", + "InvalidUsername": "Неверное имя пользователя или пароль!" + } +} From 87d41f9ac26c493e03d93ac120b76791bbc748d4 Mon Sep 17 00:00:00 2001 From: Roman Rybalko Date: Fri, 6 Mar 2020 21:24:03 +0300 Subject: [PATCH 040/334] Added ru.json for Volo.Abp.Identity.Domain.Shared --- .../Volo/Abp/Identity/Localization/ru.json | 102 ++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ru.json diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ru.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ru.json new file mode 100644 index 0000000000..1df7b63bfe --- /dev/null +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ru.json @@ -0,0 +1,102 @@ +{ + "culture": "ru", + "texts": { + "Menu:IdentityManagement": "Управление идентификацией", + "Users": "Пользователи", + "NewUser": "Новый пользователь", + "UserName": "Имя пользователя", + "EmailAddress": "Адрес электронной почты", + "PhoneNumber": "Номер телефона", + "UserInformations": "Информация о пользователе", + "DisplayName:IsDefault": "По умолчанию", + "DisplayName:IsStatic": "Статичная", + "DisplayName:IsPublic": "Доступно", + "Roles": "Роли", + "Password": "Пароль", + "PersonalInfo": "Мой профиль", + "PersonalSettings": "Персональные настройки", + "UserDeletionConfirmationMessage": "Пользователь '{0}' будет удален. Вы подтверждаете это?", + "RoleDeletionConfirmationMessage": "Роль '{0}' будет удалена. Вы подтверждаете это?", + "DisplayName:RoleName": "Название роли", + "DisplayName:UserName": "Имя пользователя", + "DisplayName:Name": "Имя", + "DisplayName:Surname": "Фамилия", + "DisplayName:Password": "Пароль", + "DisplayName:Email": "Адрес электронной почты", + "DisplayName:PhoneNumber": "Номер телефона", + "DisplayName:TwoFactorEnabled": "Двухфакторная проверка подлинности", + "DisplayName:LockoutEnabled": "Заблокировать учетную запись после неудачных попыток входа", + "NewRole": "Новая роль", + "RoleName": "Имя роли", + "CreationTime": "Время создания", + "Permissions": "Разрешения", + "DisplayName:CurrentPassword": "Текущий пароль", + "DisplayName:NewPassword": "Новый пароль", + "DisplayName:NewPasswordConfirm": "Подтверждение нового пароля", + "PasswordChangedMessage": "Ваш пароль был успешно изменен.", + "PersonalSettingsSavedMessage": "Ваши персональные настройки были успешно сохранены.", + "Identity.DefaultError": "Возникла непредвиденная ошибка.", + "Identity.ConcurrencyFailure": "Ошибка оптимального управления многопоточностью, объект был изменен.", + "Identity.DuplicateEmail": "Электронная почта '{0}' уже зарегистрирована.", + "Identity.DuplicateRoleName": "Имя роли '{0}' уже занято.", + "Identity.DuplicateUserName": "Имя пользователя '{0}' уже занято.", + "Identity.InvalidEmail": "Адрес электронной почты '{0}' недействителен.", + "Identity.InvalidPasswordHasherCompatibilityMode": "Предоставленный PasswordHasherCompatibilityMode недействителен.", + "Identity.InvalidPasswordHasherIterationCount": "Число итераций должно быть положительным целым числом.", + "Identity.InvalidRoleName": "Имя роли '{0}' недопустимо.", + "Identity.InvalidToken": "Недопустимый маркер.", + "Identity.InvalidUserName": "Имя пользователя '{0}' недопустимо и может содержать только буквы или цифры.", + "Identity.LoginAlreadyAssociated": "Пользователь с таким логином уже существует.", + "Identity.PasswordMismatch": "Неверный пароль.", + "Identity.PasswordRequiresDigit": "Пароль должен содержать по крайней мере одну цифру.", + "Identity.PasswordRequiresLower": "Пароль должен содержать хотя бы одну строчную букву.", + "Identity.PasswordRequiresNonAlphanumeric": "Пароль должен иметь по крайней мере один не буквенно-цифровой символ.", + "Identity.PasswordRequiresUpper": "Пароль должен иметь хотя бы одну букву верхнего регистра.", + "Identity.PasswordTooShort": "Пароль должен содержать не менее {0} символов.", + "Identity.RoleNotFound": "Роль {0} не существует.", + "Identity.UserAlreadyHasPassword": "У пользователя уже установлен пароль.", + "Identity.UserAlreadyInRole": "Пользователь уже имеет роль '{0}'.", + "Identity.UserLockedOut": "Пользователь временно заблокирован.", + "Identity.UserLockoutNotEnabled": "Блокировка не активирована для этого пользователя.", + "Identity.UserNameNotFound": "Пользователь {0} не существует.", + "Identity.UserNotInRole": "Пользователь не имеет роль '{0}'.", + "Identity.PasswordConfirmationFailed": "Пароли не совпадают.", + "Identity.StaticRoleRenamingErrorMessage": "Статические роли не могут быть переименованы.", + "Identity.StaticRoleDeletionErrorMessage": "Статические роли не могут быть удалены.", + "Volo.Abp.Identity:010001": "Вы не можете удалить свой собственный аккаунт!", + "Permission:IdentityManagement": "Управление идентификацией", + "Permission:RoleManagement": "Управление ролями", + "Permission:Create": "Создать", + "Permission:Edit": "Редактировать", + "Permission:Delete": "Удалить", + "Permission:ChangePermissions": "Изменить разрешения", + "Permission:UserManagement": "Управление пользователями", + "Permission:UserLookup": "Поиск пользователя", + "DisplayName:Abp.Identity.Password.RequiredLength": "Требуемая длина", + "DisplayName:Abp.Identity.Password.RequiredUniqueChars": "Обязательное количество уникальных символов", + "DisplayName:Abp.Identity.Password.RequireNonAlphanumeric": "Обязательный не буквенно-цифровой символ", + "DisplayName:Abp.Identity.Password.RequireLowercase": "Обязательный символ нижнего регистра", + "DisplayName:Abp.Identity.Password.RequireUppercase": "Обязательный символ верхнего регистра", + "DisplayName:Abp.Identity.Password.RequireDigit": "Требуемая цифра", + "DisplayName:Abp.Identity.Lockout.AllowedForNewUsers": "Включено для новых пользователей", + "DisplayName:Abp.Identity.Lockout.LockoutDuration": "Длительность блокировки (секунды)", + "DisplayName:Abp.Identity.Lockout.MaxFailedAccessAttempts": "Максимальное количество неудачных попыток доступа", + "DisplayName:Abp.Identity.SignIn.RequireConfirmedEmail": "Требуется подтверждение электронной почты", + "DisplayName:Abp.Identity.SignIn.RequireConfirmedPhoneNumber": "Требуется подтверждение номера телефона", + "DisplayName:Abp.Identity.User.IsUserNameUpdateEnabled": "Пользователь может изменять имя", + "DisplayName:Abp.Identity.User.IsEmailUpdateEnabled": "Электронная почта может быть изменена", + "Description:Abp.Identity.Password.RequiredLength": "Минимальная длина пароля.", + "Description:Abp.Identity.Password.RequiredUniqueChars": "Минимальное количество уникальных символов, которые должен содержать пароль.", + "Description:Abp.Identity.Password.RequireNonAlphanumeric": "Если пароли должны содержать не буквенно- цифровой символ.", + "Description:Abp.Identity.Password.RequireLowercase": "Если пароли должны содержать строчные символы ASCII.", + "Description:Abp.Identity.Password.RequireUppercase": "Если пароли должны содержать символ ASCII в верхнем регистре.", + "Description:Abp.Identity.Password.RequireDigit": "Если пароли должны содержать цифру.", + "Description:Abp.Identity.Lockout.AllowedForNewUsers": "Может ли новый пользователь быть заблокирован.", + "Description:Abp.Identity.Lockout.LockoutDuration": "Длительность блокировки пользователя.", + "Description:Abp.Identity.Lockout.MaxFailedAccessAttempts": "Число неудачных попыток доступа, после которых пользователь будет заблокирован.", + "Description:Abp.Identity.SignIn.RequireConfirmedEmail": "Требуется ли для входа подтвержденный адрес электронной почты.", + "Description:Abp.Identity.SignIn.RequireConfirmedPhoneNumber": "Требуется ли для входа в систему подтвержденный номер телефона.", + "Description:Abp.Identity.User.IsUserNameUpdateEnabled": "Может ли пользователь обновить имя пользователя.", + "Description:Abp.Identity.User.IsEmailUpdateEnabled": "Может ли электронная почта быть обновлена пользователем." + } +} From e45c8edc1e9f8323007f2d93d1124102819a964f Mon Sep 17 00:00:00 2001 From: Roman Rybalko Date: Fri, 6 Mar 2020 21:33:17 +0300 Subject: [PATCH 041/334] Added ru.json for Volo.Abp.PermissionManagement.Domain.Shared --- .../PermissionManagement/Localization/Domain/ru.json | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/ru.json diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/ru.json b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/ru.json new file mode 100644 index 0000000000..33291e66a0 --- /dev/null +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/ru.json @@ -0,0 +1,10 @@ +{ + "culture": "ru", + "texts": { + "Permissions": "Разрешения", + "OnlyProviderPermissons": "Только этот провайдер", + "All": "Все", + "SelectAllInAllTabs": "Предоставить все разрешения", + "SelectAllInThisTab": "Выбрать все" + } +} From 52e5dcae94ab723039ab79cf92f229b81d8eb970 Mon Sep 17 00:00:00 2001 From: Roman Rybalko Date: Fri, 6 Mar 2020 21:35:57 +0300 Subject: [PATCH 042/334] Added ru.json for Volo.Abp.SettingManagement.Domain.Shared --- .../Localization/Resources/AbpSettingManagement/ru.json | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/Localization/Resources/AbpSettingManagement/ru.json diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/Localization/Resources/AbpSettingManagement/ru.json b/modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/Localization/Resources/AbpSettingManagement/ru.json new file mode 100644 index 0000000000..3b23b1d04a --- /dev/null +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/Localization/Resources/AbpSettingManagement/ru.json @@ -0,0 +1,7 @@ +{ + "culture": "ru", + "texts": { + "Settings": "Настройки", + "SuccessfullySaved": "Успешно сохранено" + } +} From 462f3f3f79546845cab34b17c6f65a23144171c0 Mon Sep 17 00:00:00 2001 From: Roman Rybalko Date: Fri, 6 Mar 2020 21:40:53 +0300 Subject: [PATCH 043/334] Added ru.json for Volo.Abp.TenantManagement.Domain.Shared --- .../Localization/Resources/ru.json | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 modules/tenant-management/src/Volo.Abp.TenantManagement.Domain.Shared/Volo/Abp/TenantManagement/Localization/Resources/ru.json diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain.Shared/Volo/Abp/TenantManagement/Localization/Resources/ru.json b/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain.Shared/Volo/Abp/TenantManagement/Localization/Resources/ru.json new file mode 100644 index 0000000000..dd8f0c3847 --- /dev/null +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain.Shared/Volo/Abp/TenantManagement/Localization/Resources/ru.json @@ -0,0 +1,20 @@ +{ + "culture": "ru", + "texts": { + "Menu:TenantManagement": "Управление арендаторами", + "Tenants": "Арендаторы", + "NewTenant": "Новый арендатор", + "TenantName": "Имя арендатора", + "DisplayName:TenantName": "Имя арендатора", + "TenantDeletionConfirmationMessage": "Арендатор '{0}' будет удален. Вы подтверждаете это?", + "ConnectionStrings": "Строки подключения", + "DisplayName:DefaultConnectionString": "Строка подключения по умолчанию", + "DisplayName:UseSharedDatabase": "Использование общей базы данных", + "Permission:TenantManagement": "Управление арендаторами", + "Permission:Create": "Создать", + "Permission:Edit": "Редактировать", + "Permission:Delete": "Удалить", + "Permission:ManageConnectionStrings": "Управление строками подключения", + "Permission:ManageFeatures": "Управление функциями" + } +} From e967bcb80b743fb317308157039ff46e8c121e9d Mon Sep 17 00:00:00 2001 From: Roman Rybalko Date: Fri, 6 Mar 2020 21:54:23 +0300 Subject: [PATCH 044/334] Added ru.json for Volo.Abp.Account.Application.Contracts --- .../Account/Localization/Resources/ru.json | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 modules/account/src/Volo.Abp.Account.Application.Contracts/Volo/Abp/Account/Localization/Resources/ru.json diff --git a/modules/account/src/Volo.Abp.Account.Application.Contracts/Volo/Abp/Account/Localization/Resources/ru.json b/modules/account/src/Volo.Abp.Account.Application.Contracts/Volo/Abp/Account/Localization/Resources/ru.json new file mode 100644 index 0000000000..7f366bd782 --- /dev/null +++ b/modules/account/src/Volo.Abp.Account.Application.Contracts/Volo/Abp/Account/Localization/Resources/ru.json @@ -0,0 +1,45 @@ +{ + "culture": "ru", + "texts": { + "UserName": "Имя пользователя", + "EmailAddress": "Адрес электронной почты", + "UserNameOrEmailAddress": "Имя пользователя или адрес электронной почты", + "Password": "Пароль", + "RememberMe": "Запомнить меня", + "UseAnotherServiceToLogin": "Использовать сторонний сервис для входа", + "UserLockedOutMessage": "Пользователь заблокирован из-за большого количества попыток входа. Пожалуйста, попробуйте позднее.", + "InvalidUserNameOrPassword": "Неправильные имя пользователя и/или пароль!", + "LoginIsNotAllowed": "Вы не можете войти. Вам необходимо подтвердить электронную почту или телефон.", + "SelfRegistrationDisabledMessage": "Самостоятельная регистрация не предусмотрена. Пожалуйста, свяжитесь с администраром для получения доступа.", + "LocalLoginDisabledMessage": "Локальный вход отключен.", + "Login": "Войти", + "Cancel": "Отмена", + "Register": "Регистрация", + "AreYouANewUser": "Новый пользователь?", + "AlreadyRegistered": "Уже зарегистрированы?", + "InvalidLoginRequest": "Неправильный запрос", + "ThereAreNoLoginSchemesConfiguredForThisClient": "Не найдено схемы для входа с текущим клиентским приложением.", + "LogInUsingYourProviderAccount": "Войти использую свой {0} аккаунт", + "DisplayName:CurrentPassword": "Текущий пароль", + "DisplayName:NewPassword": "Новый пароль", + "DisplayName:NewPasswordConfirm": "Повторите новый пароль", + "PasswordChangedMessage": "Ваш пароль успешно изменен.", + "DisplayName:UserName": "Имя пользователя", + "DisplayName:Email": "Email", + "DisplayName:Name": "Имя", + "DisplayName:Surname": "Фамилия", + "DisplayName:Password": "Пароль", + "DisplayName:EmailAddress": "Электронная почта", + "DisplayName:PhoneNumber": "Номер телефона", + "PersonalSettings": "Персональные настройки", + "PersonalSettingsSaved": "Персональные настройки сохранены", + "PasswordChanged": "Пароль изменен", + "NewPasswordConfirmFailed": "Пожалуйста подтвердите новый пароль.", + "Manage": "Управление учетной записью", + "ManageYourProfile": "Настройки", + "DisplayName:Abp.Account.IsSelfRegistrationEnabled": "Самостоятельная регистрация включена", + "Description:Abp.Account.IsSelfRegistrationEnabled": "Позволяет новым пользователям регистрироваться самостоятельно.", + "DisplayName:Abp.Account.EnableLocalLogin": "Вход с помощью локальной учетной записи приложения", + "Description:Abp.Account.EnableLocalLogin": "Указывает на то, разрешено ли пользователям входить с помощью локальной учетной записи приложения." + } +} From 9a690afddf3b5c4a417ec414a1bbed1a6d2529db Mon Sep 17 00:00:00 2001 From: Roman Rybalko Date: Fri, 6 Mar 2020 13:33:13 +0300 Subject: [PATCH 045/334] Create ru.json for Volo.Abp.Validation --- .../Volo/Abp/Validation/Localization/ru.json | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 framework/src/Volo.Abp.Validation/Volo/Abp/Validation/Localization/ru.json diff --git a/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/Localization/ru.json b/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/Localization/ru.json new file mode 100644 index 0000000000..a2023691a8 --- /dev/null +++ b/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/Localization/ru.json @@ -0,0 +1,34 @@ +{ + "culture": "ru", + "texts": { + "'{0}' and '{1}' do not match.": "'{0}' и '{1}' не совпадают.", + "The {0} field is not a valid credit card number.": "The {0} field is not a valid credit card number.", + "{0} is not valid.": "{0} is not valid.", + "The {0} field is not a valid e-mail address.": "The {0} field is not a valid e-mail address.", + "The {0} field only accepts files with the following extensions: {1}": "The {0} field only accepts files with the following extensions: {1}", + "The field {0} must be a string or array type with a maximum length of '{1}'.": "The field {0} must be a string or array type with a maximum length of '{1}'.", + "The field {0} must be a string or array type with a minimum length of '{1}'.": "The field {0} must be a string or array type with a minimum length of '{1}'.", + "The {0} field is not a valid phone number.": "The {0} field is not a valid phone number.", + "The field {0} must be between {1} and {2}.": "The field {0} must be between {1} and {2}.", + "The field {0} must match the regular expression '{1}'.": "The field {0} must match the regular expression '{1}'.", + "The {0} field is required.": "The {0} field is required.", + "The field {0} must be a string with a maximum length of {1}.": "The field {0} must be a string with a maximum length of {1}.", + "The field {0} must be a string with a minimum length of {2} and a maximum length of {1}.": "The field {0} must be a string with a minimum length of {2} and a maximum length of {1}.", + "The {0} field is not a valid fully-qualified http, https, or ftp URL.": "The {0} field is not a valid fully-qualified http, https, or ftp URL.", + "The field {0} is invalid.": "The field {0} is invalid.", + "ThisFieldIsNotAValidCreditCardNumber.": "This field is not a valid credit card number.", + "ThisFieldIsNotValid.": "This field is not valid.", + "ThisFieldIsNotAValidEmailAddress.": "This field is not a valid e-mail address.", + "ThisFieldOnlyAcceptsFilesWithTheFollowingExtensions:{0}": "This field only accepts files with the following extensions: {0}", + "ThisFieldMustBeAStringOrArrayTypeWithAMaximumLengthoOf{0}": "This field must be a string or array type with a maximum length of '{0}'.", + "ThisFieldMustBeAStringOrArrayTypeWithAMinimumLengthOf{0}": "This field must be a string or array type with a minimum length of '{0}'.", + "ThisFieldIsNotAValidPhoneNumber.": "This field is not a valid phone number.", + "ThisFieldMustBeBetween{0}And{1}": "This field must be between {0} and {1}.", + "ThisFieldMustMatchTheRegularExpression{0}": "This field must match the regular expression '{0}'.", + "ThisFieldIsRequired.": "This field is required.", + "ThisFieldMustBeAStringWithAMaximumLengthOf{0}": "This field must be a string with a maximum length of {0}.", + "ThisFieldMustBeAStringWithAMinimumLengthOf{1}AndAMaximumLengthOf{0}": "This field must be a string with a minimum length of {1} and a maximum length of {0}.", + "ThisFieldIsNotAValidFullyQualifiedHttpHttpsOrFtpUrl": "This field is not a valid fully-qualified http, https, or ftp URL.", + "ThisFieldIsInvalid.": "This field is invalid." + } +} From d8a3d324a87280c7ed990e9dcc581bace3413eb4 Mon Sep 17 00:00:00 2001 From: Roman Rybalko Date: Fri, 6 Mar 2020 14:44:25 +0300 Subject: [PATCH 046/334] Update ru.json for Volo.Abp.Validation --- .../Volo/Abp/Validation/Localization/ru.json | 56 +++++++++---------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/Localization/ru.json b/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/Localization/ru.json index a2023691a8..6272fdf534 100644 --- a/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/Localization/ru.json +++ b/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/Localization/ru.json @@ -2,33 +2,33 @@ "culture": "ru", "texts": { "'{0}' and '{1}' do not match.": "'{0}' и '{1}' не совпадают.", - "The {0} field is not a valid credit card number.": "The {0} field is not a valid credit card number.", - "{0} is not valid.": "{0} is not valid.", - "The {0} field is not a valid e-mail address.": "The {0} field is not a valid e-mail address.", - "The {0} field only accepts files with the following extensions: {1}": "The {0} field only accepts files with the following extensions: {1}", - "The field {0} must be a string or array type with a maximum length of '{1}'.": "The field {0} must be a string or array type with a maximum length of '{1}'.", - "The field {0} must be a string or array type with a minimum length of '{1}'.": "The field {0} must be a string or array type with a minimum length of '{1}'.", - "The {0} field is not a valid phone number.": "The {0} field is not a valid phone number.", - "The field {0} must be between {1} and {2}.": "The field {0} must be between {1} and {2}.", - "The field {0} must match the regular expression '{1}'.": "The field {0} must match the regular expression '{1}'.", - "The {0} field is required.": "The {0} field is required.", - "The field {0} must be a string with a maximum length of {1}.": "The field {0} must be a string with a maximum length of {1}.", - "The field {0} must be a string with a minimum length of {2} and a maximum length of {1}.": "The field {0} must be a string with a minimum length of {2} and a maximum length of {1}.", - "The {0} field is not a valid fully-qualified http, https, or ftp URL.": "The {0} field is not a valid fully-qualified http, https, or ftp URL.", - "The field {0} is invalid.": "The field {0} is invalid.", - "ThisFieldIsNotAValidCreditCardNumber.": "This field is not a valid credit card number.", - "ThisFieldIsNotValid.": "This field is not valid.", - "ThisFieldIsNotAValidEmailAddress.": "This field is not a valid e-mail address.", - "ThisFieldOnlyAcceptsFilesWithTheFollowingExtensions:{0}": "This field only accepts files with the following extensions: {0}", - "ThisFieldMustBeAStringOrArrayTypeWithAMaximumLengthoOf{0}": "This field must be a string or array type with a maximum length of '{0}'.", - "ThisFieldMustBeAStringOrArrayTypeWithAMinimumLengthOf{0}": "This field must be a string or array type with a minimum length of '{0}'.", - "ThisFieldIsNotAValidPhoneNumber.": "This field is not a valid phone number.", - "ThisFieldMustBeBetween{0}And{1}": "This field must be between {0} and {1}.", - "ThisFieldMustMatchTheRegularExpression{0}": "This field must match the regular expression '{0}'.", - "ThisFieldIsRequired.": "This field is required.", - "ThisFieldMustBeAStringWithAMaximumLengthOf{0}": "This field must be a string with a maximum length of {0}.", - "ThisFieldMustBeAStringWithAMinimumLengthOf{1}AndAMaximumLengthOf{0}": "This field must be a string with a minimum length of {1} and a maximum length of {0}.", - "ThisFieldIsNotAValidFullyQualifiedHttpHttpsOrFtpUrl": "This field is not a valid fully-qualified http, https, or ftp URL.", - "ThisFieldIsInvalid.": "This field is invalid." + "The {0} field is not a valid credit card number.": "Поле {0} не содержит действительный номер кредитной карты.", + "{0} is not valid.": "Значение {0} недействительно.", + "The {0} field is not a valid e-mail address.": "Поле {0} не содержит действительный адрес электронной почты.", + "The {0} field only accepts files with the following extensions: {1}": "В поле {0} вы можете загрузить файлы следующих форматов: {1}", + "The field {0} must be a string or array type with a maximum length of '{1}'.": "Поле {0} должно иметь тип строки или массива с максимальной длиной '{1}'.", + "The field {0} must be a string or array type with a minimum length of '{1}'.": "Поле {0} должно иметь тип строки или массива с минимальной длиной '{1}'.", + "The {0} field is not a valid phone number.": "Поле {0} не содержит действительный номер телефона.", + "The field {0} must be between {1} and {2}.": "Поле {0} должно находиться между {1} и {2}.", + "The field {0} must match the regular expression '{1}'.": "Поле {0} должно соответствовать регулярному выражению '{1}'.", + "The {0} field is required.": "Поле {0} необходимо заполнить.", + "The field {0} must be a string with a maximum length of {1}.": "Поле {0} должно быть строкой с максимальной длиной {1}.", + "The field {0} must be a string with a minimum length of {2} and a maximum length of {1}.": "Поле {0} должно быть строкой с минимальной длиной {2} и максимальной длиной {1}.", + "The {0} field is not a valid fully-qualified http, https, or ftp URL.": "Поле {0} не является действительным полным http, https или ftp адресом.", + "The field {0} is invalid.": "Значение в поле {0} недопустимо.", + "ThisFieldIsNotAValidCreditCardNumber.": "Это поле не содержит действительный номер кредитной карты.", + "ThisFieldIsNotValid.": "Значение в этом поле недействительно.", + "ThisFieldIsNotAValidEmailAddress.": "Это поле не содержит действительный адрес электронной почты.", + "ThisFieldOnlyAcceptsFilesWithTheFollowingExtensions:{0}": "Вы можете загрузить файлы только следующих форматов: {0}", + "ThisFieldMustBeAStringOrArrayTypeWithAMaximumLengthoOf{0}": "Это поле должно иметь тип строки или массива с максимальной длиной '{0}'.", + "ThisFieldMustBeAStringOrArrayTypeWithAMinimumLengthOf{0}": "Это поле должно иметь тип строки или массива с минимальной длиной '{0}'.", + "ThisFieldIsNotAValidPhoneNumber.": "Это поле не содержит действительный номер телефона.", + "ThisFieldMustBeBetween{0}And{1}": "Это поле должно быть между {0} и {1}.", + "ThisFieldMustMatchTheRegularExpression{0}": "Это поле должно соответствовать регулярному выражению '{0}'.", + "ThisFieldIsRequired.": "Это обязательное поле.", + "ThisFieldMustBeAStringWithAMaximumLengthOf{0}": "Это поле должно быть строкой с максимальной длиной {0}.", + "ThisFieldMustBeAStringWithAMinimumLengthOf{1}AndAMaximumLengthOf{0}": "Это поле должно быть строкой с минимальной длиной {1} и максимальной длиной {0}.", + "ThisFieldIsNotAValidFullyQualifiedHttpHttpsOrFtpUrl": "Значение в поле не является действительным полным http, https или ftp адресом.", + "ThisFieldIsInvalid.": "Значение в этом поле недопустимо." } } From b558021f5adece98207d1d97f66e77b5ac5b894d Mon Sep 17 00:00:00 2001 From: Roman Rybalko Date: Fri, 6 Mar 2020 15:27:18 +0300 Subject: [PATCH 047/334] Create ru.json for Volo.Abp.UI --- .../Localization/Resources/AbpUi/ru.json | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/ru.json diff --git a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/ru.json b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/ru.json new file mode 100644 index 0000000000..7b48db1a3a --- /dev/null +++ b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/ru.json @@ -0,0 +1,62 @@ +{ + "culture": "ru", + "texts": { + "InternalServerErrorMessage": "Во время запроса произошла внутренняя ошибка!", + "ValidationErrorMessage": "Ваш запрос недействителен!", + "ValidationNarrativeErrorMessageTitle": "При проверке были обнаружены следующие ошибки.", + "DefaultErrorMessage": "Произошла ошибка!", + "DefaultErrorMessageDetail": "Сведения об ошибке не были предоставлены сервером.", + "DefaultErrorMessage401": "Вы не авторизированы!", + "DefaultErrorMessage401Detail": "Вы должны Войти, чтобы выполнить эту операцию.", + "DefaultErrorMessage403": "Вы не авторизованы!", + "DefaultErrorMessage403Detail": "У вас нет доступа к выполнению этой операции!", + "DefaultErrorMessage404": "Ресурс не найден!", + "DefaultErrorMessage404Detail": "Запрошенный ресурс не удалось найти на сервере!", + "EntityNotFoundErrorMessage": "Нет объекта {0} с id = {1}!", + "Languages": "Языки", + "Error": "Ошибка", + "AreYouSure": "Вы уверены?", + "Cancel": "Отмена", + "Yes": "Да", + "No": "Нет", + "Ok": "ОК", + "Close": "Закрыть", + "Save": "Сохранить", + "SavingWithThreeDot": "Сохранение...", + "Actions": "Действия", + "Delete": "Удалить", + "Edit": "Редактировать", + "Refresh": "Обновить", + "Language": "Язык", + "LoadMore": "Загрузить еще", + "ProcessingWithThreeDot": "Обработка...", + "LoadingWithThreeDot": "Загрузка...", + "Welcome": "Добро пожаловать", + "Login": "Войти", + "Register": "Зарегистрироваться", + "Logout": "Выйти", + "Submit": "Подтвердить", + "Back": "Назад", + "PagerSearch": "Поиск", + "PagerNext": "Следующее", + "PagerPrevious": "Предыдущее", + "PagerFirst": "Первая", + "PagerLast": "Последняя", + "PagerInfo": "Записи с _START_ до _END_ из _TOTAL_ записей", + "PagerInfoEmpty": "Записи с 0 до 0 из 0 записей.", + "PagerInfoFiltered": "(отфильтровано из _MAX_ записей)", + "NoDataAvailableInDatatable": "Данные в таблице отсутствуют", + "PagerShowMenuEntries": "Показать _MENU_ записей", + "DatatableActionDropdownDefaultText": "Действия", + "ChangePassword": "Изменить пароль", + "PersonalInfo": "Мой профиль", + "AreYouSureYouWantToCancelEditingWarningMessage": "У вас есть несохраненные изменения.", + "UnhandledException": "Непредвиденная ошибка!", + "401Message": "Неавторизованный", + "403Message": "В доступе отказано", + "404Message": "Страница не найдена", + "500Message": "Внутренняя ошибка сервера", + "GoHomePage": "Вернуться на главную страницу", + "GoBack": "Вернуться назад" + } +} From fe00608d6df0b45e422a3b6279cba81c392d2716 Mon Sep 17 00:00:00 2001 From: Roman Rybalko Date: Fri, 6 Mar 2020 15:55:59 +0300 Subject: [PATCH 048/334] Create ru.json for Volo.Abp.UI.Navigation --- .../Volo/Abp/Ui/Navigation/Localization/Resource/ru.json | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/Localization/Resource/ru.json diff --git a/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/Localization/Resource/ru.json b/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/Localization/Resource/ru.json new file mode 100644 index 0000000000..2a76578396 --- /dev/null +++ b/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/Localization/Resource/ru.json @@ -0,0 +1,6 @@ +{ + "culture": "ru", + "texts": { + "Menu:Administration": "Администрирование" + } +} From 1edb1e237be4b70f1c3e05a99d7255657a9113f9 Mon Sep 17 00:00:00 2001 From: Roman Rybalko Date: Fri, 6 Mar 2020 16:18:32 +0300 Subject: [PATCH 049/334] Create ru.json for Volo.Abp.Localization --- .../Abp/Localization/Resources/AbpLocalization/ru.json | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 framework/src/Volo.Abp.Localization/Volo/Abp/Localization/Resources/AbpLocalization/ru.json diff --git a/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/Resources/AbpLocalization/ru.json b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/Resources/AbpLocalization/ru.json new file mode 100644 index 0000000000..3f00c8994b --- /dev/null +++ b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/Resources/AbpLocalization/ru.json @@ -0,0 +1,7 @@ +{ + "culture": "ru", + "texts": { + "DisplayName:Abp.Localization.DefaultLanguage": "Язык по умолчанию", + "Description:Abp.Localization.DefaultLanguage": "Язык приложения по умолчанию." + } +} From c8d8cda55aa5ba831237fe1c56144e6008720e99 Mon Sep 17 00:00:00 2001 From: Roman Rybalko Date: Fri, 6 Mar 2020 16:59:59 +0300 Subject: [PATCH 050/334] Create ru.json for Volo.Abp.Emailing --- .../Volo/Abp/Emailing/Localization/ru.json | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Localization/ru.json diff --git a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Localization/ru.json b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Localization/ru.json new file mode 100644 index 0000000000..249baa61b2 --- /dev/null +++ b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Localization/ru.json @@ -0,0 +1,23 @@ +{ + "culture": "ru", + "texts": { + "DisplayName:Abp.Mailing.DefaultFromAddress": "Адрес отправления по умолчанию", + "DisplayName:Abp.Mailing.DefaultFromDisplayName": "Имя отправителя по умолчанию", + "DisplayName:Abp.Mailing.Smtp.Host": "Сервер", + "DisplayName:Abp.Mailing.Smtp.Port": "Порт", + "DisplayName:Abp.Mailing.Smtp.UserName": "Имя пользователя", + "DisplayName:Abp.Mailing.Smtp.Password": "Пароль", + "DisplayName:Abp.Mailing.Smtp.Domain": "Домен", + "DisplayName:Abp.Mailing.Smtp.EnableSsl": "Включить SSL", + "DisplayName:Abp.Mailing.Smtp.UseDefaultCredentials": "Использовать учетные данные по умолчанию", + "Description:Abp.Mailing.DefaultFromAddress": "Отправление по умолчанию от адреса.", + "Description:Abp.Mailing.DefaultFromDisplayName": "Имя отправителя по умолчанию.", + "Description:Abp.Mailing.Smtp.Host": "Имя или IP- адрес сервера, используемого для отправки по протоколу SMTP.", + "Description:Abp.Mailing.Smtp.Port": "Порт, используемый для отправки по протоколу SMTP.", + "Description:Abp.Mailing.Smtp.UserName": "Имя пользователя для SMTP-сервера.", + "Description:Abp.Mailing.Smtp.Password": "Пароль для SMTP-сервера.", + "Description:Abp.Mailing.Smtp.Domain": "Домен или имя компьютера, от которого производится SMTP-запрос.", + "Description:Abp.Mailing.Smtp.EnableSsl": "Использовать SSL для подключения к SMTP-серверу.", + "Description:Abp.Mailing.Smtp.UseDefaultCredentials": "Использовать учетные данные для SMTP по умолчанию." + } +} From 4fa0f1e5806d75517f0701bc15c1c302f737492c Mon Sep 17 00:00:00 2001 From: Roman Rybalko Date: Fri, 6 Mar 2020 17:09:55 +0300 Subject: [PATCH 051/334] Added ru.json For Volo.Abp.Ddd.Application.Contracts --- .../Abp/Application/Localization/Resources/AbpDdd/ru.json | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Localization/Resources/AbpDdd/ru.json diff --git a/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Localization/Resources/AbpDdd/ru.json b/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Localization/Resources/AbpDdd/ru.json new file mode 100644 index 0000000000..b84f77f8b3 --- /dev/null +++ b/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Localization/Resources/AbpDdd/ru.json @@ -0,0 +1,6 @@ +{ + "culture": "ru", + "texts": { + "MaxResultCountExceededExceptionMessage": "{0} не может быть больше {1}! Увеличьте {2}.{3} на стороне сервера, чтобы получить больше результатов." + } +} From 5269468ce04da4f06b0d866dff2729ac2d14d135 Mon Sep 17 00:00:00 2001 From: Roman Rybalko Date: Fri, 6 Mar 2020 18:12:11 +0300 Subject: [PATCH 052/334] Create ru.json for Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy --- .../Mvc/UI/MultiTenancy/Localization/ru.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/ru.json diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/ru.json b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/ru.json new file mode 100644 index 0000000000..04b2e5cf85 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/ru.json @@ -0,0 +1,12 @@ +{ + "culture": "ru", + "texts": { + "GivenTenantIsNotAvailable": "Данный арендатор недоступен: {0}", + "Tenant": "Арендатор", + "Switch": "переключиться", + "Name": "Имя", + "SwitchTenantHint": "Оставьте поле Имя пустым, чтобы переключиться на администратора.", + "SwitchTenant": "Сменить арендатора", + "NotSelected": "Не выбрано" + } +} From 6cad7ce02ab831ca9a8a9e60d3752e5786cc6654 Mon Sep 17 00:00:00 2001 From: Roman Rybalko Date: Fri, 6 Mar 2020 18:38:13 +0300 Subject: [PATCH 053/334] Create ru.json for Volo.Blogging.Domain.Shared --- .../Blogging/Localization/Resources/ru.json | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 modules/blogging/src/Volo.Blogging.Domain.Shared/Volo/Blogging/Localization/Resources/ru.json diff --git a/modules/blogging/src/Volo.Blogging.Domain.Shared/Volo/Blogging/Localization/Resources/ru.json b/modules/blogging/src/Volo.Blogging.Domain.Shared/Volo/Blogging/Localization/Resources/ru.json new file mode 100644 index 0000000000..898d363cef --- /dev/null +++ b/modules/blogging/src/Volo.Blogging.Domain.Shared/Volo/Blogging/Localization/Resources/ru.json @@ -0,0 +1,47 @@ +{ + "culture": "ru", + "texts": { + "Menu:Blogs": "Блоги", + "Menu:BlogManagement": "Управление блогом", + "Title": "Заголовок", + "Delete": "Удалить", + "Reply": "Ответить", + "ReplyTo": "Ответить {0}", + "ContinueReading": "Продолжить чтение", + "DaysAgo": "{0} дней назад", + "YearsAgo": "{0} лет назад", + "MonthsAgo": "{0} месяцев назад", + "WeeksAgo": "{0} недель назад", + "MinutesAgo": "{0} минут назад", + "SecondsAgo": "{0} секунд назад", + "HoursAgo": "{0} часов назад", + "Now": "сейчас", + "Content": "Содержание", + "SeeAll": "Увидеть все", + "PopularTags": "Популярные тэги", + "WiewsWithCount": "{0} просмотров", + "LastPosts": "Последние записи", + "LeaveComment": "Оставить комментарий", + "TagsInThisArticle": "Теги в этой статье", + "Posts": "Записи", + "Edit": "Редактировать", + "BLOG": "БЛОГ", + "CommentDeletionWarningMessage": "Комментарий будет удален.", + "PostDeletionWarningMessage": "Запись будет удалена.", + "BlogDeletionWarningMessage": "Блог будет удален.", + "AreYouSure": "Вы уверены?", + "CommentWithCount": "{0} комментариев", + "Comment": "Комментарий", + "ShareOnTwitter": "Поделиться в Twitter", + "CoverImage": "Обложка", + "CreateANewPost": "Создать новый пост", + "CreateANewBlog": "Создать новый блог", + "WhatIsNew": "Что нового?", + "Name": "Имя", + "ShortName": "Фамилия", + "CreationTime": "Время создания", + "Description": "Описание", + "Blogs": "Блоги", + "Tags": "Теги" + } +} From 1c04dce4a37561e982b1599d4209cdd4c0322339 Mon Sep 17 00:00:00 2001 From: Roman Rybalko Date: Fri, 6 Mar 2020 19:07:54 +0300 Subject: [PATCH 054/334] Added ru.json for Volo.Docs.Admin.Application.Contracts --- .../Docs/ApplicationContracts/ru.json | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Localization/Resources/Docs/ApplicationContracts/ru.json diff --git a/modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Localization/Resources/Docs/ApplicationContracts/ru.json b/modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Localization/Resources/Docs/ApplicationContracts/ru.json new file mode 100644 index 0000000000..ba2680892c --- /dev/null +++ b/modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Localization/Resources/Docs/ApplicationContracts/ru.json @@ -0,0 +1,37 @@ +{ + "culture": "ru", + "texts": { + "Permission:DocumentManagement": "Управление документацией", + "Permission:Projects": "Проекты", + "Permission:Edit": "Редактировать", + "Permission:Delete": "Удалить", + "Permission:Create": "Создать", + "Permission:Documents": "Документы", + "Menu:DocumentManagement": "Документы", + "Menu:ProjectManagement": "Проекты", + "CreateANewProject": "Создать проекты", + "Edit": "Редактировать", + "Create": "Создать", + "Pull": "Получить", + "Projects": "Проекты", + "Name": "Название", + "ShortName": "Сокращенное название", + "DocumentStoreType": "Тип системы хранения", + "Format": "Формат", + "ShortNameInfoText": "Будет использоваться для уникального URL.", + "DisplayName:Name": "Название", + "DisplayName:ShortName": "Сокращенное название", + "DisplayName:Format": "Формат", + "DisplayName:DefaultDocumentName": "Имя документа по умолчанию", + "DisplayName:NavigationDocumentName": "Имя документа для навигации", + "DisplayName:MinimumVersion": "Минимальная версия", + "DisplayName:MainWebsiteUrl": "URL основного веб-сайта", + "DisplayName:LatestVersionBranchName": "Название ветки последней версии", + "DisplayName:GitHubRootUrl": "Корневой URL-адрес GitHub", + "DisplayName:GitHubAccessToken": "Маркер доступа для GitHub", + "DisplayName:GitHubUserAgent": "Заголовок User-Agent для GitHub", + "DisplayName:All": "Получить все", + "DisplayName:LanguageCode": "Код языка", + "DisplayName:Version": "Версия" + } +} From bb9ab67e765b82b047417036c79842ac39db2f93 Mon Sep 17 00:00:00 2001 From: Roman Rybalko Date: Fri, 6 Mar 2020 19:24:34 +0300 Subject: [PATCH 055/334] Added ru.json for VoloDocs.Web --- .../Localization/Resources/VoloDocs/Web/ru.json | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 modules/docs/app/VoloDocs.Web/Localization/Resources/VoloDocs/Web/ru.json diff --git a/modules/docs/app/VoloDocs.Web/Localization/Resources/VoloDocs/Web/ru.json b/modules/docs/app/VoloDocs.Web/Localization/Resources/VoloDocs/Web/ru.json new file mode 100644 index 0000000000..e0e5094cc1 --- /dev/null +++ b/modules/docs/app/VoloDocs.Web/Localization/Resources/VoloDocs/Web/ru.json @@ -0,0 +1,10 @@ +{ + "culture": "ru", + "texts": { + "DocsTitle": "VoloDocs", + "WelcomeVoloDocs": "Добро пожаловать в VoloDocs!", + "NoProjectWarning": "Отсутствует определение проекта!", + "CreateYourFirstProject": "Нажмите здесь, чтобы добавить свой первый проект", + "NoProject": "Нет проекта!" + } +} From 728c05903b2588026bf810cd65d80c271b06f63a Mon Sep 17 00:00:00 2001 From: Roman Rybalko Date: Fri, 6 Mar 2020 19:28:54 +0300 Subject: [PATCH 056/334] Added ru.json for Volo.Abp.FeatureManagement.Domain.Shared --- .../Volo/Abp/FeatureManagement/Localization/Domain/ru.json | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/ru.json diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/ru.json b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/ru.json new file mode 100644 index 0000000000..3945762269 --- /dev/null +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/ru.json @@ -0,0 +1,7 @@ +{ + "culture": "ru", + "texts": { + "Features": "Функциональные возможности", + "NoFeatureFoundMessage": "Нет доступных функциональных возможностей." + } +} From 22f28fb0f04f326aa46b1870e875a7c75f1da0bc Mon Sep 17 00:00:00 2001 From: Roman Rybalko Date: Fri, 6 Mar 2020 21:04:22 +0300 Subject: [PATCH 057/334] Added ru.json for Volo.Abp.IdentityServer.Domain.Shared --- .../IdentityServer/Localization/Resources/ru.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 modules/identityserver/src/Volo.Abp.IdentityServer.Domain.Shared/Volo/Abp/IdentityServer/Localization/Resources/ru.json diff --git a/modules/identityserver/src/Volo.Abp.IdentityServer.Domain.Shared/Volo/Abp/IdentityServer/Localization/Resources/ru.json b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain.Shared/Volo/Abp/IdentityServer/Localization/Resources/ru.json new file mode 100644 index 0000000000..808962d8e5 --- /dev/null +++ b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain.Shared/Volo/Abp/IdentityServer/Localization/Resources/ru.json @@ -0,0 +1,12 @@ +{ + "culture": "ru", + "texts": { + "Volo.IdentityServer:DuplicateIdentityResourceName": "Имя ресурса идентификации уже существует: {Name}", + "Volo.IdentityServer:DuplicateApiResourceName": "Имя ресурса API уже существует: {Name}", + "Volo.IdentityServer:DuplicateClientId": "Параметр ClientID уже существует: {ClientId}", + "UserLockedOut": "Учетная запись пользователя была заблокирована из-за неудачных попыток входа в систему. Пожалуйста, попробуйте позже.", + "InvalidUserNameOrPassword": "Неверное имя пользователя или пароль!", + "LoginIsNotAllowed": "У вас нет разрешения на вход в систему. Необходимо подтвердить свой адрес электронной почты/номер телефона.", + "InvalidUsername": "Неверное имя пользователя или пароль!" + } +} From b78a4923b29de5f6c733162ef9ef5fdbb6bdcf52 Mon Sep 17 00:00:00 2001 From: Roman Rybalko Date: Fri, 6 Mar 2020 21:24:03 +0300 Subject: [PATCH 058/334] Added ru.json for Volo.Abp.Identity.Domain.Shared --- .../Volo/Abp/Identity/Localization/ru.json | 102 ++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ru.json diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ru.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ru.json new file mode 100644 index 0000000000..1df7b63bfe --- /dev/null +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ru.json @@ -0,0 +1,102 @@ +{ + "culture": "ru", + "texts": { + "Menu:IdentityManagement": "Управление идентификацией", + "Users": "Пользователи", + "NewUser": "Новый пользователь", + "UserName": "Имя пользователя", + "EmailAddress": "Адрес электронной почты", + "PhoneNumber": "Номер телефона", + "UserInformations": "Информация о пользователе", + "DisplayName:IsDefault": "По умолчанию", + "DisplayName:IsStatic": "Статичная", + "DisplayName:IsPublic": "Доступно", + "Roles": "Роли", + "Password": "Пароль", + "PersonalInfo": "Мой профиль", + "PersonalSettings": "Персональные настройки", + "UserDeletionConfirmationMessage": "Пользователь '{0}' будет удален. Вы подтверждаете это?", + "RoleDeletionConfirmationMessage": "Роль '{0}' будет удалена. Вы подтверждаете это?", + "DisplayName:RoleName": "Название роли", + "DisplayName:UserName": "Имя пользователя", + "DisplayName:Name": "Имя", + "DisplayName:Surname": "Фамилия", + "DisplayName:Password": "Пароль", + "DisplayName:Email": "Адрес электронной почты", + "DisplayName:PhoneNumber": "Номер телефона", + "DisplayName:TwoFactorEnabled": "Двухфакторная проверка подлинности", + "DisplayName:LockoutEnabled": "Заблокировать учетную запись после неудачных попыток входа", + "NewRole": "Новая роль", + "RoleName": "Имя роли", + "CreationTime": "Время создания", + "Permissions": "Разрешения", + "DisplayName:CurrentPassword": "Текущий пароль", + "DisplayName:NewPassword": "Новый пароль", + "DisplayName:NewPasswordConfirm": "Подтверждение нового пароля", + "PasswordChangedMessage": "Ваш пароль был успешно изменен.", + "PersonalSettingsSavedMessage": "Ваши персональные настройки были успешно сохранены.", + "Identity.DefaultError": "Возникла непредвиденная ошибка.", + "Identity.ConcurrencyFailure": "Ошибка оптимального управления многопоточностью, объект был изменен.", + "Identity.DuplicateEmail": "Электронная почта '{0}' уже зарегистрирована.", + "Identity.DuplicateRoleName": "Имя роли '{0}' уже занято.", + "Identity.DuplicateUserName": "Имя пользователя '{0}' уже занято.", + "Identity.InvalidEmail": "Адрес электронной почты '{0}' недействителен.", + "Identity.InvalidPasswordHasherCompatibilityMode": "Предоставленный PasswordHasherCompatibilityMode недействителен.", + "Identity.InvalidPasswordHasherIterationCount": "Число итераций должно быть положительным целым числом.", + "Identity.InvalidRoleName": "Имя роли '{0}' недопустимо.", + "Identity.InvalidToken": "Недопустимый маркер.", + "Identity.InvalidUserName": "Имя пользователя '{0}' недопустимо и может содержать только буквы или цифры.", + "Identity.LoginAlreadyAssociated": "Пользователь с таким логином уже существует.", + "Identity.PasswordMismatch": "Неверный пароль.", + "Identity.PasswordRequiresDigit": "Пароль должен содержать по крайней мере одну цифру.", + "Identity.PasswordRequiresLower": "Пароль должен содержать хотя бы одну строчную букву.", + "Identity.PasswordRequiresNonAlphanumeric": "Пароль должен иметь по крайней мере один не буквенно-цифровой символ.", + "Identity.PasswordRequiresUpper": "Пароль должен иметь хотя бы одну букву верхнего регистра.", + "Identity.PasswordTooShort": "Пароль должен содержать не менее {0} символов.", + "Identity.RoleNotFound": "Роль {0} не существует.", + "Identity.UserAlreadyHasPassword": "У пользователя уже установлен пароль.", + "Identity.UserAlreadyInRole": "Пользователь уже имеет роль '{0}'.", + "Identity.UserLockedOut": "Пользователь временно заблокирован.", + "Identity.UserLockoutNotEnabled": "Блокировка не активирована для этого пользователя.", + "Identity.UserNameNotFound": "Пользователь {0} не существует.", + "Identity.UserNotInRole": "Пользователь не имеет роль '{0}'.", + "Identity.PasswordConfirmationFailed": "Пароли не совпадают.", + "Identity.StaticRoleRenamingErrorMessage": "Статические роли не могут быть переименованы.", + "Identity.StaticRoleDeletionErrorMessage": "Статические роли не могут быть удалены.", + "Volo.Abp.Identity:010001": "Вы не можете удалить свой собственный аккаунт!", + "Permission:IdentityManagement": "Управление идентификацией", + "Permission:RoleManagement": "Управление ролями", + "Permission:Create": "Создать", + "Permission:Edit": "Редактировать", + "Permission:Delete": "Удалить", + "Permission:ChangePermissions": "Изменить разрешения", + "Permission:UserManagement": "Управление пользователями", + "Permission:UserLookup": "Поиск пользователя", + "DisplayName:Abp.Identity.Password.RequiredLength": "Требуемая длина", + "DisplayName:Abp.Identity.Password.RequiredUniqueChars": "Обязательное количество уникальных символов", + "DisplayName:Abp.Identity.Password.RequireNonAlphanumeric": "Обязательный не буквенно-цифровой символ", + "DisplayName:Abp.Identity.Password.RequireLowercase": "Обязательный символ нижнего регистра", + "DisplayName:Abp.Identity.Password.RequireUppercase": "Обязательный символ верхнего регистра", + "DisplayName:Abp.Identity.Password.RequireDigit": "Требуемая цифра", + "DisplayName:Abp.Identity.Lockout.AllowedForNewUsers": "Включено для новых пользователей", + "DisplayName:Abp.Identity.Lockout.LockoutDuration": "Длительность блокировки (секунды)", + "DisplayName:Abp.Identity.Lockout.MaxFailedAccessAttempts": "Максимальное количество неудачных попыток доступа", + "DisplayName:Abp.Identity.SignIn.RequireConfirmedEmail": "Требуется подтверждение электронной почты", + "DisplayName:Abp.Identity.SignIn.RequireConfirmedPhoneNumber": "Требуется подтверждение номера телефона", + "DisplayName:Abp.Identity.User.IsUserNameUpdateEnabled": "Пользователь может изменять имя", + "DisplayName:Abp.Identity.User.IsEmailUpdateEnabled": "Электронная почта может быть изменена", + "Description:Abp.Identity.Password.RequiredLength": "Минимальная длина пароля.", + "Description:Abp.Identity.Password.RequiredUniqueChars": "Минимальное количество уникальных символов, которые должен содержать пароль.", + "Description:Abp.Identity.Password.RequireNonAlphanumeric": "Если пароли должны содержать не буквенно- цифровой символ.", + "Description:Abp.Identity.Password.RequireLowercase": "Если пароли должны содержать строчные символы ASCII.", + "Description:Abp.Identity.Password.RequireUppercase": "Если пароли должны содержать символ ASCII в верхнем регистре.", + "Description:Abp.Identity.Password.RequireDigit": "Если пароли должны содержать цифру.", + "Description:Abp.Identity.Lockout.AllowedForNewUsers": "Может ли новый пользователь быть заблокирован.", + "Description:Abp.Identity.Lockout.LockoutDuration": "Длительность блокировки пользователя.", + "Description:Abp.Identity.Lockout.MaxFailedAccessAttempts": "Число неудачных попыток доступа, после которых пользователь будет заблокирован.", + "Description:Abp.Identity.SignIn.RequireConfirmedEmail": "Требуется ли для входа подтвержденный адрес электронной почты.", + "Description:Abp.Identity.SignIn.RequireConfirmedPhoneNumber": "Требуется ли для входа в систему подтвержденный номер телефона.", + "Description:Abp.Identity.User.IsUserNameUpdateEnabled": "Может ли пользователь обновить имя пользователя.", + "Description:Abp.Identity.User.IsEmailUpdateEnabled": "Может ли электронная почта быть обновлена пользователем." + } +} From 9900e15dfeb65f0d01359520dbb4a99ee06fdc05 Mon Sep 17 00:00:00 2001 From: Roman Rybalko Date: Fri, 6 Mar 2020 21:33:17 +0300 Subject: [PATCH 059/334] Added ru.json for Volo.Abp.PermissionManagement.Domain.Shared --- .../PermissionManagement/Localization/Domain/ru.json | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/ru.json diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/ru.json b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/ru.json new file mode 100644 index 0000000000..33291e66a0 --- /dev/null +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/ru.json @@ -0,0 +1,10 @@ +{ + "culture": "ru", + "texts": { + "Permissions": "Разрешения", + "OnlyProviderPermissons": "Только этот провайдер", + "All": "Все", + "SelectAllInAllTabs": "Предоставить все разрешения", + "SelectAllInThisTab": "Выбрать все" + } +} From f69c5138923244f00e434ec0bf137352fc130b86 Mon Sep 17 00:00:00 2001 From: Roman Rybalko Date: Fri, 6 Mar 2020 21:35:57 +0300 Subject: [PATCH 060/334] Added ru.json for Volo.Abp.SettingManagement.Domain.Shared --- .../Localization/Resources/AbpSettingManagement/ru.json | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/Localization/Resources/AbpSettingManagement/ru.json diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/Localization/Resources/AbpSettingManagement/ru.json b/modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/Localization/Resources/AbpSettingManagement/ru.json new file mode 100644 index 0000000000..3b23b1d04a --- /dev/null +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/Localization/Resources/AbpSettingManagement/ru.json @@ -0,0 +1,7 @@ +{ + "culture": "ru", + "texts": { + "Settings": "Настройки", + "SuccessfullySaved": "Успешно сохранено" + } +} From a905ae45ec0348688f6443a457cfcafc5e53ac9d Mon Sep 17 00:00:00 2001 From: Roman Rybalko Date: Fri, 6 Mar 2020 21:40:53 +0300 Subject: [PATCH 061/334] Added ru.json for Volo.Abp.TenantManagement.Domain.Shared --- .../Localization/Resources/ru.json | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 modules/tenant-management/src/Volo.Abp.TenantManagement.Domain.Shared/Volo/Abp/TenantManagement/Localization/Resources/ru.json diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain.Shared/Volo/Abp/TenantManagement/Localization/Resources/ru.json b/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain.Shared/Volo/Abp/TenantManagement/Localization/Resources/ru.json new file mode 100644 index 0000000000..dd8f0c3847 --- /dev/null +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain.Shared/Volo/Abp/TenantManagement/Localization/Resources/ru.json @@ -0,0 +1,20 @@ +{ + "culture": "ru", + "texts": { + "Menu:TenantManagement": "Управление арендаторами", + "Tenants": "Арендаторы", + "NewTenant": "Новый арендатор", + "TenantName": "Имя арендатора", + "DisplayName:TenantName": "Имя арендатора", + "TenantDeletionConfirmationMessage": "Арендатор '{0}' будет удален. Вы подтверждаете это?", + "ConnectionStrings": "Строки подключения", + "DisplayName:DefaultConnectionString": "Строка подключения по умолчанию", + "DisplayName:UseSharedDatabase": "Использование общей базы данных", + "Permission:TenantManagement": "Управление арендаторами", + "Permission:Create": "Создать", + "Permission:Edit": "Редактировать", + "Permission:Delete": "Удалить", + "Permission:ManageConnectionStrings": "Управление строками подключения", + "Permission:ManageFeatures": "Управление функциями" + } +} From 03215c2114b32b98ef427e00187dcf72b2d97407 Mon Sep 17 00:00:00 2001 From: Roman Rybalko Date: Fri, 6 Mar 2020 21:54:23 +0300 Subject: [PATCH 062/334] Added ru.json for Volo.Abp.Account.Application.Contracts --- .../Account/Localization/Resources/ru.json | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 modules/account/src/Volo.Abp.Account.Application.Contracts/Volo/Abp/Account/Localization/Resources/ru.json diff --git a/modules/account/src/Volo.Abp.Account.Application.Contracts/Volo/Abp/Account/Localization/Resources/ru.json b/modules/account/src/Volo.Abp.Account.Application.Contracts/Volo/Abp/Account/Localization/Resources/ru.json new file mode 100644 index 0000000000..7f366bd782 --- /dev/null +++ b/modules/account/src/Volo.Abp.Account.Application.Contracts/Volo/Abp/Account/Localization/Resources/ru.json @@ -0,0 +1,45 @@ +{ + "culture": "ru", + "texts": { + "UserName": "Имя пользователя", + "EmailAddress": "Адрес электронной почты", + "UserNameOrEmailAddress": "Имя пользователя или адрес электронной почты", + "Password": "Пароль", + "RememberMe": "Запомнить меня", + "UseAnotherServiceToLogin": "Использовать сторонний сервис для входа", + "UserLockedOutMessage": "Пользователь заблокирован из-за большого количества попыток входа. Пожалуйста, попробуйте позднее.", + "InvalidUserNameOrPassword": "Неправильные имя пользователя и/или пароль!", + "LoginIsNotAllowed": "Вы не можете войти. Вам необходимо подтвердить электронную почту или телефон.", + "SelfRegistrationDisabledMessage": "Самостоятельная регистрация не предусмотрена. Пожалуйста, свяжитесь с администраром для получения доступа.", + "LocalLoginDisabledMessage": "Локальный вход отключен.", + "Login": "Войти", + "Cancel": "Отмена", + "Register": "Регистрация", + "AreYouANewUser": "Новый пользователь?", + "AlreadyRegistered": "Уже зарегистрированы?", + "InvalidLoginRequest": "Неправильный запрос", + "ThereAreNoLoginSchemesConfiguredForThisClient": "Не найдено схемы для входа с текущим клиентским приложением.", + "LogInUsingYourProviderAccount": "Войти использую свой {0} аккаунт", + "DisplayName:CurrentPassword": "Текущий пароль", + "DisplayName:NewPassword": "Новый пароль", + "DisplayName:NewPasswordConfirm": "Повторите новый пароль", + "PasswordChangedMessage": "Ваш пароль успешно изменен.", + "DisplayName:UserName": "Имя пользователя", + "DisplayName:Email": "Email", + "DisplayName:Name": "Имя", + "DisplayName:Surname": "Фамилия", + "DisplayName:Password": "Пароль", + "DisplayName:EmailAddress": "Электронная почта", + "DisplayName:PhoneNumber": "Номер телефона", + "PersonalSettings": "Персональные настройки", + "PersonalSettingsSaved": "Персональные настройки сохранены", + "PasswordChanged": "Пароль изменен", + "NewPasswordConfirmFailed": "Пожалуйста подтвердите новый пароль.", + "Manage": "Управление учетной записью", + "ManageYourProfile": "Настройки", + "DisplayName:Abp.Account.IsSelfRegistrationEnabled": "Самостоятельная регистрация включена", + "Description:Abp.Account.IsSelfRegistrationEnabled": "Позволяет новым пользователям регистрироваться самостоятельно.", + "DisplayName:Abp.Account.EnableLocalLogin": "Вход с помощью локальной учетной записи приложения", + "Description:Abp.Account.EnableLocalLogin": "Указывает на то, разрешено ли пользователям входить с помощью локальной учетной записи приложения." + } +} From 0ac721c9ee26805412ce218ffcbe1195971720ee Mon Sep 17 00:00:00 2001 From: Roman Rybalko Date: Tue, 10 Mar 2020 15:52:28 +0300 Subject: [PATCH 063/334] Added ru.json for template --- .../Localization/MyProjectName/ru.json | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Domain.Shared/Localization/MyProjectName/ru.json diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Domain.Shared/Localization/MyProjectName/ru.json b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Domain.Shared/Localization/MyProjectName/ru.json new file mode 100644 index 0000000000..8464e44344 --- /dev/null +++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Domain.Shared/Localization/MyProjectName/ru.json @@ -0,0 +1,8 @@ +{ + "culture": "ru", + "texts": { + "Menu:Home": "Главная", + "Welcome": "Добро пожаловать", + "LongWelcomeMessage": "Добро пожаловать в приложение. Этот запущенный проект основан на фреймворке ABP. Для получения дополнительной информации посетите сайт abp.io." + } +} From 4c192da10b49deb01e7f6b01ce05c5b1a84ad644 Mon Sep 17 00:00:00 2001 From: Roman Rybalko Date: Tue, 10 Mar 2020 16:30:39 +0300 Subject: [PATCH 064/334] Added Russian language definiton to app and module templates --- .../MyProjectNameHttpApiHostModule.cs | 1 + .../MyProjectNameHttpApiHostModule.cs | 1 + .../MyProjectNameIdentityServerModule.cs | 1 + .../MyCompanyName.MyProjectName.Web/MyProjectNameWebModule.cs | 1 + .../MyProjectNameHttpApiHostModule.cs | 1 + .../MyProjectNameIdentityServerModule.cs | 1 + .../MyProjectNameWebUnifiedModule.cs | 1 + 7 files changed, 7 insertions(+) diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.Host/MyProjectNameHttpApiHostModule.cs b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.Host/MyProjectNameHttpApiHostModule.cs index 6cdc617690..edbece71e0 100644 --- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.Host/MyProjectNameHttpApiHostModule.cs +++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.Host/MyProjectNameHttpApiHostModule.cs @@ -111,6 +111,7 @@ namespace MyCompanyName.MyProjectName options.Languages.Add(new LanguageInfo("cs", "cs", "Čeština")); options.Languages.Add(new LanguageInfo("en", "en", "English")); 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", "繁體中文")); diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.HostWithIds/MyProjectNameHttpApiHostModule.cs b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.HostWithIds/MyProjectNameHttpApiHostModule.cs index 80aa44c647..27a5485c05 100644 --- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.HostWithIds/MyProjectNameHttpApiHostModule.cs +++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.HostWithIds/MyProjectNameHttpApiHostModule.cs @@ -120,6 +120,7 @@ namespace MyCompanyName.MyProjectName options.Languages.Add(new LanguageInfo("cs", "cs", "Čeština")); options.Languages.Add(new LanguageInfo("en", "en", "English")); 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", "繁體中文")); diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.IdentityServer/MyProjectNameIdentityServerModule.cs b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.IdentityServer/MyProjectNameIdentityServerModule.cs index c20e77adf1..9a17f5e3ba 100644 --- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.IdentityServer/MyProjectNameIdentityServerModule.cs +++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.IdentityServer/MyProjectNameIdentityServerModule.cs @@ -59,6 +59,7 @@ namespace MyCompanyName.MyProjectName options.Languages.Add(new LanguageInfo("cs", "cs", "Čeština")); options.Languages.Add(new LanguageInfo("en", "en", "English")); 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", "繁體中文")); diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web/MyProjectNameWebModule.cs b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web/MyProjectNameWebModule.cs index 89cf3c1358..4a588d4945 100644 --- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web/MyProjectNameWebModule.cs +++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web/MyProjectNameWebModule.cs @@ -152,6 +152,7 @@ namespace MyCompanyName.MyProjectName.Web options.Languages.Add(new LanguageInfo("cs", "cs", "Čeština")); options.Languages.Add(new LanguageInfo("en", "en", "English")); 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", "繁體中文")); diff --git a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.HttpApi.Host/MyProjectNameHttpApiHostModule.cs b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.HttpApi.Host/MyProjectNameHttpApiHostModule.cs index 3bfa9a36bf..bb63eed520 100644 --- a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.HttpApi.Host/MyProjectNameHttpApiHostModule.cs +++ b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.HttpApi.Host/MyProjectNameHttpApiHostModule.cs @@ -86,6 +86,7 @@ namespace MyCompanyName.MyProjectName options.Languages.Add(new LanguageInfo("cs", "cs", "Čeština")); options.Languages.Add(new LanguageInfo("en", "en", "English")); 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", "繁體中文")); diff --git a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.IdentityServer/MyProjectNameIdentityServerModule.cs b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.IdentityServer/MyProjectNameIdentityServerModule.cs index b92fe455b5..1085d796f5 100644 --- a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.IdentityServer/MyProjectNameIdentityServerModule.cs +++ b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.IdentityServer/MyProjectNameIdentityServerModule.cs @@ -97,6 +97,7 @@ namespace MyCompanyName.MyProjectName options.Languages.Add(new LanguageInfo("cs", "cs", "Čeština")); options.Languages.Add(new LanguageInfo("en", "en", "English")); 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", "繁體中文")); diff --git a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/MyProjectNameWebUnifiedModule.cs b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/MyProjectNameWebUnifiedModule.cs index cdd5de9398..c7daebdc7b 100644 --- a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/MyProjectNameWebUnifiedModule.cs +++ b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/MyProjectNameWebUnifiedModule.cs @@ -97,6 +97,7 @@ namespace MyCompanyName.MyProjectName options.Languages.Add(new LanguageInfo("cs", "cs", "Čeština")); options.Languages.Add(new LanguageInfo("en", "en", "English")); options.Languages.Add(new LanguageInfo("pt-BR", "pt-BR", "Português (Brasil)")); + 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", "繁體中文")); From 2568f8214d9f250df3a05275a997b02167832f48 Mon Sep 17 00:00:00 2001 From: Roman Rybalko Date: Tue, 10 Mar 2020 19:09:05 +0300 Subject: [PATCH 065/334] Added ru.json for Account --- .../Account/Localization/Resources/ru.json | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 abp_io/AbpIoLocalization/AbpIoLocalization/Account/Localization/Resources/ru.json diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Account/Localization/Resources/ru.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Account/Localization/Resources/ru.json new file mode 100644 index 0000000000..a39240b02e --- /dev/null +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Account/Localization/Resources/ru.json @@ -0,0 +1,13 @@ +{ + "culture": "ru", + "texts": { + "Account": "Аккаунт", + "Welcome": "Добро пожаловать", + "UseOneOfTheFollowingLinksToContinue": "Для продолжения используйте одну из следующих ссылок", + "FrameworkHomePage": "Главная страница фреймворка", + "FrameworkDocumentation": "Документация фреймворка", + "OfficialBlog": "Официальный блог", + "CommercialHomePage": "Главная страница коммерческой версии", + "CommercialSupportWebSite": "Сайт коммерческой поддержки" + } +} From 97f57bf6429cda566d938abdba4edd5bfc4b6fee Mon Sep 17 00:00:00 2001 From: Roman Rybalko Date: Tue, 10 Mar 2020 20:15:43 +0300 Subject: [PATCH 066/334] Added ru.json for AbpIoLocalization/Admin --- .../Admin/Localization/Resources/ru.json | 90 +++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/ru.json diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/ru.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/ru.json new file mode 100644 index 0000000000..38b4e728f8 --- /dev/null +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/ru.json @@ -0,0 +1,90 @@ +{ + "culture": "ru", + "texts": { + "Permission:Organizations": "Организации", + "Permission:Manage": "Управление организациями", + "Permission:NpmPackages": "Пакеты NPM", + "Permission:NugetPackages": "Пакеты NuGet", + "Permission:Maintenance": "Обслуживание", + "Permission:Maintain": "Обслуживать", + "Permission:ClearCaches": "Очистить кэш", + "Permission:Modules": "Модули", + "Permission:Packages": "Пакеты", + "Permission:Edit": "Редактировать", + "Permission:Delete": "Удалить", + "Permission:Create": "Создать", + "Menu:Organizations": "Организации", + "Menu:Packages": "Пакеты", + "NpmPackageDeletionWarningMessage": "Этот пакет NPM будет удален. Вы подтверждаете это?", + "NugetPackageDeletionWarningMessage": "Этот пакет NuGet будет удален. Вы подтверждаете это?", + "ModuleDeletionWarningMessage": "Этот модуль будет удален. Вы подтверждаете это?", + "Name": "Имя", + "DisplayName": "Отображаемое имя", + "ShortDescription": "Краткое описание", + "NameFilter": "Имя", + "CreationTime": "Время создания", + "IsPro": "Is pro", + "EfCoreConfigureMethodName": "Настроить имя метода", + "IsProFilter": "Is pro", + "ApplicationType": "Тип приложения", + "Target": "Цель", + "TargetFilter": "Цель", + "ModuleClass": "Класс модуля", + "NugetPackageTarget.DomainShared": "Domain Shared", + "NugetPackageTarget.Domain": "Domain", + "NugetPackageTarget.Application": "Application", + "NugetPackageTarget.ApplicationContracts": "Application Contracts", + "NugetPackageTarget.HttpApi": "Http Api", + "NugetPackageTarget.HttpApiClient": "Http Api Client", + "NugetPackageTarget.Web": "Web", + "NugetPackageTarget.EntityFrameworkCore": "DeleteAllEntityFramework Core", + "NugetPackageTarget.MongoDB": "MongoDB", + "Edit": "Редактировать", + "Delete": "Удалить", + "Refresh": "Обновить", + "NpmPackages": "NPM пакеты", + "NugetPackages": "NuGet пакеты", + "NpmPackageCount": "Количество пакетов NPM", + "NugetPackageCount": "Количество пакетов NuGet", + "Module": "Модули", + "ModuleInfo": "Информация о модуле", + "CreateANpmPackage": "Создать пакет NPM", + "CreateAModule": "Создать модуль", + "CreateANugetPackage": "Создать пакет NuGet", + "AddNew": "Добавить новый", + "PackageAlreadyExist{0}": "\"{0}\" пакет уже существует.", + "ModuleAlreadyExist{0}": "\"{0}\" модуль уже добавлен.", + "ClearCache": "Очистить кэш", + "SuccessfullyCleared": "Успешно очищено", + "Menu:NpmPackages": "Пакеты NPM", + "Menu:Modules": "Модули", + "Menu:Maintenance": "Поддержка", + "Menu:NugetPackages": "Пакеты NuGet", + "CreateAnOrganization": "Создать организацию", + "Organizations": "Организации", + "LongName": "Полное название", + "LicenseType": "Тип лицензии", + "LicenseStartTime": "Время начала действия лицензии", + "LicenseEndTime": "Время окончания действия лицензии", + "AllowedDeveloperCount": "Разрешенное количество разработчиков", + "UserNameOrEmailAddress": "Имя пользователя или адрес электронной почты", + "AddOwner": "Добавить владельца", + "UserName": "Имя пользователя", + "Email": "Электронная почта", + "Developers": "Разработчики", + "AddDeveloper": "Добавить разработчика", + "Create": "Создать", + "UserNotFound": "Пользователь не обнаружен", + "{0}WillBeRemovedFromMembers": "{0} будет удален из членов", + "Computers": "Компьютеры", + "UniqueComputerId": "Уникальный id компьютера", + "LastSeenDate": "Дата последнего визита", + "{0}Computer{1}WillBeRemovedFromRecords": "Компьютер {0} ({1}) будет удален из записей", + "OrganizationDeletionWarningMessage": "Организация будет удалена", + "This{0}AlreadyExistInThisOrganization": "{0} уже существует в данной организации", + "AreYouSureYouWantToDeleteAllComputers": "Вы уверены, что хотите удалить все компьютеры?", + "DeleteAll": "Удалить все", + "DoYouWantToCreateNewUser": "Вы хотите создать нового пользователя?", + "MasterModules": "Мастер модулей" + } +} From 12053115dbb4b39713889a92f0bffc691118c798 Mon Sep 17 00:00:00 2001 From: Oliver Cooper Date: Fri, 20 Mar 2020 16:35:32 +0000 Subject: [PATCH 067/334] Add Angular 9 '@Injectable()' to tutorials and book store sample. --- docs/en/Tutorials/Part-1.md | 2 ++ docs/en/Tutorials/Part-2.md | 4 ++++ docs/pt-BR/Tutorials/Angular/Part-I.md | 2 ++ .../angular/src/app/store/states/books.state.ts | 2 ++ 4 files changed, 10 insertions(+) diff --git a/docs/en/Tutorials/Part-1.md b/docs/en/Tutorials/Part-1.md index 20b64f3189..1711c21e25 100644 --- a/docs/en/Tutorials/Part-1.md +++ b/docs/en/Tutorials/Part-1.md @@ -982,11 +982,13 @@ import { GetBooks } from '../actions/books.actions'; import { Books } from '../models/books'; import { BooksService } from '../../books/shared/books.service'; import { tap } from 'rxjs/operators'; +import { Injectable } from '@angular/core'; @State({ name: 'BooksState', defaults: { books: {} } as Books.State, }) +@Injectable() export class BooksState { @Selector() static getBooks(state: Books.State) { diff --git a/docs/en/Tutorials/Part-2.md b/docs/en/Tutorials/Part-2.md index 08e17e0e3f..8bf3cb053b 100644 --- a/docs/en/Tutorials/Part-2.md +++ b/docs/en/Tutorials/Part-2.md @@ -574,11 +574,13 @@ import { GetBooks, CreateUpdateBook } from '../actions/books.actions'; //<== add import { Books } from '../models/books'; import { BooksService } from '../../books/shared/books.service'; import { tap } from 'rxjs/operators'; +import { Injectable } from '@angular/core'; @State({ name: 'BooksState', defaults: { books: {} } as Books.State, }) +@Injectable() export class BooksState { @Selector() static getBooks(state: Books.State) { @@ -1330,11 +1332,13 @@ import { GetBooks, CreateUpdateBook, DeleteBook } from '../actions/books.actions import { Books } from '../models/books'; import { BooksService } from '../../books/shared/books.service'; import { tap } from 'rxjs/operators'; +import { Injectable } from '@angular/core'; @State({ name: 'BooksState', defaults: { books: {} } as Books.State, }) +@Injectable() export class BooksState { @Selector() static getBooks(state: Books.State) { diff --git a/docs/pt-BR/Tutorials/Angular/Part-I.md b/docs/pt-BR/Tutorials/Angular/Part-I.md index 05e8a1b7e1..7fbe0827ce 100644 --- a/docs/pt-BR/Tutorials/Angular/Part-I.md +++ b/docs/pt-BR/Tutorials/Angular/Part-I.md @@ -537,11 +537,13 @@ import { GetBooks } from '../actions/books.actions'; import { Books } from '../models/books'; import { BooksService } from '../../books/shared/books.service'; import { tap } from 'rxjs/operators'; +import { Injectable } from '@angular/core'; @State({ name: 'BooksState', defaults: { books: {} } as Books.State, }) +@Injectable() export class BooksState { @Selector() static getBooks(state: Books.State) { diff --git a/samples/BookStore-Angular-MongoDb/angular/src/app/store/states/books.state.ts b/samples/BookStore-Angular-MongoDb/angular/src/app/store/states/books.state.ts index f2d1c78d90..54ecaeb155 100644 --- a/samples/BookStore-Angular-MongoDb/angular/src/app/store/states/books.state.ts +++ b/samples/BookStore-Angular-MongoDb/angular/src/app/store/states/books.state.ts @@ -7,11 +7,13 @@ import { import { Books } from "../models/books"; import { BooksService } from "../../books/shared/books.service"; import { tap } from "rxjs/operators"; +import { Injectable } from '@angular/core'; @State({ name: "BooksState", defaults: { books: {} } as Books.State }) +@Injectable() export class BooksState { @Selector() static getBooks(state: Books.State) { From f2d3b712247111a6c869fb85457dca734b7b2985 Mon Sep 17 00:00:00 2001 From: maliming Date: Wed, 25 Mar 2020 18:08:13 +0800 Subject: [PATCH 068/334] Introducing DynamicProxyIgnoreTypes. Resolve #3180 --- .../AspNetCore/Mvc/AbpAspNetCoreMvcModule.cs | 6 +++++ .../Auditing/AuditingInterceptorRegistrar.cs | 3 ++- .../AuthorizationInterceptorRegistrar.cs | 3 ++- .../DynamicProxy/DynamicProxyIgnoreTypes.cs | 24 +++++++++++++++++++ .../Features/FeatureInterceptorRegistrar.cs | 3 ++- .../Abp/Uow/UnitOfWorkInterceptorRegistrar.cs | 3 ++- .../ValidationInterceptorRegistrar.cs | 3 ++- .../AbpAuthorizationTestModule.cs | 4 +++- ...plicationService_FluentValidation_Tests.cs | 4 +++- .../ApplicationService_Validation_Tests.cs | 4 +++- 10 files changed, 49 insertions(+), 8 deletions(-) create mode 100644 framework/src/Volo.Abp.Core/Volo/Abp/DynamicProxy/DynamicProxyIgnoreTypes.cs diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcModule.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcModule.cs index 21a675ddc4..e609b0a601 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcModule.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcModule.cs @@ -12,6 +12,7 @@ using System; using System.Collections.Generic; using System.Linq; using System.Reflection; +using Microsoft.AspNetCore.Mvc.RazorPages; using Microsoft.Extensions.Hosting; using Volo.Abp.ApiVersioning; using Volo.Abp.AspNetCore.Mvc.Conventions; @@ -20,6 +21,7 @@ using Volo.Abp.AspNetCore.Mvc.Json; using Volo.Abp.AspNetCore.Mvc.Localization; using Volo.Abp.AspNetCore.VirtualFileSystem; using Volo.Abp.DependencyInjection; +using Volo.Abp.DynamicProxy; using Volo.Abp.Http.Modeling; using Volo.Abp.Localization; using Volo.Abp.Modularity; @@ -38,6 +40,10 @@ namespace Volo.Abp.AspNetCore.Mvc { public override void PreConfigureServices(ServiceConfigurationContext context) { + DynamicProxyIgnoreTypes.IgnoreTypes.AddIfNotContains(typeof(ControllerBase)); + DynamicProxyIgnoreTypes.IgnoreTypes.AddIfNotContains(typeof(PageModel)); + DynamicProxyIgnoreTypes.IgnoreTypes.AddIfNotContains(typeof(ViewComponent)); + context.Services.AddConventionalRegistrar(new AbpAspNetCoreMvcConventionalRegistrar()); } diff --git a/framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/AuditingInterceptorRegistrar.cs b/framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/AuditingInterceptorRegistrar.cs index 94920fe1be..6790995331 100644 --- a/framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/AuditingInterceptorRegistrar.cs +++ b/framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/AuditingInterceptorRegistrar.cs @@ -1,6 +1,7 @@ using System; using System.Linq; using Volo.Abp.DependencyInjection; +using Volo.Abp.DynamicProxy; namespace Volo.Abp.Auditing { @@ -8,7 +9,7 @@ namespace Volo.Abp.Auditing { public static void RegisterIfNeeded(IOnServiceRegistredContext context) { - if (ShouldIntercept(context.ImplementationType)) + if (ShouldIntercept(context.ImplementationType) && !DynamicProxyIgnoreTypes.Contains(context.ImplementationType)) { context.Interceptors.TryAdd(); } diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/AuthorizationInterceptorRegistrar.cs b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/AuthorizationInterceptorRegistrar.cs index 69a285ddc8..b44c299b28 100644 --- a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/AuthorizationInterceptorRegistrar.cs +++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/AuthorizationInterceptorRegistrar.cs @@ -3,6 +3,7 @@ using System.Linq; using System.Reflection; using Microsoft.AspNetCore.Authorization; using Volo.Abp.DependencyInjection; +using Volo.Abp.DynamicProxy; namespace Volo.Abp.Authorization { @@ -10,7 +11,7 @@ namespace Volo.Abp.Authorization { public static void RegisterIfNeeded(IOnServiceRegistredContext context) { - if (ShouldIntercept(context.ImplementationType)) + if (ShouldIntercept(context.ImplementationType) && !DynamicProxyIgnoreTypes.Contains(context.ImplementationType)) { context.Interceptors.TryAdd(); } diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/DynamicProxy/DynamicProxyIgnoreTypes.cs b/framework/src/Volo.Abp.Core/Volo/Abp/DynamicProxy/DynamicProxyIgnoreTypes.cs new file mode 100644 index 0000000000..5eae6ef092 --- /dev/null +++ b/framework/src/Volo.Abp.Core/Volo/Abp/DynamicProxy/DynamicProxyIgnoreTypes.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Volo.Abp.DynamicProxy +{ + /// + /// Castle's dynamic proxy class feature will have performance issues for some components, such as the controller of Asp net core MVC. + /// For related discussions, see: https://github.com/castleproject/Core/issues/486 https://github.com/abpframework/abp/issues/3180 + /// The Abp framework may enable interceptors for certain components (UOW, Auditing, Authorization, etc.), which requires dynamic proxy classes, but will cause application performance to decline. + /// We need to use other methods for the controller to implement interception, such as middleware or MVC / Page filters. + /// So we provide some ignored types to avoid enabling dynamic proxy classes. + /// By default it is empty. When you use middleware or filters for these components in your application, you can add these types to the list. + /// + public static class DynamicProxyIgnoreTypes + { + public static List IgnoreTypes { get; } = new List(); + + public static bool Contains(Type type, bool includeDerivedTypes = true) + { + return includeDerivedTypes ? IgnoreTypes.Any(t => t.IsAssignableFrom(type)) : IgnoreTypes.Contains(type); + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Features/Volo/Abp/Features/FeatureInterceptorRegistrar.cs b/framework/src/Volo.Abp.Features/Volo/Abp/Features/FeatureInterceptorRegistrar.cs index 8cb6cd7ea5..b2caa734b5 100644 --- a/framework/src/Volo.Abp.Features/Volo/Abp/Features/FeatureInterceptorRegistrar.cs +++ b/framework/src/Volo.Abp.Features/Volo/Abp/Features/FeatureInterceptorRegistrar.cs @@ -2,6 +2,7 @@ using System.Linq; using System.Reflection; using Volo.Abp.DependencyInjection; +using Volo.Abp.DynamicProxy; namespace Volo.Abp.Features { @@ -9,7 +10,7 @@ namespace Volo.Abp.Features { public static void RegisterIfNeeded(IOnServiceRegistredContext context) { - if (ShouldIntercept(context.ImplementationType)) + if (ShouldIntercept(context.ImplementationType) && !DynamicProxyIgnoreTypes.Contains(context.ImplementationType)) { context.Interceptors.TryAdd(); } diff --git a/framework/src/Volo.Abp.Uow/Volo/Abp/Uow/UnitOfWorkInterceptorRegistrar.cs b/framework/src/Volo.Abp.Uow/Volo/Abp/Uow/UnitOfWorkInterceptorRegistrar.cs index 849ca8ffd8..c01e760d58 100644 --- a/framework/src/Volo.Abp.Uow/Volo/Abp/Uow/UnitOfWorkInterceptorRegistrar.cs +++ b/framework/src/Volo.Abp.Uow/Volo/Abp/Uow/UnitOfWorkInterceptorRegistrar.cs @@ -1,5 +1,6 @@ using System.Reflection; using Volo.Abp.DependencyInjection; +using Volo.Abp.DynamicProxy; namespace Volo.Abp.Uow { @@ -7,7 +8,7 @@ namespace Volo.Abp.Uow { public static void RegisterIfNeeded(IOnServiceRegistredContext context) { - if (UnitOfWorkHelper.IsUnitOfWorkType(context.ImplementationType.GetTypeInfo())) + if (UnitOfWorkHelper.IsUnitOfWorkType(context.ImplementationType.GetTypeInfo()) && !DynamicProxyIgnoreTypes.Contains(context.ImplementationType)) { context.Interceptors.TryAdd(); } diff --git a/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/ValidationInterceptorRegistrar.cs b/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/ValidationInterceptorRegistrar.cs index 81f6eb6597..187f64436e 100644 --- a/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/ValidationInterceptorRegistrar.cs +++ b/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/ValidationInterceptorRegistrar.cs @@ -1,4 +1,5 @@ using Volo.Abp.DependencyInjection; +using Volo.Abp.DynamicProxy; namespace Volo.Abp.Validation { @@ -6,7 +7,7 @@ namespace Volo.Abp.Validation { public static void RegisterIfNeeded(IOnServiceRegistredContext context) { - if (typeof(IValidationEnabled).IsAssignableFrom(context.ImplementationType)) + if (typeof(IValidationEnabled).IsAssignableFrom(context.ImplementationType) && !DynamicProxyIgnoreTypes.Contains(context.ImplementationType)) { context.Interceptors.TryAdd(); } diff --git a/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/AbpAuthorizationTestModule.cs b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/AbpAuthorizationTestModule.cs index 51337ae871..492a36f8b9 100644 --- a/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/AbpAuthorizationTestModule.cs +++ b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/AbpAuthorizationTestModule.cs @@ -1,6 +1,7 @@ using Microsoft.Extensions.DependencyInjection; using Volo.Abp.Authorization.TestServices; using Volo.Abp.Autofac; +using Volo.Abp.DynamicProxy; using Volo.Abp.Modularity; namespace Volo.Abp.Authorization @@ -13,7 +14,8 @@ namespace Volo.Abp.Authorization { context.Services.OnRegistred(onServiceRegistredContext => { - if (typeof(IMyAuthorizedService1).IsAssignableFrom(onServiceRegistredContext.ImplementationType)) + if (typeof(IMyAuthorizedService1).IsAssignableFrom(onServiceRegistredContext.ImplementationType) && + !DynamicProxyIgnoreTypes.Contains(onServiceRegistredContext.ImplementationType)) { onServiceRegistredContext.Interceptors.TryAdd(); } diff --git a/framework/test/Volo.Abp.FluentValidation.Tests/Volo/Abp/FluentValidation/ApplicationService_FluentValidation_Tests.cs b/framework/test/Volo.Abp.FluentValidation.Tests/Volo/Abp/FluentValidation/ApplicationService_FluentValidation_Tests.cs index 5bf11b6d5e..a93eabda1d 100644 --- a/framework/test/Volo.Abp.FluentValidation.Tests/Volo/Abp/FluentValidation/ApplicationService_FluentValidation_Tests.cs +++ b/framework/test/Volo.Abp.FluentValidation.Tests/Volo/Abp/FluentValidation/ApplicationService_FluentValidation_Tests.cs @@ -5,6 +5,7 @@ using Microsoft.Extensions.DependencyInjection; using Shouldly; using Volo.Abp.Autofac; using Volo.Abp.DependencyInjection; +using Volo.Abp.DynamicProxy; using Volo.Abp.Modularity; using Volo.Abp.Testing; using Volo.Abp.Validation; @@ -108,7 +109,8 @@ namespace Volo.Abp.FluentValidation { context.Services.OnRegistred(onServiceRegistredContext => { - if (typeof(IMyAppService).IsAssignableFrom(onServiceRegistredContext.ImplementationType)) + if (typeof(IMyAppService).IsAssignableFrom(onServiceRegistredContext.ImplementationType) && + !DynamicProxyIgnoreTypes.Contains(onServiceRegistredContext.ImplementationType)) { onServiceRegistredContext.Interceptors.TryAdd(); } diff --git a/framework/test/Volo.Abp.Validation.Tests/Volo/Abp/Validation/ApplicationService_Validation_Tests.cs b/framework/test/Volo.Abp.Validation.Tests/Volo/Abp/Validation/ApplicationService_Validation_Tests.cs index 0d13867819..de9067e2f7 100644 --- a/framework/test/Volo.Abp.Validation.Tests/Volo/Abp/Validation/ApplicationService_Validation_Tests.cs +++ b/framework/test/Volo.Abp.Validation.Tests/Volo/Abp/Validation/ApplicationService_Validation_Tests.cs @@ -8,6 +8,7 @@ using Shouldly; using Volo.Abp.Application.Dtos; using Volo.Abp.Autofac; using Volo.Abp.DependencyInjection; +using Volo.Abp.DynamicProxy; using Volo.Abp.Modularity; using Volo.Abp.Testing; using Xunit; @@ -198,7 +199,8 @@ namespace Volo.Abp.Validation { context.Services.OnRegistred(onServiceRegistredContext => { - if (typeof(IMyAppService).IsAssignableFrom(onServiceRegistredContext.ImplementationType)) + if (typeof(IMyAppService).IsAssignableFrom(onServiceRegistredContext.ImplementationType) && + !DynamicProxyIgnoreTypes.Contains(onServiceRegistredContext.ImplementationType)) { onServiceRegistredContext.Interceptors.TryAdd(); } From 1475940d853379a867bef3d899c9000199144a95 Mon Sep 17 00:00:00 2001 From: maliming Date: Fri, 27 Mar 2020 10:24:51 +0800 Subject: [PATCH 069/334] Refactor. --- .../Abp/AspNetCore/Mvc/AbpAspNetCoreMvcModule.cs | 8 ++++---- .../Abp/Auditing/AuditingInterceptorRegistrar.cs | 7 ++++++- .../AuthorizationInterceptorRegistrar.cs | 6 +++--- .../Volo/Abp/DynamicProxy/DynamicProxyIgnoreTypes.cs | 12 +++++++++--- .../Volo/Abp/Features/FeatureInterceptorRegistrar.cs | 7 ++++--- .../Volo/Abp/Uow/UnitOfWorkInterceptorRegistrar.cs | 10 ++++++++-- .../Abp/Validation/ValidationInterceptorRegistrar.cs | 10 ++++++++-- 7 files changed, 42 insertions(+), 18 deletions(-) diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcModule.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcModule.cs index e609b0a601..668e7a77dc 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcModule.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcModule.cs @@ -40,10 +40,10 @@ namespace Volo.Abp.AspNetCore.Mvc { public override void PreConfigureServices(ServiceConfigurationContext context) { - DynamicProxyIgnoreTypes.IgnoreTypes.AddIfNotContains(typeof(ControllerBase)); - DynamicProxyIgnoreTypes.IgnoreTypes.AddIfNotContains(typeof(PageModel)); - DynamicProxyIgnoreTypes.IgnoreTypes.AddIfNotContains(typeof(ViewComponent)); - + DynamicProxyIgnoreTypes.Add(); + DynamicProxyIgnoreTypes.Add(); + DynamicProxyIgnoreTypes.Add(); + context.Services.AddConventionalRegistrar(new AbpAspNetCoreMvcConventionalRegistrar()); } diff --git a/framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/AuditingInterceptorRegistrar.cs b/framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/AuditingInterceptorRegistrar.cs index 6790995331..a407335f3d 100644 --- a/framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/AuditingInterceptorRegistrar.cs +++ b/framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/AuditingInterceptorRegistrar.cs @@ -9,7 +9,7 @@ namespace Volo.Abp.Auditing { public static void RegisterIfNeeded(IOnServiceRegistredContext context) { - if (ShouldIntercept(context.ImplementationType) && !DynamicProxyIgnoreTypes.Contains(context.ImplementationType)) + if (ShouldIntercept(context.ImplementationType)) { context.Interceptors.TryAdd(); } @@ -17,6 +17,11 @@ namespace Volo.Abp.Auditing private static bool ShouldIntercept(Type type) { + if (DynamicProxyIgnoreTypes.Contains(type)) + { + return false; + } + if (ShouldAuditTypeByDefault(type)) { return true; diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/AuthorizationInterceptorRegistrar.cs b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/AuthorizationInterceptorRegistrar.cs index b44c299b28..e33a8fca7e 100644 --- a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/AuthorizationInterceptorRegistrar.cs +++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/AuthorizationInterceptorRegistrar.cs @@ -11,7 +11,7 @@ namespace Volo.Abp.Authorization { public static void RegisterIfNeeded(IOnServiceRegistredContext context) { - if (ShouldIntercept(context.ImplementationType) && !DynamicProxyIgnoreTypes.Contains(context.ImplementationType)) + if (ShouldIntercept(context.ImplementationType)) { context.Interceptors.TryAdd(); } @@ -19,8 +19,8 @@ namespace Volo.Abp.Authorization private static bool ShouldIntercept(Type type) { - return type.IsDefined(typeof(AuthorizeAttribute), true) || - AnyMethodHasAuthorizeAttribute(type); + return !DynamicProxyIgnoreTypes.Contains(type) && + (type.IsDefined(typeof(AuthorizeAttribute), true) || AnyMethodHasAuthorizeAttribute(type)); } private static bool AnyMethodHasAuthorizeAttribute(Type implementationType) diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/DynamicProxy/DynamicProxyIgnoreTypes.cs b/framework/src/Volo.Abp.Core/Volo/Abp/DynamicProxy/DynamicProxyIgnoreTypes.cs index 5eae6ef092..6cdefb6705 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/DynamicProxy/DynamicProxyIgnoreTypes.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/DynamicProxy/DynamicProxyIgnoreTypes.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using Volo.Abp.Threading; namespace Volo.Abp.DynamicProxy { @@ -14,11 +15,16 @@ namespace Volo.Abp.DynamicProxy /// public static class DynamicProxyIgnoreTypes { - public static List IgnoreTypes { get; } = new List(); - + private static HashSet IgnoredTypes { get; } = new HashSet(); + + public static void Add() + { + IgnoredTypes.Locking(() => IgnoredTypes.AddIfNotContains(typeof(T))); + } + public static bool Contains(Type type, bool includeDerivedTypes = true) { - return includeDerivedTypes ? IgnoreTypes.Any(t => t.IsAssignableFrom(type)) : IgnoreTypes.Contains(type); + return includeDerivedTypes ? IgnoredTypes.Any(t => t.IsAssignableFrom(type)) : IgnoredTypes.Contains(type); } } } \ No newline at end of file diff --git a/framework/src/Volo.Abp.Features/Volo/Abp/Features/FeatureInterceptorRegistrar.cs b/framework/src/Volo.Abp.Features/Volo/Abp/Features/FeatureInterceptorRegistrar.cs index b2caa734b5..c20b98c143 100644 --- a/framework/src/Volo.Abp.Features/Volo/Abp/Features/FeatureInterceptorRegistrar.cs +++ b/framework/src/Volo.Abp.Features/Volo/Abp/Features/FeatureInterceptorRegistrar.cs @@ -10,7 +10,7 @@ namespace Volo.Abp.Features { public static void RegisterIfNeeded(IOnServiceRegistredContext context) { - if (ShouldIntercept(context.ImplementationType) && !DynamicProxyIgnoreTypes.Contains(context.ImplementationType)) + if (ShouldIntercept(context.ImplementationType)) { context.Interceptors.TryAdd(); } @@ -18,8 +18,9 @@ namespace Volo.Abp.Features private static bool ShouldIntercept(Type type) { - return type.IsDefined(typeof(RequiresFeatureAttribute), true) || - AnyMethodHasRequiresFeatureAttribute(type); + return !DynamicProxyIgnoreTypes.Contains(type) && + (type.IsDefined(typeof(RequiresFeatureAttribute), true) || + AnyMethodHasRequiresFeatureAttribute(type)); } private static bool AnyMethodHasRequiresFeatureAttribute(Type implementationType) diff --git a/framework/src/Volo.Abp.Uow/Volo/Abp/Uow/UnitOfWorkInterceptorRegistrar.cs b/framework/src/Volo.Abp.Uow/Volo/Abp/Uow/UnitOfWorkInterceptorRegistrar.cs index c01e760d58..5331cb1d0e 100644 --- a/framework/src/Volo.Abp.Uow/Volo/Abp/Uow/UnitOfWorkInterceptorRegistrar.cs +++ b/framework/src/Volo.Abp.Uow/Volo/Abp/Uow/UnitOfWorkInterceptorRegistrar.cs @@ -1,4 +1,5 @@ -using System.Reflection; +using System; +using System.Reflection; using Volo.Abp.DependencyInjection; using Volo.Abp.DynamicProxy; @@ -8,10 +9,15 @@ namespace Volo.Abp.Uow { public static void RegisterIfNeeded(IOnServiceRegistredContext context) { - if (UnitOfWorkHelper.IsUnitOfWorkType(context.ImplementationType.GetTypeInfo()) && !DynamicProxyIgnoreTypes.Contains(context.ImplementationType)) + if (ShouldIntercept(context.ImplementationType)) { context.Interceptors.TryAdd(); } } + + private static bool ShouldIntercept(Type type) + { + return !DynamicProxyIgnoreTypes.Contains(type) && UnitOfWorkHelper.IsUnitOfWorkType(type.GetTypeInfo()); + } } } \ No newline at end of file diff --git a/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/ValidationInterceptorRegistrar.cs b/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/ValidationInterceptorRegistrar.cs index 187f64436e..1474efd710 100644 --- a/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/ValidationInterceptorRegistrar.cs +++ b/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/ValidationInterceptorRegistrar.cs @@ -1,4 +1,5 @@ -using Volo.Abp.DependencyInjection; +using System; +using Volo.Abp.DependencyInjection; using Volo.Abp.DynamicProxy; namespace Volo.Abp.Validation @@ -7,10 +8,15 @@ namespace Volo.Abp.Validation { public static void RegisterIfNeeded(IOnServiceRegistredContext context) { - if (typeof(IValidationEnabled).IsAssignableFrom(context.ImplementationType) && !DynamicProxyIgnoreTypes.Contains(context.ImplementationType)) + if (ShouldIntercept(context.ImplementationType)) { context.Interceptors.TryAdd(); } } + + private static bool ShouldIntercept(Type type) + { + return !DynamicProxyIgnoreTypes.Contains(type) && typeof(IValidationEnabled).IsAssignableFrom(type); + } } } \ No newline at end of file From 0b1606f40bc9d207b73844ad56b2c7cf43806c2e Mon Sep 17 00:00:00 2001 From: maliming Date: Fri, 27 Mar 2020 11:20:17 +0800 Subject: [PATCH 070/334] Add AbpAuditPageFilter, AbpFeaturePageFilter, AbpUowPageFilter, AbpExceptionPageFilter. --- .../ActionDescriptorExtensions.cs | 31 +++++ .../AspNetCore/Mvc/AbpMvcOptionsExtensions.cs | 13 +- .../Mvc/Auditing/AbpAuditPageFilter.cs | 103 ++++++++++++++++ .../AbpExceptionPageFilter.cs | 112 ++++++++++++++++++ .../Mvc/Features/AbpFeaturePageFilter.cs | 44 +++++++ .../AspNetCore/Mvc/Uow/AbpUowPageFilter.cs | 105 ++++++++++++++++ 6 files changed, 406 insertions(+), 2 deletions(-) create mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Auditing/AbpAuditPageFilter.cs create mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ExceptionHandling/AbpExceptionPageFilter.cs create mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Features/AbpFeaturePageFilter.cs create mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Uow/AbpUowPageFilter.cs diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Microsoft/AspNetCore/Mvc/Abstractions/ActionDescriptorExtensions.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Microsoft/AspNetCore/Mvc/Abstractions/ActionDescriptorExtensions.cs index fb992cb4af..97b5a6c61b 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Microsoft/AspNetCore/Mvc/Abstractions/ActionDescriptorExtensions.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Microsoft/AspNetCore/Mvc/Abstractions/ActionDescriptorExtensions.cs @@ -1,6 +1,7 @@ using System; using System.Reflection; using Microsoft.AspNetCore.Mvc.Controllers; +using Microsoft.AspNetCore.Mvc.RazorPages; using Volo.Abp; using Volo.Abp.AspNetCore.Mvc; @@ -37,5 +38,35 @@ namespace Microsoft.AspNetCore.Mvc.Abstractions { return actionDescriptor is ControllerActionDescriptor; } + + public static PageActionDescriptor AsPageActionDescriptor(this ActionDescriptor actionDescriptor) + { + if (!actionDescriptor.IsPageAction()) + { + throw new AbpException($"{nameof(actionDescriptor)} should be type of {typeof(PageActionDescriptor).AssemblyQualifiedName}"); + } + + return actionDescriptor as PageActionDescriptor; + } + + public static MethodInfo GetPageActionMethodInfo(this ActionDescriptor actionDescriptor) + { + return actionDescriptor.AsPageActionDescriptor().GetMethodInfo(); + } + + public static Type GetPageActionReturnType(this PageActionDescriptor actionDescriptor) + { + return actionDescriptor.GetPageActionMethodInfo().ReturnType; + } + + public static bool HasObjectResult(this PageActionDescriptor actionDescriptor) + { + return ActionResultHelper.IsObjectResult(actionDescriptor.GetReturnType()); + } + + public static bool IsPageAction(this ActionDescriptor actionDescriptor) + { + return actionDescriptor is PageActionDescriptor; + } } } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpMvcOptionsExtensions.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpMvcOptionsExtensions.cs index 4aedf0b087..64d9daca93 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpMvcOptionsExtensions.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpMvcOptionsExtensions.cs @@ -16,7 +16,8 @@ namespace Volo.Abp.AspNetCore.Mvc public static void AddAbp(this MvcOptions options, IServiceCollection services) { AddConventions(options, services); - AddFilters(options); + AddActionFilters(options); + AddPageFilters(options); AddModelBinders(options); AddMetadataProviders(options, services); } @@ -26,7 +27,7 @@ namespace Volo.Abp.AspNetCore.Mvc options.Conventions.Add(new AbpServiceConventionWrapper(services)); } - private static void AddFilters(MvcOptions options) + private static void AddActionFilters(MvcOptions options) { options.Filters.AddService(typeof(AbpAuditActionFilter)); options.Filters.AddService(typeof(AbpNoContentActionFilter)); @@ -36,6 +37,14 @@ namespace Volo.Abp.AspNetCore.Mvc options.Filters.AddService(typeof(AbpExceptionFilter)); } + private static void AddPageFilters(MvcOptions options) + { + options.Filters.AddService(typeof(AbpAuditPageFilter)); + options.Filters.AddService(typeof(AbpFeaturePageFilter)); + options.Filters.AddService(typeof(AbpUowPageFilter)); + options.Filters.AddService(typeof(AbpExceptionPageFilter)); + } + private static void AddModelBinders(MvcOptions options) { options.ModelBinderProviders.Insert(0, new AbpDateTimeModelBinderProvider()); diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Auditing/AbpAuditPageFilter.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Auditing/AbpAuditPageFilter.cs new file mode 100644 index 0000000000..23e94790e9 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Auditing/AbpAuditPageFilter.cs @@ -0,0 +1,103 @@ +using System; +using System.Diagnostics; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc.Abstractions; +using Microsoft.AspNetCore.Mvc.Filters; +using Microsoft.Extensions.Options; +using Volo.Abp.Aspects; +using Volo.Abp.Auditing; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.AspNetCore.Mvc.Auditing +{ + public class AbpAuditPageFilter : IAsyncPageFilter, ITransientDependency + { + protected AbpAuditingOptions Options { get; } + private readonly IAuditingHelper _auditingHelper; + private readonly IAuditingManager _auditingManager; + + public AbpAuditPageFilter(IOptions options, IAuditingHelper auditingHelper, IAuditingManager auditingManager) + { + Options = options.Value; + _auditingHelper = auditingHelper; + _auditingManager = auditingManager; + } + + public Task OnPageHandlerSelectionAsync(PageHandlerSelectedContext context) + { + return Task.CompletedTask; + } + + public async Task OnPageHandlerExecutionAsync(PageHandlerExecutingContext context, PageHandlerExecutionDelegate next) + { + if (context.HandlerMethod == null || !ShouldSaveAudit(context, out var auditLog, out var auditLogAction)) + { + await next(); + return; + } + + using (AbpCrossCuttingConcerns.Applying(context.HandlerInstance, AbpCrossCuttingConcerns.Auditing)) + { + var stopwatch = Stopwatch.StartNew(); + + try + { + var result = await next(); + + if (result.Exception != null && !result.ExceptionHandled) + { + auditLog.Exceptions.Add(result.Exception); + } + } + catch (Exception ex) + { + auditLog.Exceptions.Add(ex); + throw; + } + finally + { + stopwatch.Stop(); + auditLogAction.ExecutionDuration = Convert.ToInt32(stopwatch.Elapsed.TotalMilliseconds); + auditLog.Actions.Add(auditLogAction); + } + } + } + + private bool ShouldSaveAudit(PageHandlerExecutingContext context, out AuditLogInfo auditLog, out AuditLogActionInfo auditLogAction) + { + auditLog = null; + auditLogAction = null; + + if (!Options.IsEnabled) + { + return false; + } + + if (!context.ActionDescriptor.IsPageAction()) + { + return false; + } + + var auditLogScope = _auditingManager.Current; + if (auditLogScope == null) + { + return false; + } + + if (!_auditingHelper.ShouldSaveAudit(context.ActionDescriptor.GetMethodInfo(), true)) + { + return false; + } + + auditLog = auditLogScope.Log; + auditLogAction = _auditingHelper.CreateAuditLogAction( + auditLog, + context.ActionDescriptor.AsControllerActionDescriptor().ControllerTypeInfo.AsType(), + context.ActionDescriptor.AsControllerActionDescriptor().MethodInfo, + context.HandlerArguments + ); + + return true; + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ExceptionHandling/AbpExceptionPageFilter.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ExceptionHandling/AbpExceptionPageFilter.cs new file mode 100644 index 0000000000..8aa45688ca --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ExceptionHandling/AbpExceptionPageFilter.cs @@ -0,0 +1,112 @@ +using System; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Abstractions; +using Microsoft.AspNetCore.Mvc.Filters; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; +using Volo.Abp.AspNetCore.ExceptionHandling; +using Volo.Abp.DependencyInjection; +using Volo.Abp.ExceptionHandling; +using Volo.Abp.Http; +using Volo.Abp.Json; + +namespace Volo.Abp.AspNetCore.Mvc.ExceptionHandling +{ + public class AbpExceptionPageFilter : IAsyncPageFilter, ITransientDependency + { + public ILogger Logger { get; set; } + + private readonly IExceptionToErrorInfoConverter _errorInfoConverter; + private readonly IHttpExceptionStatusCodeFinder _statusCodeFinder; + private readonly IJsonSerializer _jsonSerializer; + + public AbpExceptionPageFilter( + IExceptionToErrorInfoConverter errorInfoConverter, + IHttpExceptionStatusCodeFinder statusCodeFinder, + IJsonSerializer jsonSerializer) + { + _errorInfoConverter = errorInfoConverter; + _statusCodeFinder = statusCodeFinder; + _jsonSerializer = jsonSerializer; + + Logger = NullLogger.Instance; + } + + + public Task OnPageHandlerSelectionAsync(PageHandlerSelectedContext context) + { + return Task.CompletedTask; + } + + public async Task OnPageHandlerExecutionAsync(PageHandlerExecutingContext context, PageHandlerExecutionDelegate next) + { + if (context.HandlerMethod == null || !ShouldHandleException(context)) + { + await next(); + return; + } + + var pageHandlerExecutedContext = await next(); + if (pageHandlerExecutedContext.Exception == null) + { + return;; + } + + await HandleAndWrapException(pageHandlerExecutedContext); + } + + protected virtual bool ShouldHandleException(PageHandlerExecutingContext context) + { + //TODO: Create DontWrap attribute to control wrapping..? + + if (context.ActionDescriptor.IsPageAction() && + context.ActionDescriptor.HasObjectResult()) + { + return true; + } + + if (context.HttpContext.Request.CanAccept(MimeTypes.Application.Json)) + { + return true; + } + + if (context.HttpContext.Request.IsAjax()) + { + return true; + } + + return false; + } + + protected virtual async Task HandleAndWrapException(PageHandlerExecutedContext context) + { + //TODO: Trigger an AbpExceptionHandled event or something like that. + + context.HttpContext.Response.Headers.Add(AbpHttpConsts.AbpErrorFormat, "true"); + context.HttpContext.Response.StatusCode = (int)_statusCodeFinder.GetStatusCode(context.HttpContext, context.Exception); + + var remoteServiceErrorInfo = _errorInfoConverter.Convert(context.Exception); + + context.Result = new ObjectResult(new RemoteServiceErrorResponse(remoteServiceErrorInfo)); + + var logLevel = context.Exception.GetLogLevel(); + + Logger.LogWithLevel(logLevel, $"---------- {nameof(RemoteServiceErrorInfo)} ----------"); + Logger.LogWithLevel(logLevel, _jsonSerializer.Serialize(remoteServiceErrorInfo, indented: true)); + Logger.LogException(context.Exception, logLevel); + + await context.HttpContext + .RequestServices + .GetRequiredService() + .NotifyAsync( + new ExceptionNotificationContext(context.Exception) + ); + + context.Exception = null; //Handled! + } + + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Features/AbpFeaturePageFilter.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Features/AbpFeaturePageFilter.cs new file mode 100644 index 0000000000..ceb117d2ff --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Features/AbpFeaturePageFilter.cs @@ -0,0 +1,44 @@ +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc.Abstractions; +using Microsoft.AspNetCore.Mvc.Filters; +using Volo.Abp.Aspects; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Features; + +namespace Volo.Abp.AspNetCore.Mvc.Features +{ + public class AbpFeaturePageFilter : IAsyncPageFilter, ITransientDependency + { + private readonly IMethodInvocationFeatureCheckerService _methodInvocationAuthorizationService; + + public AbpFeaturePageFilter(IMethodInvocationFeatureCheckerService methodInvocationAuthorizationService) + { + _methodInvocationAuthorizationService = methodInvocationAuthorizationService; + } + + public Task OnPageHandlerSelectionAsync(PageHandlerSelectedContext context) + { + return Task.CompletedTask; + } + + public async Task OnPageHandlerExecutionAsync(PageHandlerExecutingContext context, PageHandlerExecutionDelegate next) + { + if (context.HandlerMethod == null || !context.ActionDescriptor.IsPageAction()) + { + await next(); + return; + } + + var methodInfo = context.ActionDescriptor.GetMethodInfo(); + + using (AbpCrossCuttingConcerns.Applying(context.HandlerInstance, AbpCrossCuttingConcerns.FeatureChecking)) + { + await _methodInvocationAuthorizationService.CheckAsync( + new MethodInvocationFeatureCheckerContext(methodInfo) + ); + + await next(); + } + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Uow/AbpUowPageFilter.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Uow/AbpUowPageFilter.cs new file mode 100644 index 0000000000..aeed982173 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Uow/AbpUowPageFilter.cs @@ -0,0 +1,105 @@ +using System; +using System.Net.Http; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc.Abstractions; +using Microsoft.AspNetCore.Mvc.Filters; +using Microsoft.Extensions.Options; +using Volo.Abp.AspNetCore.Uow; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Uow; + +namespace Volo.Abp.AspNetCore.Mvc.Uow +{ + public class AbpUowPageFilter : IAsyncPageFilter, ITransientDependency + { + private readonly IUnitOfWorkManager _unitOfWorkManager; + private readonly AbpUnitOfWorkDefaultOptions _defaultOptions; + + public AbpUowPageFilter(IUnitOfWorkManager unitOfWorkManager, IOptions options) + { + _unitOfWorkManager = unitOfWorkManager; + _defaultOptions = options.Value; + } + public Task OnPageHandlerSelectionAsync(PageHandlerSelectedContext context) + { + return Task.CompletedTask; + } + + public async Task OnPageHandlerExecutionAsync(PageHandlerExecutingContext context, PageHandlerExecutionDelegate next) + { + if (context.HandlerMethod == null || !context.ActionDescriptor.IsPageAction()) + { + await next(); + return; + } + + var methodInfo = context.ActionDescriptor.GetMethodInfo(); + var unitOfWorkAttr = UnitOfWorkHelper.GetUnitOfWorkAttributeOrNull(methodInfo); + + context.HttpContext.Items["_AbpActionInfo"] = new AbpActionInfoInHttpContext + { + IsObjectResult = context.ActionDescriptor.HasObjectResult() + }; + + if (unitOfWorkAttr?.IsDisabled == true) + { + await next(); + return; + } + + var options = CreateOptions(context, unitOfWorkAttr); + + //Trying to begin a reserved UOW by AbpUnitOfWorkMiddleware + if (_unitOfWorkManager.TryBeginReserved(AbpUnitOfWorkMiddleware.UnitOfWorkReservationName, options)) + { + var result = await next(); + if (!Succeed(result)) + { + await RollbackAsync(context); + } + + return; + } + + //Begin a new, independent unit of work + using (var uow = _unitOfWorkManager.Begin(options)) + { + var result = await next(); + if (Succeed(result)) + { + await uow.CompleteAsync(context.HttpContext.RequestAborted); + } + } + } + + private AbpUnitOfWorkOptions CreateOptions(PageHandlerExecutingContext context, UnitOfWorkAttribute unitOfWorkAttribute) + { + var options = new AbpUnitOfWorkOptions(); + + unitOfWorkAttribute?.SetOptions(options); + + if (unitOfWorkAttribute?.IsTransactional == null) + { + options.IsTransactional = _defaultOptions.CalculateIsTransactional( + autoValue: !string.Equals(context.HttpContext.Request.Method, HttpMethod.Get.Method, StringComparison.OrdinalIgnoreCase) + ); + } + + return options; + } + + private async Task RollbackAsync(PageHandlerExecutingContext context) + { + var currentUow = _unitOfWorkManager.Current; + if (currentUow != null) + { + await currentUow.RollbackAsync(context.HttpContext.RequestAborted); + } + } + + private static bool Succeed(PageHandlerExecutedContext result) + { + return result.Exception == null || result.ExceptionHandled; + } + } +} \ No newline at end of file From fd5eda2b7f533aa4b0cf51a7384c8ebfd15293da Mon Sep 17 00:00:00 2001 From: maliming Date: Fri, 27 Mar 2020 16:32:21 +0800 Subject: [PATCH 071/334] Add unit tests for razor page filters. --- .../ActionDescriptorExtensions.cs | 25 ------- .../AspNetCore/Mvc/AbpAspNetCoreMvcModule.cs | 7 +- .../AspNetCore/Mvc/AbpMvcOptionsExtensions.cs | 2 +- .../Mvc/Auditing/AbpAuditPageFilter.cs | 6 +- .../AbpExceptionPageFilter.cs | 2 +- .../Mvc/Features/AbpFeaturePageFilter.cs | 2 +- .../AspNetCore/Mvc/Uow/AbpUowPageFilter.cs | 4 +- .../Volo.Abp.AspNetCore.Mvc.Tests.csproj | 19 ++++++ .../Mvc/AbpAspNetCoreMvcTestModule.cs | 10 ++- .../Mvc/Auditing/AuditTestController_Tests.cs | 1 + .../Mvc/Auditing/AuditTestPage.cshtml | 19 ++++++ .../Mvc/Auditing/AuditTestPage.cshtml.cs | 33 ++++++++++ .../Mvc/Auditing/AuditTestPage_Tests.cs | 65 +++++++++++++++++++ .../ExceptionTestController_Tests.cs | 4 ++ .../ExceptionTestPage.cshtml | 19 ++++++ .../ExceptionTestPage.cshtml.cs | 18 +++++ .../ExceptionTestPage_Tests.cs | 56 ++++++++++++++++ .../Mvc/Features/FeatureTestPage.cshtml | 19 ++++++ .../Mvc/Features/FeatureTestPage.cshtml.cs | 27 ++++++++ .../Mvc/Features/FeatureTestPage_Tests.cs | 34 ++++++++++ ...WorkPageFilter_Exception_Rollback_Tests.cs | 37 +++++++++++ .../Mvc/Uow/UnitOfWorkPageFilter_Tests.cs | 22 +++++++ .../Mvc/Uow/UnitOfWorkTestPage.cshtml | 19 ++++++ .../Mvc/Uow/UnitOfWorkTestPage.cshtml.cs | 54 +++++++++++++++ 24 files changed, 469 insertions(+), 35 deletions(-) create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Auditing/AuditTestPage.cshtml create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Auditing/AuditTestPage.cshtml.cs create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Auditing/AuditTestPage_Tests.cs create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/ExceptionHandling/ExceptionTestPage.cshtml create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/ExceptionHandling/ExceptionTestPage.cshtml.cs create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/ExceptionHandling/ExceptionTestPage_Tests.cs create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Features/FeatureTestPage.cshtml create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Features/FeatureTestPage.cshtml.cs create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Features/FeatureTestPage_Tests.cs create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Uow/UnitOfWorkPageFilter_Exception_Rollback_Tests.cs create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Uow/UnitOfWorkPageFilter_Tests.cs create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Uow/UnitOfWorkTestPage.cshtml create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Uow/UnitOfWorkTestPage.cshtml.cs diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Microsoft/AspNetCore/Mvc/Abstractions/ActionDescriptorExtensions.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Microsoft/AspNetCore/Mvc/Abstractions/ActionDescriptorExtensions.cs index 97b5a6c61b..f54375c844 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Microsoft/AspNetCore/Mvc/Abstractions/ActionDescriptorExtensions.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Microsoft/AspNetCore/Mvc/Abstractions/ActionDescriptorExtensions.cs @@ -38,31 +38,6 @@ namespace Microsoft.AspNetCore.Mvc.Abstractions { return actionDescriptor is ControllerActionDescriptor; } - - public static PageActionDescriptor AsPageActionDescriptor(this ActionDescriptor actionDescriptor) - { - if (!actionDescriptor.IsPageAction()) - { - throw new AbpException($"{nameof(actionDescriptor)} should be type of {typeof(PageActionDescriptor).AssemblyQualifiedName}"); - } - - return actionDescriptor as PageActionDescriptor; - } - - public static MethodInfo GetPageActionMethodInfo(this ActionDescriptor actionDescriptor) - { - return actionDescriptor.AsPageActionDescriptor().GetMethodInfo(); - } - - public static Type GetPageActionReturnType(this PageActionDescriptor actionDescriptor) - { - return actionDescriptor.GetPageActionMethodInfo().ReturnType; - } - - public static bool HasObjectResult(this PageActionDescriptor actionDescriptor) - { - return ActionResultHelper.IsObjectResult(actionDescriptor.GetReturnType()); - } public static bool IsPageAction(this ActionDescriptor actionDescriptor) { diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcModule.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcModule.cs index 668e7a77dc..4d970acd45 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcModule.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcModule.cs @@ -1,4 +1,4 @@ -using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.ApplicationParts; using Microsoft.AspNetCore.Mvc.Controllers; using Microsoft.AspNetCore.Mvc.Filters; @@ -12,7 +12,9 @@ using System; using System.Collections.Generic; using System.Linq; using System.Reflection; +using Microsoft.AspNetCore.Mvc.Razor; using Microsoft.AspNetCore.Mvc.RazorPages; +using Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure; using Microsoft.Extensions.Hosting; using Volo.Abp.ApiVersioning; using Volo.Abp.AspNetCore.Mvc.Conventions; @@ -114,6 +116,9 @@ namespace Volo.Abp.AspNetCore.Mvc //Use DI to create view components context.Services.Replace(ServiceDescriptor.Singleton()); + //Use DI to create razor page + context.Services.Replace(ServiceDescriptor.Singleton()); + //Add feature providers var partManager = context.Services.GetSingletonInstance(); var application = context.Services.GetSingletonInstance(); diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpMvcOptionsExtensions.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpMvcOptionsExtensions.cs index 64d9daca93..f1225f1abf 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpMvcOptionsExtensions.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpMvcOptionsExtensions.cs @@ -39,10 +39,10 @@ namespace Volo.Abp.AspNetCore.Mvc private static void AddPageFilters(MvcOptions options) { + options.Filters.AddService(typeof(AbpExceptionPageFilter)); options.Filters.AddService(typeof(AbpAuditPageFilter)); options.Filters.AddService(typeof(AbpFeaturePageFilter)); options.Filters.AddService(typeof(AbpUowPageFilter)); - options.Filters.AddService(typeof(AbpExceptionPageFilter)); } private static void AddModelBinders(MvcOptions options) diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Auditing/AbpAuditPageFilter.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Auditing/AbpAuditPageFilter.cs index 23e94790e9..6e9996574c 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Auditing/AbpAuditPageFilter.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Auditing/AbpAuditPageFilter.cs @@ -84,7 +84,7 @@ namespace Volo.Abp.AspNetCore.Mvc.Auditing return false; } - if (!_auditingHelper.ShouldSaveAudit(context.ActionDescriptor.GetMethodInfo(), true)) + if (!_auditingHelper.ShouldSaveAudit(context.HandlerMethod.MethodInfo, true)) { return false; } @@ -92,8 +92,8 @@ namespace Volo.Abp.AspNetCore.Mvc.Auditing auditLog = auditLogScope.Log; auditLogAction = _auditingHelper.CreateAuditLogAction( auditLog, - context.ActionDescriptor.AsControllerActionDescriptor().ControllerTypeInfo.AsType(), - context.ActionDescriptor.AsControllerActionDescriptor().MethodInfo, + context.HandlerMethod.GetType(), + context.HandlerMethod.MethodInfo, context.HandlerArguments ); diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ExceptionHandling/AbpExceptionPageFilter.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ExceptionHandling/AbpExceptionPageFilter.cs index 8aa45688ca..fb0a7c5a1f 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ExceptionHandling/AbpExceptionPageFilter.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ExceptionHandling/AbpExceptionPageFilter.cs @@ -63,7 +63,7 @@ namespace Volo.Abp.AspNetCore.Mvc.ExceptionHandling //TODO: Create DontWrap attribute to control wrapping..? if (context.ActionDescriptor.IsPageAction() && - context.ActionDescriptor.HasObjectResult()) + ActionResultHelper.IsObjectResult(context.HandlerMethod.MethodInfo.ReturnType)) { return true; } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Features/AbpFeaturePageFilter.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Features/AbpFeaturePageFilter.cs index ceb117d2ff..83e26ace9c 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Features/AbpFeaturePageFilter.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Features/AbpFeaturePageFilter.cs @@ -29,7 +29,7 @@ namespace Volo.Abp.AspNetCore.Mvc.Features return; } - var methodInfo = context.ActionDescriptor.GetMethodInfo(); + var methodInfo = context.HandlerMethod.MethodInfo; using (AbpCrossCuttingConcerns.Applying(context.HandlerInstance, AbpCrossCuttingConcerns.FeatureChecking)) { diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Uow/AbpUowPageFilter.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Uow/AbpUowPageFilter.cs index aeed982173..993a12b0e7 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Uow/AbpUowPageFilter.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Uow/AbpUowPageFilter.cs @@ -33,12 +33,12 @@ namespace Volo.Abp.AspNetCore.Mvc.Uow return; } - var methodInfo = context.ActionDescriptor.GetMethodInfo(); + var methodInfo = context.HandlerMethod.MethodInfo; var unitOfWorkAttr = UnitOfWorkHelper.GetUnitOfWorkAttributeOrNull(methodInfo); context.HttpContext.Items["_AbpActionInfo"] = new AbpActionInfoInHttpContext { - IsObjectResult = context.ActionDescriptor.HasObjectResult() + IsObjectResult = ActionResultHelper.IsObjectResult(context.HandlerMethod.MethodInfo.ReturnType) }; if (unitOfWorkAttr?.IsDisabled == true) diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo.Abp.AspNetCore.Mvc.Tests.csproj b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo.Abp.AspNetCore.Mvc.Tests.csproj index ddb3f5bc44..d47b369902 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo.Abp.AspNetCore.Mvc.Tests.csproj +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo.Abp.AspNetCore.Mvc.Tests.csproj @@ -24,6 +24,7 @@ + @@ -39,6 +40,24 @@ PreserveNewest + + + true + PreserveNewest + + + true + PreserveNewest + + + true + PreserveNewest + + + true + PreserveNewest + + diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcTestModule.cs b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcTestModule.cs index 5e74ec4bfa..39b7d9af5f 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcTestModule.cs +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcTestModule.cs @@ -1,6 +1,9 @@ -using System; +using System; +using System.Linq; using Localization.Resources.AbpUi; using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Mvc.ApplicationModels; +using Microsoft.AspNetCore.Mvc.RazorPages; using Microsoft.Extensions.DependencyInjection; using Volo.Abp.AspNetCore.Mvc.Authorization; using Volo.Abp.AspNetCore.Mvc.Localization; @@ -73,6 +76,11 @@ namespace Volo.Abp.AspNetCore.Mvc options.Languages.Add(new LanguageInfo("en", "en", "English")); options.Languages.Add(new LanguageInfo("tr", "tr", "Türkçe")); }); + + Configure(options => + { + options.RootDirectory = "/Volo/Abp/AspNetCore/Mvc"; + }); } public override void OnApplicationInitialization(ApplicationInitializationContext context) diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Auditing/AuditTestController_Tests.cs b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Auditing/AuditTestController_Tests.cs index 49bc689e14..3f934d5fe8 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Auditing/AuditTestController_Tests.cs +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Auditing/AuditTestController_Tests.cs @@ -51,6 +51,7 @@ namespace Volo.Abp.AspNetCore.Mvc.Auditing await _auditingStore.Received().SaveAsync(Arg.Any()); } + [Fact] public async Task Should_Trigger_Middleware_And_AuditLog_Exception_When_Returns_Object() { diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Auditing/AuditTestPage.cshtml b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Auditing/AuditTestPage.cshtml new file mode 100644 index 0000000000..bf85af77ef --- /dev/null +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Auditing/AuditTestPage.cshtml @@ -0,0 +1,19 @@ +@page +@model Volo.Abp.AspNetCore.Mvc.Auditing.AuditTestPage + +@{ + Layout = null; +} + + + + + + + + +
+ +
+ + \ No newline at end of file diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Auditing/AuditTestPage.cshtml.cs b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Auditing/AuditTestPage.cshtml.cs new file mode 100644 index 0000000000..6425d6585b --- /dev/null +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Auditing/AuditTestPage.cshtml.cs @@ -0,0 +1,33 @@ +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.RazorPages; +using Microsoft.Extensions.Options; +using Volo.Abp.AspNetCore.Mvc.UI.RazorPages; +using Volo.Abp.Auditing; + +namespace Volo.Abp.AspNetCore.Mvc.Auditing +{ + public class AuditTestPage : AbpPageModel + { + private readonly AbpAuditingOptions _options; + + public AuditTestPage(IOptions options) + { + _options = options.Value; + } + + public IActionResult OnGetAuditSuccessForGetRequests() + { + return new OkResult(); + } + + public IActionResult OnGetAuditFailForGetRequests() + { + throw new UserFriendlyException("Exception occurred!"); + } + + public ObjectResult OnGetAuditFailForGetRequestsReturningObject() + { + throw new UserFriendlyException("Exception occurred!"); + } + } +} \ No newline at end of file diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Auditing/AuditTestPage_Tests.cs b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Auditing/AuditTestPage_Tests.cs new file mode 100644 index 0000000000..7d5298e253 --- /dev/null +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Auditing/AuditTestPage_Tests.cs @@ -0,0 +1,65 @@ +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Options; +using NSubstitute; +using Volo.Abp.Auditing; +using Xunit; + +namespace Volo.Abp.AspNetCore.Mvc.Auditing +{ + public class AuditTestPage_Tests : AspNetCoreMvcTestBase + { + private readonly AbpAuditingOptions _options; + private IAuditingStore _auditingStore; + + public AuditTestPage_Tests() + { + _options = ServiceProvider.GetRequiredService>().Value; + _auditingStore = ServiceProvider.GetRequiredService(); + } + + protected override void ConfigureServices(HostBuilderContext context, IServiceCollection services) + { + _auditingStore = Substitute.For(); + services.Replace(ServiceDescriptor.Singleton(_auditingStore)); + base.ConfigureServices(context, services); + } + + [Fact] + public async Task Should_Trigger_Middleware_And_AuditLog_Success_For_GetRequests() + { + _options.IsEnabledForGetRequests = true; + _options.AlwaysLogOnException = false; + await GetResponseAsync("/Auditing/AuditTestPage?handler=AuditSuccessForGetRequests"); + await _auditingStore.Received().SaveAsync(Arg.Any()); + } + + [Fact] + public async Task Should_Trigger_Middleware_And_AuditLog_Exception_Always() + { + _options.IsEnabled = true; + _options.AlwaysLogOnException = true; + + try + { + await GetResponseAsync("/Auditing/AuditTestPage?handler=AuditFailForGetRequests", System.Net.HttpStatusCode.Forbidden); + } + catch { } + + await _auditingStore.Received().SaveAsync(Arg.Any()); + } + + [Fact] + public async Task Should_Trigger_Middleware_And_AuditLog_Exception_When_Returns_Object() + { + _options.IsEnabled = true; + _options.AlwaysLogOnException = true; + + await GetResponseAsync("/Auditing/AuditTestPage?handler=AuditFailForGetRequestsReturningObject", System.Net.HttpStatusCode.Forbidden); + + await _auditingStore.Received().SaveAsync(Arg.Any()); + } + } +} \ No newline at end of file diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/ExceptionHandling/ExceptionTestController_Tests.cs b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/ExceptionHandling/ExceptionTestController_Tests.cs index 0de46fbe55..46cdd073e7 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/ExceptionHandling/ExceptionTestController_Tests.cs +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/ExceptionHandling/ExceptionTestController_Tests.cs @@ -30,9 +30,11 @@ namespace Volo.Abp.AspNetCore.Mvc.ExceptionHandling result.Error.ShouldNotBeNull(); result.Error.Message.ShouldBe("This is a sample exception!"); +#pragma warning disable 4014 _fakeExceptionSubscriber .Received() .HandleAsync(Arg.Any()); +#pragma warning restore 4014 } [Fact] @@ -44,9 +46,11 @@ namespace Volo.Abp.AspNetCore.Mvc.ExceptionHandling ) ); +#pragma warning disable 4014 _fakeExceptionSubscriber .DidNotReceive() .HandleAsync(Arg.Any()); +#pragma warning restore 4014 } } } diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/ExceptionHandling/ExceptionTestPage.cshtml b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/ExceptionHandling/ExceptionTestPage.cshtml new file mode 100644 index 0000000000..7ba36da037 --- /dev/null +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/ExceptionHandling/ExceptionTestPage.cshtml @@ -0,0 +1,19 @@ +@page +@model Volo.Abp.AspNetCore.Mvc.ExceptionHandling.ExceptionTestPage + +@{ + Layout = null; +} + + + + + + + + +
+ +
+ + \ No newline at end of file diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/ExceptionHandling/ExceptionTestPage.cshtml.cs b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/ExceptionHandling/ExceptionTestPage.cshtml.cs new file mode 100644 index 0000000000..717d31effe --- /dev/null +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/ExceptionHandling/ExceptionTestPage.cshtml.cs @@ -0,0 +1,18 @@ +using Microsoft.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc.UI.RazorPages; + +namespace Volo.Abp.AspNetCore.Mvc.ExceptionHandling +{ + public class ExceptionTestPage : AbpPageModel + { + public void OnGetUserFriendlyException1() + { + throw new UserFriendlyException("This is a sample exception!"); + } + + public IActionResult OnGetUserFriendlyException2() + { + throw new UserFriendlyException("This is a sample exception!"); + } + } +} \ No newline at end of file diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/ExceptionHandling/ExceptionTestPage_Tests.cs b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/ExceptionHandling/ExceptionTestPage_Tests.cs new file mode 100644 index 0000000000..7013c0c676 --- /dev/null +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/ExceptionHandling/ExceptionTestPage_Tests.cs @@ -0,0 +1,56 @@ +using System.Net; +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using NSubstitute; +using Shouldly; +using Volo.Abp.ExceptionHandling; +using Volo.Abp.Http; +using Xunit; + +namespace Volo.Abp.AspNetCore.Mvc.ExceptionHandling +{ + public class ExceptionTestPage_Tests : AspNetCoreMvcTestBase + { + private IExceptionSubscriber _fakeExceptionSubscriber; + + protected override void ConfigureServices(HostBuilderContext context, IServiceCollection services) + { + base.ConfigureServices(context, services); + + _fakeExceptionSubscriber = Substitute.For(); + + services.AddSingleton(_fakeExceptionSubscriber); + } + + [Fact] + public async Task Should_Return_RemoteServiceErrorResponse_For_UserFriendlyException_For_Void_Return_Value() + { + var result = await GetResponseAsObjectAsync("/ExceptionHandling/ExceptionTestPage?handler=UserFriendlyException1", HttpStatusCode.Forbidden); + result.Error.ShouldNotBeNull(); + result.Error.Message.ShouldBe("This is a sample exception!"); + +#pragma warning disable 4014 + _fakeExceptionSubscriber + .Received() + .HandleAsync(Arg.Any()); +#pragma warning restore 4014 + } + + [Fact] + public async Task Should_Not_Handle_Exceptions_For_ActionResult_Return_Values() + { + await Assert.ThrowsAsync( + async () => await GetResponseAsObjectAsync( + "/ExceptionHandling/ExceptionTestPage?handler=UserFriendlyException2" + ) + ); + +#pragma warning disable 4014 + _fakeExceptionSubscriber + .DidNotReceive() + .HandleAsync(Arg.Any()); +#pragma warning restore 4014 + } + } +} \ No newline at end of file diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Features/FeatureTestPage.cshtml b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Features/FeatureTestPage.cshtml new file mode 100644 index 0000000000..8f0450becb --- /dev/null +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Features/FeatureTestPage.cshtml @@ -0,0 +1,19 @@ +@page +@model Volo.Abp.AspNetCore.Mvc.Features.FeatureTestPage + +@{ + Layout = null; +} + + + + + + + + +
+ +
+ + \ No newline at end of file diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Features/FeatureTestPage.cshtml.cs b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Features/FeatureTestPage.cshtml.cs new file mode 100644 index 0000000000..6a051a29ee --- /dev/null +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Features/FeatureTestPage.cshtml.cs @@ -0,0 +1,27 @@ +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc.UI.RazorPages; +using Volo.Abp.Features; + +namespace Volo.Abp.AspNetCore.Mvc.Features +{ + public class FeatureTestPage : AbpPageModel + { + [RequiresFeature("AllowedFeature")] + public Task OnGetAllowedFeatureAsync() + { + return Task.CompletedTask; + } + + [RequiresFeature("NotAllowedFeature")] + public void OnGetNotAllowedFeature() + { + + } + + public ObjectResult OnGetNoFeature() + { + return new ObjectResult(42); + } + } +} \ No newline at end of file diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Features/FeatureTestPage_Tests.cs b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Features/FeatureTestPage_Tests.cs new file mode 100644 index 0000000000..91226f1938 --- /dev/null +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Features/FeatureTestPage_Tests.cs @@ -0,0 +1,34 @@ +using System.Net; +using System.Threading.Tasks; +using Xunit; + +namespace Volo.Abp.AspNetCore.Mvc.Features +{ + public class FeatureTestPage_Tests : AspNetCoreMvcTestBase + { + [Fact] + public async Task Should_Allow_Enabled_Features() + { + await GetResponseAsStringAsync( + "/Features/FeatureTestPage?handler=AllowedFeature" + ); + } + + [Fact] + public async Task Should_Not_Allow_Not_Enabled_Features() + { + await GetResponseAsStringAsync( + "/Features/FeatureTestPage?handler=NotAllowedFeature", + HttpStatusCode.Unauthorized + ); + } + + [Fact] + public async Task Should_Allow_Actions_With_No_Feature() + { + await GetResponseAsStringAsync( + "/Features/FeatureTestPage?handler=NoFeature" + ); + } + } +} \ No newline at end of file diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Uow/UnitOfWorkPageFilter_Exception_Rollback_Tests.cs b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Uow/UnitOfWorkPageFilter_Exception_Rollback_Tests.cs new file mode 100644 index 0000000000..b09d3ca2c9 --- /dev/null +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Uow/UnitOfWorkPageFilter_Exception_Rollback_Tests.cs @@ -0,0 +1,37 @@ +using System.Linq; +using System.Net; +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; +using Shouldly; +using Volo.Abp.Http; +using Volo.Abp.Json; +using Xunit; + +namespace Volo.Abp.AspNetCore.Mvc.Uow +{ + public class UnitOfWorkPageFilter_Exception_Rollback_Tests : AspNetCoreMvcTestBase + { + [Fact] + public async Task Should_Rollback_Transaction_For_Handled_Exceptions() + { + var result = await GetResponseAsObjectAsync("/Uow/UnitOfWorkTestPage?handler=HandledException", HttpStatusCode.Forbidden); + result.Error.ShouldNotBeNull(); + result.Error.Message.ShouldBe("This is a sample exception!"); + } + + [Fact] + public async Task Should_Gracefully_Handle_Exceptions_On_Complete() + { + var response = await GetResponseAsync("/Uow/UnitOfWorkTestPage?handler=ExceptionOnComplete", HttpStatusCode.Forbidden); + + response.Headers.GetValues(AbpHttpConsts.AbpErrorFormat).FirstOrDefault().ShouldBe("true"); + + var resultAsString = await response.Content.ReadAsStringAsync(); + + var result = ServiceProvider.GetRequiredService().Deserialize(resultAsString); + + result.Error.ShouldNotBeNull(); + result.Error.Message.ShouldBe(TestUnitOfWorkConfig.ExceptionOnCompleteMessage); + } + } +} \ No newline at end of file diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Uow/UnitOfWorkPageFilter_Tests.cs b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Uow/UnitOfWorkPageFilter_Tests.cs new file mode 100644 index 0000000000..820ccf91b7 --- /dev/null +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Uow/UnitOfWorkPageFilter_Tests.cs @@ -0,0 +1,22 @@ +using System.Threading.Tasks; +using Shouldly; +using Xunit; + +namespace Volo.Abp.AspNetCore.Mvc.Uow +{ + public class UnitOfWorkPageFilter_Tests: AspNetCoreMvcTestBase + { + [Fact] + public async Task Get_Actions_Should_Not_Be_Transactional() + { + await GetResponseAsStringAsync("/Uow/UnitOfWorkTestPage?handler=RequiresUow"); + } + + [Fact] + public async Task Non_Get_Actions_Should_Be_Transactional() + { + var result = await Client.PostAsync("/Uow/UnitOfWorkTestPage?handler=RequiresUow", null); + result.IsSuccessStatusCode.ShouldBeTrue(); + } + } +} \ No newline at end of file diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Uow/UnitOfWorkTestPage.cshtml b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Uow/UnitOfWorkTestPage.cshtml new file mode 100644 index 0000000000..da30a64818 --- /dev/null +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Uow/UnitOfWorkTestPage.cshtml @@ -0,0 +1,19 @@ +@page +@model Volo.Abp.AspNetCore.Mvc.Uow.UnitOfWorkTestPage + +@{ + Layout = null; +} + + + + + + + + +
+ +
+ + \ No newline at end of file diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Uow/UnitOfWorkTestPage.cshtml.cs b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Uow/UnitOfWorkTestPage.cshtml.cs new file mode 100644 index 0000000000..ce54e8d34f --- /dev/null +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Uow/UnitOfWorkTestPage.cshtml.cs @@ -0,0 +1,54 @@ +using Microsoft.AspNetCore.Mvc; +using Shouldly; +using Volo.Abp.AspNetCore.Mvc.UI.RazorPages; +using Volo.Abp.Uow; + +namespace Volo.Abp.AspNetCore.Mvc.Uow +{ + [IgnoreAntiforgeryToken] + public class UnitOfWorkTestPage : AbpPageModel + { + private readonly TestUnitOfWorkConfig _testUnitOfWorkConfig; + + public UnitOfWorkTestPage(TestUnitOfWorkConfig testUnitOfWorkConfig) + { + _testUnitOfWorkConfig = testUnitOfWorkConfig; + } + + public IActionResult OnGetRequiresUow() + { + CurrentUnitOfWork.ShouldNotBeNull(); + CurrentUnitOfWork.Options.IsTransactional.ShouldBeFalse(); + + return Content("OK"); + } + + public IActionResult OnPostRequiresUow() + { + CurrentUnitOfWork.ShouldNotBeNull(); + CurrentUnitOfWork.Options.IsTransactional.ShouldBeTrue(); + + return Content("OK"); + } + + [UnitOfWork(isTransactional: true)] + public void OnGetHandledException() + { + CurrentUnitOfWork.ShouldNotBeNull(); + CurrentUnitOfWork.Options.IsTransactional.ShouldBeTrue(); + + throw new UserFriendlyException("This is a sample exception!"); + } + + public ObjectResult OnGetExceptionOnComplete() + { + CurrentUnitOfWork.ShouldNotBeNull(); + CurrentUnitOfWork.Options.IsTransactional.ShouldBeFalse(); + + _testUnitOfWorkConfig.ThrowExceptionOnComplete = true; + + //Prevent rendering of pages. + return new ObjectResult(""); + } + } +} \ No newline at end of file From 406d1cdb9b22c22d028043790d2f0bfc8aed015a Mon Sep 17 00:00:00 2001 From: maliming Date: Fri, 27 Mar 2020 16:34:21 +0800 Subject: [PATCH 072/334] Remove ViewComponent in DynamicProxyIgnoreTypes. --- .../Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcModule.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcModule.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcModule.cs index 4d970acd45..b3f70b161d 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcModule.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcModule.cs @@ -44,7 +44,6 @@ namespace Volo.Abp.AspNetCore.Mvc { DynamicProxyIgnoreTypes.Add(); DynamicProxyIgnoreTypes.Add(); - DynamicProxyIgnoreTypes.Add(); context.Services.AddConventionalRegistrar(new AbpAspNetCoreMvcConventionalRegistrar()); } From abda1104aed9ec70b2a08e6ced5399b1cdf29f80 Mon Sep 17 00:00:00 2001 From: maliming Date: Fri, 27 Mar 2020 21:23:30 +0800 Subject: [PATCH 073/334] Add authorization unit test for razor page. --- .../Volo.Abp.AspNetCore.Mvc.Tests.csproj | 4 ++ .../Mvc/Authorization/AuthTestPage.cshtml | 19 +++++++++ .../Mvc/Authorization/AuthTestPage.cshtml.cs | 18 +++++++++ .../Mvc/Authorization/AuthTestPage_Tests.cs | 40 +++++++++++++++++++ 4 files changed, 81 insertions(+) create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Authorization/AuthTestPage.cshtml create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Authorization/AuthTestPage.cshtml.cs create mode 100644 framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Authorization/AuthTestPage_Tests.cs diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo.Abp.AspNetCore.Mvc.Tests.csproj b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo.Abp.AspNetCore.Mvc.Tests.csproj index d47b369902..bb841bc085 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo.Abp.AspNetCore.Mvc.Tests.csproj +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo.Abp.AspNetCore.Mvc.Tests.csproj @@ -57,6 +57,10 @@ true PreserveNewest + + true + PreserveNewest + diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Authorization/AuthTestPage.cshtml b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Authorization/AuthTestPage.cshtml new file mode 100644 index 0000000000..cf94310510 --- /dev/null +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Authorization/AuthTestPage.cshtml @@ -0,0 +1,19 @@ +@page +@model Volo.Abp.AspNetCore.Mvc.Authorization.AuthTestPage + +@{ + Layout = null; +} + + + + + + + + +
+ +
+ + \ No newline at end of file diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Authorization/AuthTestPage.cshtml.cs b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Authorization/AuthTestPage.cshtml.cs new file mode 100644 index 0000000000..5ae66edb5f --- /dev/null +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Authorization/AuthTestPage.cshtml.cs @@ -0,0 +1,18 @@ +using System; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc.UI.RazorPages; + +namespace Volo.Abp.AspNetCore.Mvc.Authorization +{ + [Authorize] + public class AuthTestPage : AbpPageModel + { + public static Guid FakeUserId { get; } = Guid.NewGuid(); + + public ActionResult OnGet() + { + return Content("OK"); + } + } +} \ No newline at end of file diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Authorization/AuthTestPage_Tests.cs b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Authorization/AuthTestPage_Tests.cs new file mode 100644 index 0000000000..ec8a043fbe --- /dev/null +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Authorization/AuthTestPage_Tests.cs @@ -0,0 +1,40 @@ +using System.Security.Claims; +using System.Threading.Tasks; +using Shouldly; +using Volo.Abp.AspNetCore.TestBase; +using Volo.Abp.Autofac; +using Volo.Abp.MemoryDb; +using Volo.Abp.Modularity; +using Volo.Abp.Security.Claims; +using Xunit; + +namespace Volo.Abp.AspNetCore.Mvc.Authorization +{ + [DependsOn( + typeof(AbpAspNetCoreTestBaseModule), + typeof(AbpMemoryDbTestModule), + typeof(AbpAspNetCoreMvcModule), + typeof(AbpAutofacModule) + )] + public class AuthTestPage_Tests: AspNetCoreMvcTestBase + { + private readonly FakeUserClaims _fakeRequiredService; + + public AuthTestPage_Tests() + { + _fakeRequiredService = GetRequiredService(); + } + + [Fact] + public async Task Should_Call_Simple_Authorized_Method_With_Authenticated_User() + { + _fakeRequiredService.Claims.AddRange(new[] + { + new Claim(AbpClaimTypes.UserId, AuthTestController.FakeUserId.ToString()) + }); + + var result = await GetResponseAsStringAsync("/Authorization/AuthTestPage"); + result.ShouldBe("OK"); + } + } +} \ No newline at end of file From 65a7ea84a2173a1b900f4426d0b2dd799750d19e Mon Sep 17 00:00:00 2001 From: maliming Date: Mon, 30 Mar 2020 14:54:03 +0800 Subject: [PATCH 074/334] Removed UnitOfWork attribute in razor page model. --- .../src/Volo.Abp.Account.Web/Pages/Account/Login.cshtml.cs | 3 --- .../src/Volo.Abp.Account.Web/Pages/Account/Register.cshtml.cs | 1 - 2 files changed, 4 deletions(-) diff --git a/modules/account/src/Volo.Abp.Account.Web/Pages/Account/Login.cshtml.cs b/modules/account/src/Volo.Abp.Account.Web/Pages/Account/Login.cshtml.cs index 014088983a..db0cf372d7 100644 --- a/modules/account/src/Volo.Abp.Account.Web/Pages/Account/Login.cshtml.cs +++ b/modules/account/src/Volo.Abp.Account.Web/Pages/Account/Login.cshtml.cs @@ -87,7 +87,6 @@ namespace Volo.Abp.Account.Web.Pages.Account return Page(); } - [UnitOfWork] //TODO: Will be removed when we implement action filter public virtual async Task OnPostAsync(string action) { await CheckLocalLoginAsync(); @@ -140,7 +139,6 @@ namespace Volo.Abp.Account.Web.Pages.Account return RedirectSafely(ReturnUrl, ReturnUrlHash); } - [UnitOfWork] public virtual async Task OnPostExternalLogin(string provider) { var redirectUrl = Url.Page("./Login", pageHandler: "ExternalLoginCallback", values: new { ReturnUrl, ReturnUrlHash }); @@ -150,7 +148,6 @@ namespace Volo.Abp.Account.Web.Pages.Account return await Task.FromResult(Challenge(properties, provider)); } - [UnitOfWork] public virtual async Task OnGetExternalLoginCallbackAsync(string returnUrl = "", string returnUrlHash = "", string remoteError = null) { //TODO: Did not implemented Identity Server 4 sample for this method (see ExternalLoginCallback in Quickstart of IDS4 sample) diff --git a/modules/account/src/Volo.Abp.Account.Web/Pages/Account/Register.cshtml.cs b/modules/account/src/Volo.Abp.Account.Web/Pages/Account/Register.cshtml.cs index 0cb71f2ed9..db085d6587 100644 --- a/modules/account/src/Volo.Abp.Account.Web/Pages/Account/Register.cshtml.cs +++ b/modules/account/src/Volo.Abp.Account.Web/Pages/Account/Register.cshtml.cs @@ -36,7 +36,6 @@ namespace Volo.Abp.Account.Web.Pages.Account await CheckSelfRegistrationAsync(); } - [UnitOfWork] //TODO: Will be removed when we implement action filter public virtual async Task OnPostAsync() { ValidateModel(); From ea9118dfee97fd2583d0d3da3a89876df73a69e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leon=20Ko=C5=A1ak?= Date: Tue, 31 Mar 2020 08:51:27 +0200 Subject: [PATCH 075/334] Slovenian translations for Volo.Abp.UI --- .../Localization/Resources/AbpUi/sl.json | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/sl.json diff --git a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/sl.json b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/sl.json new file mode 100644 index 0000000000..641de8a242 --- /dev/null +++ b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/sl.json @@ -0,0 +1,62 @@ +{ + "culture": "sl", + "texts": { + "InternalServerErrorMessage": "Zgodila se je napaka na strežniku!", + "ValidationErrorMessage": "Vaš zahtevek ni veljaven!", + "ValidationNarrativeErrorMessageTitle": "Pri preverjanju so bile zaznane sledeče napake.", + "DefaultErrorMessage": "Zgodila se je napaka!", + "DefaultErrorMessageDetail": "Strežnik ni poslal podrobnosti o napaki.", + "DefaultErrorMessage401": "Niste prijavljeni!", + "DefaultErrorMessage401Detail": "Za izvedbo te operacije se morate prijaviti.", + "DefaultErrorMessage403": "Nimate pravic!", + "DefaultErrorMessage403Detail": "Nimate dovoljenja za izvedbo te operacije!", + "DefaultErrorMessage404": "Vir ni bil najden!", + "DefaultErrorMessage404Detail": "Zahtevanega vira ni bilo mogoče najti na strežniku!", + "EntityNotFoundErrorMessage": "Ni entitete {0} z id-jem = {1}!", + "Languages": "Jeziki", + "Error": "Napaka", + "AreYouSure": "Ali ste prepričani?", + "Cancel": "Prekliči", + "Yes": "Da", + "No": "Ne", + "Ok": "V redu", + "Close": "Zapri", + "Save": "Shrani", + "SavingWithThreeDot": "Shranjujem...", + "Actions": "Dejanja", + "Delete": "Izbriši", + "Edit": "Uredi", + "Refresh": "Osveži", + "Language": "Jezik", + "LoadMore": "Naloži več", + "ProcessingWithThreeDot": "Procesiram...", + "LoadingWithThreeDot": "Nalagam...", + "Welcome": "Dobrodošli", + "Login": "Prijava", + "Register": "Registracija", + "Logout": "Odjava", + "Submit": "Pošlji", + "Back": "Nazaj", + "PagerSearch": "Iskanje", + "PagerNext": "Naslednja", + "PagerPrevious": "Prejšnja", + "PagerFirst": "Prva", + "PagerLast": "Zadnja", + "PagerInfo": "Prikazanih _START_ do _END_ od _TOTAL_ zapisov", + "PagerInfoEmpty": "Prikazanih 0 do 0 od 0 zapisov", + "PagerInfoFiltered": "(filtrirano od vseh _MAX_ zapisov)", + "NoDataAvailableInDatatable": "V tabeli ni na voljo podatkov", + "PagerShowMenuEntries": "Prikaži _MENU_ zapise", + "DatatableActionDropdownDefaultText": "Dejanja", + "ChangePassword": "Zamenjaj geslo", + "PersonalInfo": "Moj profil", + "AreYouSureYouWantToCancelEditingWarningMessage": "Imate neshranjene spremembe.", + "UnhandledException": "Neobravnavana napaka!", + "401Message": "Nepooblaščeno", + "403Message": "Prepovedano", + "404Message": "Strani ni mogoče najti", + "500Message": "Napaka na strani strežnika", + "GoHomePage": "Pojdi na osnovno stran", + "GoBack": "Nazaj" + } +} From a5d8452934e13b49f16c767ee473b2eea5362211 Mon Sep 17 00:00:00 2001 From: fmpfmp Date: Thu, 2 Apr 2020 10:32:45 +0800 Subject: [PATCH 076/334] add Feature Management Module Description add Feature Management Module Description --- docs/zh-Hans/Modules/Index.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/zh-Hans/Modules/Index.md b/docs/zh-Hans/Modules/Index.md index 9b44967c53..fb07b5b001 100644 --- a/docs/zh-Hans/Modules/Index.md +++ b/docs/zh-Hans/Modules/Index.md @@ -16,6 +16,7 @@ ABP是一个 **模块化的应用程序框架** 由十多个 **nuget packages** * **Background Jobs**: 用于在使用默认后台作业管理器时保存后台作业. * **Blogging**: 用于创建精美的博客. ABP的[博客](https://blog.abp.io/) 就使用了此模块. * [**Docs**](Docs.md): 用于创建技术文档页面. ABP的[文档](https://abp.io/documents/) 就使用了此模块. +* **Feature Management**: 用于保存和管理功能. * **Identity**: 基于Microsoft Identity管理角色,用户和他们的权限. * **Identity Server**: 集成了IdentityServer4. * **Permission Management**: 用于保存权限. @@ -27,4 +28,4 @@ ABP是一个 **模块化的应用程序框架** 由十多个 **nuget packages** ## 商业应用模块 -[ABP商业](https://commercial.abp.io/)许可证在ABP框架上提供了额外的预构建应用程序模块. 参见ABP商业版提供的[模块列表](https://commercial.abp.io/module). \ No newline at end of file +[ABP商业](https://commercial.abp.io/)许可证在ABP框架上提供了额外的预构建应用程序模块. 参见ABP商业版提供的[模块列表](https://commercial.abp.io/module). From 8df24a62fd35acd64b7f1f79a8c30f74c6d20805 Mon Sep 17 00:00:00 2001 From: Oliver Cooper Date: Thu, 2 Apr 2020 17:44:17 +0100 Subject: [PATCH 077/334] Add Quartz StartupDelay option. --- .../Volo/Abp/Quartz/AbpQuartzModule.cs | 9 ++++++++- .../Volo/Abp/Quartz/AbpQuartzPreOptions.cs | 11 ++++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/framework/src/Volo.Abp.Quartz/Volo/Abp/Quartz/AbpQuartzModule.cs b/framework/src/Volo.Abp.Quartz/Volo/Abp/Quartz/AbpQuartzModule.cs index c16ab14f4d..615009f914 100644 --- a/framework/src/Volo.Abp.Quartz/Volo/Abp/Quartz/AbpQuartzModule.cs +++ b/framework/src/Volo.Abp.Quartz/Volo/Abp/Quartz/AbpQuartzModule.cs @@ -1,4 +1,5 @@ using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; using Quartz; using Quartz.Impl; using Quartz.Spi; @@ -20,9 +21,15 @@ namespace Volo.Abp.Quartz public override void OnApplicationInitialization(ApplicationInitializationContext context) { + var options = context.ServiceProvider.GetRequiredService>().Value; + _scheduler = context.ServiceProvider.GetService(); _scheduler.JobFactory = context.ServiceProvider.GetService(); - _scheduler.Start(); + + if (options.StartDelay != null && options.StartDelay.Ticks > 0) + _scheduler.StartDelayed(options.StartDelay); + else + _scheduler.Start(); } public override void OnApplicationShutdown(ApplicationShutdownContext context) diff --git a/framework/src/Volo.Abp.Quartz/Volo/Abp/Quartz/AbpQuartzPreOptions.cs b/framework/src/Volo.Abp.Quartz/Volo/Abp/Quartz/AbpQuartzPreOptions.cs index e86f993d1d..9e48744d96 100644 --- a/framework/src/Volo.Abp.Quartz/Volo/Abp/Quartz/AbpQuartzPreOptions.cs +++ b/framework/src/Volo.Abp.Quartz/Volo/Abp/Quartz/AbpQuartzPreOptions.cs @@ -1,14 +1,23 @@ -using System.Collections.Specialized; +using System; +using System.Collections.Specialized; namespace Volo.Abp.Quartz { public class AbpQuartzPreOptions { + /// + /// The quartz configuration. Available properties can be found within Quartz.Impl.StdSchedulerFactory. + /// public NameValueCollection Properties { get; set; } + /// + /// How long Quartz should wait before starting. Default: 0. + /// + public TimeSpan StartDelay { get; set; } public AbpQuartzPreOptions() { Properties = new NameValueCollection(); + StartDelay = new TimeSpan(0); } } } From b0f954036be466f40c35166ab321118429d24826 Mon Sep 17 00:00:00 2001 From: Oliver Cooper Date: Fri, 3 Apr 2020 07:30:40 +0000 Subject: [PATCH 078/334] Added braces and removed null check on StartDelay. --- .../src/Volo.Abp.Quartz/Volo/Abp/Quartz/AbpQuartzModule.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/framework/src/Volo.Abp.Quartz/Volo/Abp/Quartz/AbpQuartzModule.cs b/framework/src/Volo.Abp.Quartz/Volo/Abp/Quartz/AbpQuartzModule.cs index 615009f914..ccd0327ecf 100644 --- a/framework/src/Volo.Abp.Quartz/Volo/Abp/Quartz/AbpQuartzModule.cs +++ b/framework/src/Volo.Abp.Quartz/Volo/Abp/Quartz/AbpQuartzModule.cs @@ -26,10 +26,14 @@ namespace Volo.Abp.Quartz _scheduler = context.ServiceProvider.GetService(); _scheduler.JobFactory = context.ServiceProvider.GetService(); - if (options.StartDelay != null && options.StartDelay.Ticks > 0) + if (options.StartDelay.Ticks > 0) + { _scheduler.StartDelayed(options.StartDelay); + } else + { _scheduler.Start(); + } } public override void OnApplicationShutdown(ApplicationShutdownContext context) From fb8dee5cccff615c8f92b8734a292721986294ea Mon Sep 17 00:00:00 2001 From: maliming Date: Tue, 7 Apr 2020 11:13:42 +0800 Subject: [PATCH 079/334] Enhance EntityHelper's TrySetId method. Resolve #3461 --- .../Volo/Abp/Domain/Entities/EntityHelper.cs | 46 +++++++++++-------- .../Abp/Domain/Entities/EntityHelper_Tests.cs | 19 ++++++++ 2 files changed, 47 insertions(+), 18 deletions(-) diff --git a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/EntityHelper.cs b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/EntityHelper.cs index 2b38059ef8..5233f2accc 100644 --- a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/EntityHelper.cs +++ b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/EntityHelper.cs @@ -1,5 +1,7 @@ using System; +using System.Collections.Concurrent; using System.Collections.Generic; +using System.Linq; using System.Linq.Expressions; using System.Reflection; using JetBrains.Annotations; @@ -95,32 +97,40 @@ namespace Volo.Abp.Domain.Entities var lambdaBody = Expression.Equal(leftExpression, rightExpression); return Expression.Lambda>(lambdaBody, lambdaParam); } - + + private static readonly ConcurrentDictionary CachedPropertyInfo = + new ConcurrentDictionary(); + public static void TrySetId( IEntity entity, Func idFactory, bool checkForDisableGuidGenerationAttribute = false) { - //TODO: Can be optimized (by caching per entity type)? - var entityType = entity.GetType(); - var idProperty = entityType.GetProperty( - nameof(entity.Id) - ); + var property = CachedPropertyInfo.GetOrAdd( + entity.GetType().FullName + checkForDisableGuidGenerationAttribute, () => + { + var entityType = entity.GetType(); + var idProperty = entityType.GetProperties() + .Where(x => x.GetSetMethod(true) != null) + .FirstOrDefault(x => x.Name == nameof(entity.Id)); - if (idProperty == null || idProperty.GetSetMethod(true) == null) - { - return; - } + if (idProperty == null) + { + return null; + } - if (checkForDisableGuidGenerationAttribute) - { - if (idProperty.IsDefined(typeof(DisableIdGenerationAttribute), true)) - { - return; - } - } + if (checkForDisableGuidGenerationAttribute) + { + if (idProperty.IsDefined(typeof(DisableIdGenerationAttribute), true)) + { + return null; + } + } + + return idProperty; + }); - idProperty.SetValue(entity, idFactory()); + property?.SetValue(entity, idFactory()); } } } diff --git a/framework/test/Volo.Abp.Ddd.Tests/Volo/Abp/Domain/Entities/EntityHelper_Tests.cs b/framework/test/Volo.Abp.Ddd.Tests/Volo/Abp/Domain/Entities/EntityHelper_Tests.cs index 2ad6a45b05..8d405f6907 100644 --- a/framework/test/Volo.Abp.Ddd.Tests/Volo/Abp/Domain/Entities/EntityHelper_Tests.cs +++ b/framework/test/Volo.Abp.Ddd.Tests/Volo/Abp/Domain/Entities/EntityHelper_Tests.cs @@ -1,4 +1,5 @@ using System; +using System.ComponentModel; using Shouldly; using Xunit; @@ -33,6 +34,15 @@ namespace Volo.Abp.Domain.Entities myEntityDisablesIdGeneration.Id.ShouldBe(default); } + [Fact] + public static void SetId_NewIdFromBaseClass() + { + var idValue = Guid.NewGuid(); + var myNewIdEntity = new NewIdEntity(); + EntityHelper.TrySetId(myNewIdEntity, () => idValue, true); + myNewIdEntity.Id.ShouldBe(idValue); + } + private class MyEntityDerivedFromAggregateRoot : AggregateRoot { @@ -53,5 +63,14 @@ namespace Volo.Abp.Domain.Entities [DisableIdGeneration] public override Guid Id { get; protected set; } } + + public class NewIdEntity : Entity + { + public new Guid Id + { + get => base.Id; + set => base.Id = value; + } + } } } From c1e969cc3cdd619c436d6bfa281a6139451d2d00 Mon Sep 17 00:00:00 2001 From: Weihan Li Date: Tue, 7 Apr 2020 11:38:36 +0800 Subject: [PATCH 080/334] update IsRelational extension for EntityFramework --- .../Volo/Abp/EntityFrameworkCore/DatabaseFacadeExtensions.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/DatabaseFacadeExtensions.cs b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/DatabaseFacadeExtensions.cs index f663f43a0d..fbea680be1 100644 --- a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/DatabaseFacadeExtensions.cs +++ b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/DatabaseFacadeExtensions.cs @@ -8,7 +8,9 @@ namespace Volo.Abp.EntityFrameworkCore { public static bool IsRelational(this DatabaseFacade database) { - return database.GetInfrastructure().GetService() != null; +#pragma warning disable EF1001 // Internal EF Core API usage. + return ((IDatabaseFacadeDependenciesAccessor)database).Dependencies is IRelationalDatabaseFacadeDependencies; +#pragma warning restore EF1001 // Internal EF Core API usage. } } } From 0139ee819433699a7c5e54fe3019820e59d7f292 Mon Sep 17 00:00:00 2001 From: mehmet-erim Date: Tue, 7 Apr 2020 11:00:29 +0300 Subject: [PATCH 081/334] docs: add content strategy documentation --- docs/en/UI/Angular/Content-Strategy.md | 95 ++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 docs/en/UI/Angular/Content-Strategy.md diff --git a/docs/en/UI/Angular/Content-Strategy.md b/docs/en/UI/Angular/Content-Strategy.md new file mode 100644 index 0000000000..e3d3ca9849 --- /dev/null +++ b/docs/en/UI/Angular/Content-Strategy.md @@ -0,0 +1,95 @@ +# ContentStrategy + +`ContentStrategy` is an abstract class exposed by @abp/ng.core package. It helps you create inline scripts or styles. + +## API + + +### constructor + +```js +constructor( + public content: string, + protected domStrategy?: DomStrategy, + protected contentSecurityStrategy?: ContentSecurityStrategy +) +``` + +- `content` is set to `` element will place at the **end** of ``. + +Please refer to [ContentStrategy](./Content-Strategy.md) to see all available content strategies and how you can build your own content strategy. + + +### How to Insert Styles + +If you pass a `StyleContentStrategy` instance as the first parameter of `insertContent` method, the `DomInsertionService` will create a `` element will place at the **end** of ``. + +Please refer to [ContentStrategy](./Content-Strategy.md) to see all available content strategies and how you can build your own content strategy. + + +## API + + +### inserted + +```js +inserted: Set +``` + +All previously inserted contents are stored via this property as hashes. It is a simple [JavaScript Set](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set). + + + +### insertContent + +```js +insertContent(strategy: ContentStrategy): void +``` + +`strategy` parameter is the primary focus here and is explained above. + + +## What's Next? + +- [TrackByService](./Track-By-Service.md) diff --git a/docs/en/UI/Angular/Lazy-Load-Service.md b/docs/en/UI/Angular/Lazy-Load-Service.md index 43ee7bc6b8..a03381869e 100644 --- a/docs/en/UI/Angular/Lazy-Load-Service.md +++ b/docs/en/UI/Angular/Lazy-Load-Service.md @@ -210,4 +210,4 @@ load(strategy: LoadingStrategy, retryTimes?: number, retryDelay?: number): Obser ## What's Next? -- [TrackByService](./Track-By-Service.md) +- [DomInsertionService](./Dom-Insertion-Service.md) diff --git a/docs/en/docs-nav.json b/docs/en/docs-nav.json index 8034913c4c..471e215e3a 100644 --- a/docs/en/docs-nav.json +++ b/docs/en/docs-nav.json @@ -349,6 +349,10 @@ "text": "Lazy Loading Scripts & Styles", "path": "UI/Angular/Lazy-Load-Service.md" }, + { + "text": "DomInsertionService", + "path": "UI/Angular/Dom-Insertion-Service.md" + }, { "text": "TrackByService", "path": "UI/Angular/Track-By-Service.md" From 97ee0edf4fa8377e0ec2eb49bc04acea2a243862 Mon Sep 17 00:00:00 2001 From: mehmet-erim Date: Tue, 7 Apr 2020 12:08:42 +0300 Subject: [PATCH 084/334] docs: refactor strategy docs --- .../UI/Angular/Content-Security-Strategy.md | 4 +-- docs/en/UI/Angular/Content-Strategy.md | 10 +++--- docs/en/UI/Angular/Cross-Origin-Strategy.md | 4 +-- docs/en/UI/Angular/Dom-Strategy.md | 32 ++++++++++++++++--- docs/en/UI/Angular/Loading-Strategy.md | 10 +++--- 5 files changed, 41 insertions(+), 19 deletions(-) diff --git a/docs/en/UI/Angular/Content-Security-Strategy.md b/docs/en/UI/Angular/Content-Security-Strategy.md index c45cf23c58..f32317c9ca 100644 --- a/docs/en/UI/Angular/Content-Security-Strategy.md +++ b/docs/en/UI/Angular/Content-Security-Strategy.md @@ -50,7 +50,7 @@ Predefined content security strategies are accessible via `CONTENT_SECURITY_STRA ### Loose ```js -Loose(nonce: string) +CONTENT_SECURITY_STRATEGY.Loose(nonce: string) ``` `nonce` will be set. @@ -59,7 +59,7 @@ Loose(nonce: string) ### None ```js -None() +CONTENT_SECURITY_STRATEGY.None() ``` Nothing will be done. diff --git a/docs/en/UI/Angular/Content-Strategy.md b/docs/en/UI/Angular/Content-Strategy.md index e3d3ca9849..8544042c32 100644 --- a/docs/en/UI/Angular/Content-Strategy.md +++ b/docs/en/UI/Angular/Content-Strategy.md @@ -57,7 +57,7 @@ Predefined content strategies are accessible via `CONTENT_STRATEGY` constant. ### AppendScriptToBody ```js -AppendScriptToBody(content: string) +CONTENT_STRATEGY.AppendScriptToBody(content: string) ``` Creates a `` element will place at the **end Please refer to [ContentStrategy](./Content-Strategy.md) to see all available content strategies and how you can build your own content strategy. - ### How to Insert Styles If you pass a `StyleContentStrategy` instance as the first parameter of `insertContent` method, the `DomInsertionService` will create a `` element will place at t Please refer to [ContentStrategy](./Content-Strategy.md) to see all available content strategies and how you can build your own content strategy. +### How to Project Components & Templates + +If you pass a `ProjectionStrategy` as the first parameter of `projectContent` method, the `DomInsertionService` will resolve the projected component or template and place it at the designated target, such as containers or document body. If provided, it will also pass the component or the template a context. + +```js +const componentRef = this.domInsertionService.projectContent( + PROJECTION_STRATEGY.AppendComponentToBody(SomeOverlayComponent) +); +``` + +In the example above, `SomeOverlayComponent` component will placed at the **end** of `` and a `ComponentRef` will be returned. + +> You should keep the returned `ComponentRef` instance, as it is a reference to the projected component and you will need that reference to destroy the projected view and the component instance. + +```js +const componentRef = this.domInsertionService.projectContent( + PROJECTION_STRATEGY.ProjectComponentToContainer( + SomeOverlayComponent, + viewContainerRefOfTarget, + { someProp: "SOME_VALUE" } + ) +); +``` + +In this example, the `viewContainerRefOfTarget`, which is a `ViewContainerRef` instance, will be cleared and `SomeOverlayComponent` component will placed inside it. Moreover, the given context will be applied, so `someProp` of the component will be set to `SOME_VALUE`. + +Please refer to [ProjectionStrategy](./Projection-Strategy.md) to see all available projection strategies and how you can build your own projection strategy. ## API ### insertContent ```js -insertContent(strategy: ContentStrategy): void +injectContent(injector: Injector): ComponentRef | EmbeddedViewRef ``` -`strategy` parameter is the primary focus here and is explained above. +`injector` parameter is the `Injector` instance you can pass to the projected content. It is not used in `TemplateProjectionStrategy`. ## What's Next? From 31624376c49de3b5f45f564c6d5a79ff629a9072 Mon Sep 17 00:00:00 2001 From: mehmet-erim Date: Fri, 10 Apr 2020 09:20:20 +0300 Subject: [PATCH 119/334] chore: replace tilde with caret for abp versions --- npm/ng-packs/packages/account/package.json | 4 ++-- npm/ng-packs/packages/identity/package.json | 6 +++--- npm/ng-packs/packages/permission-management/package.json | 2 +- npm/ng-packs/packages/setting-management/package.json | 4 ++-- npm/ng-packs/packages/tenant-management/package.json | 6 +++--- npm/ng-packs/packages/theme-basic/package.json | 2 +- npm/ng-packs/packages/theme-shared/package.json | 2 +- 7 files changed, 13 insertions(+), 13 deletions(-) diff --git a/npm/ng-packs/packages/account/package.json b/npm/ng-packs/packages/account/package.json index 08c92c1e21..14c3553212 100644 --- a/npm/ng-packs/packages/account/package.json +++ b/npm/ng-packs/packages/account/package.json @@ -7,8 +7,8 @@ "url": "https://github.com/abpframework/abp.git" }, "dependencies": { - "@abp/ng.account.config": "^2.5.0", - "@abp/ng.theme.shared": "^2.5.0" + "@abp/ng.account.config": "~2.5.0", + "@abp/ng.theme.shared": "~2.5.0" }, "publishConfig": { "access": "public" diff --git a/npm/ng-packs/packages/identity/package.json b/npm/ng-packs/packages/identity/package.json index 023f373ab7..5e9930608e 100644 --- a/npm/ng-packs/packages/identity/package.json +++ b/npm/ng-packs/packages/identity/package.json @@ -7,9 +7,9 @@ "url": "https://github.com/abpframework/abp.git" }, "dependencies": { - "@abp/ng.identity.config": "^2.5.0", - "@abp/ng.permission-management": "^2.5.0", - "@abp/ng.theme.shared": "^2.5.0" + "@abp/ng.identity.config": "~2.5.0", + "@abp/ng.permission-management": "~2.5.0", + "@abp/ng.theme.shared": "~2.5.0" }, "publishConfig": { "access": "public" diff --git a/npm/ng-packs/packages/permission-management/package.json b/npm/ng-packs/packages/permission-management/package.json index 0b538d00fa..520ec54765 100644 --- a/npm/ng-packs/packages/permission-management/package.json +++ b/npm/ng-packs/packages/permission-management/package.json @@ -7,7 +7,7 @@ "url": "https://github.com/abpframework/abp.git" }, "dependencies": { - "@abp/ng.theme.shared": "^2.5.0" + "@abp/ng.theme.shared": "~2.5.0" }, "publishConfig": { "access": "public" diff --git a/npm/ng-packs/packages/setting-management/package.json b/npm/ng-packs/packages/setting-management/package.json index 5788bdc72b..716df5385e 100644 --- a/npm/ng-packs/packages/setting-management/package.json +++ b/npm/ng-packs/packages/setting-management/package.json @@ -7,8 +7,8 @@ "url": "https://github.com/abpframework/abp.git" }, "dependencies": { - "@abp/ng.setting-management.config": "^2.5.0", - "@abp/ng.theme.shared": "^2.5.0" + "@abp/ng.setting-management.config": "~2.5.0", + "@abp/ng.theme.shared": "~2.5.0" }, "publishConfig": { "access": "public" diff --git a/npm/ng-packs/packages/tenant-management/package.json b/npm/ng-packs/packages/tenant-management/package.json index 8c07199b6c..49baed552f 100644 --- a/npm/ng-packs/packages/tenant-management/package.json +++ b/npm/ng-packs/packages/tenant-management/package.json @@ -7,9 +7,9 @@ "url": "https://github.com/abpframework/abp.git" }, "dependencies": { - "@abp/ng.feature-management": "^2.5.0", - "@abp/ng.tenant-management.config": "^2.5.0", - "@abp/ng.theme.shared": "^2.5.0" + "@abp/ng.feature-management": "~2.5.0", + "@abp/ng.tenant-management.config": "~2.5.0", + "@abp/ng.theme.shared": "~2.5.0" }, "publishConfig": { "access": "public" diff --git a/npm/ng-packs/packages/theme-basic/package.json b/npm/ng-packs/packages/theme-basic/package.json index 3c07884583..bfbe9e170b 100644 --- a/npm/ng-packs/packages/theme-basic/package.json +++ b/npm/ng-packs/packages/theme-basic/package.json @@ -7,7 +7,7 @@ "url": "https://github.com/abpframework/abp.git" }, "dependencies": { - "@abp/ng.theme.shared": "^2.5.0" + "@abp/ng.theme.shared": "~2.5.0" }, "publishConfig": { "access": "public" diff --git a/npm/ng-packs/packages/theme-shared/package.json b/npm/ng-packs/packages/theme-shared/package.json index 9aece312d3..ce8ee044b9 100644 --- a/npm/ng-packs/packages/theme-shared/package.json +++ b/npm/ng-packs/packages/theme-shared/package.json @@ -7,7 +7,7 @@ "url": "https://github.com/abpframework/abp.git" }, "dependencies": { - "@abp/ng.core": "^2.5.0", + "@abp/ng.core": "~2.5.0", "@fortawesome/fontawesome-free": "^5.12.1", "@ng-bootstrap/ng-bootstrap": "^5.3.0", "@ngx-validate/core": "^0.0.7", From 29c567bedeb100283ca65504dbc0d2553937c75f Mon Sep 17 00:00:00 2001 From: mehmet-erim Date: Fri, 10 Apr 2020 09:21:37 +0300 Subject: [PATCH 120/334] feat: add components enum to all modules #3425 --- npm/ng-packs/.vscode/settings.json | 4 +++- .../packages/account/src/lib/account-routing.module.ts | 7 ++++--- .../auth-wrapper/auth-wrapper.component.html | 4 +--- .../components/auth-wrapper/auth-wrapper.component.ts | 3 +++ .../src/lib/components/login/login.component.html | 2 +- .../src/lib/components/login/login.component.ts | 3 +++ .../manage-profile/manage-profile.component.html | 4 ++-- .../manage-profile/manage-profile.component.ts | 5 +++++ .../lib/components/register/register.component.html | 2 +- .../src/lib/components/register/register.component.ts | 3 +++ .../packages/account/src/lib/enums/components.ts | 9 +++++++++ npm/ng-packs/packages/account/src/public-api.ts | 1 + npm/ng-packs/packages/feature-management/package.json | 2 +- .../feature-management/src/lib/enums/components.ts | 3 +++ .../packages/feature-management/src/public-api.ts | 1 + .../src/lib/components/roles/roles.component.html | 2 +- .../src/lib/components/roles/roles.component.ts | 3 +++ .../src/lib/components/users/users.component.html | 2 +- .../src/lib/components/users/users.component.ts | 3 +++ .../packages/identity/src/lib/enums/components.ts | 4 ++++ .../identity/src/lib/identity-routing.module.ts | 5 +++-- npm/ng-packs/packages/identity/src/public-api.ts | 1 + .../permission-management/src/lib/enums/components.ts | 3 +++ .../packages/permission-management/src/public-api.ts | 1 + .../setting-management/src/lib/enums/components.ts | 3 +++ .../src/lib/setting-management-routing.module.ts | 3 ++- .../packages/setting-management/src/public-api.ts | 1 + .../src/lib/components/tenants/tenants.component.html | 10 +++++++--- .../src/lib/components/tenants/tenants.component.ts | 3 +++ .../tenant-management/src/lib/enums/components.ts | 3 +++ .../src/lib/tenant-management-routing.module.ts | 3 ++- .../packages/tenant-management/src/public-api.ts | 1 + .../packages/theme-basic/src/lib/enums/components.ts | 5 +++++ .../theme-basic/src/lib/services/initial.service.ts | 7 ++++--- npm/ng-packs/packages/theme-basic/src/public-api.ts | 1 + 35 files changed, 93 insertions(+), 24 deletions(-) create mode 100644 npm/ng-packs/packages/account/src/lib/enums/components.ts create mode 100644 npm/ng-packs/packages/feature-management/src/lib/enums/components.ts create mode 100644 npm/ng-packs/packages/identity/src/lib/enums/components.ts create mode 100644 npm/ng-packs/packages/permission-management/src/lib/enums/components.ts create mode 100644 npm/ng-packs/packages/setting-management/src/lib/enums/components.ts create mode 100644 npm/ng-packs/packages/tenant-management/src/lib/enums/components.ts create mode 100644 npm/ng-packs/packages/theme-basic/src/lib/enums/components.ts diff --git a/npm/ng-packs/.vscode/settings.json b/npm/ng-packs/.vscode/settings.json index 9c2678df08..a04bf7ca0c 100644 --- a/npm/ng-packs/.vscode/settings.json +++ b/npm/ng-packs/.vscode/settings.json @@ -18,7 +18,9 @@ "titleBar.inactiveForeground": "#e7e7e799", "statusBar.background": "#1d70a2", "statusBarItem.hoverBackground": "#258ecd", - "statusBar.foreground": "#e7e7e7" + "statusBar.foreground": "#e7e7e7", + "statusBar.border": "#1d70a2", + "titleBar.border": "#1d70a2" }, "peacock.color": "#1D70A2" } diff --git a/npm/ng-packs/packages/account/src/lib/account-routing.module.ts b/npm/ng-packs/packages/account/src/lib/account-routing.module.ts index db4147f2a0..2225e7c592 100644 --- a/npm/ng-packs/packages/account/src/lib/account-routing.module.ts +++ b/npm/ng-packs/packages/account/src/lib/account-routing.module.ts @@ -9,6 +9,7 @@ import { RouterModule, Routes } from '@angular/router'; import { LoginComponent } from './components/login/login.component'; import { ManageProfileComponent } from './components/manage-profile/manage-profile.component'; import { RegisterComponent } from './components/register/register.component'; +import { eAccountComponents } from './enums/components'; const routes: Routes = [ { path: '', pathMatch: 'full', redirectTo: 'login' }, @@ -21,7 +22,7 @@ const routes: Routes = [ component: ReplaceableRouteContainerComponent, data: { replaceableComponent: { - key: 'Account.LoginComponent', + key: eAccountComponents.Login, defaultComponent: LoginComponent, } as ReplaceableComponents.RouteData, }, @@ -31,7 +32,7 @@ const routes: Routes = [ component: ReplaceableRouteContainerComponent, data: { replaceableComponent: { - key: 'Account.RegisterComponent', + key: eAccountComponents.Register, defaultComponent: RegisterComponent, } as ReplaceableComponents.RouteData, }, @@ -42,7 +43,7 @@ const routes: Routes = [ canActivate: [AuthGuard], data: { replaceableComponent: { - key: 'Account.ManageProfileComponent', + key: eAccountComponents.ManageProfile, defaultComponent: ManageProfileComponent, } as ReplaceableComponents.RouteData, }, diff --git a/npm/ng-packs/packages/account/src/lib/components/auth-wrapper/auth-wrapper.component.html b/npm/ng-packs/packages/account/src/lib/components/auth-wrapper/auth-wrapper.component.html index 6e732540d4..3377b74a88 100644 --- a/npm/ng-packs/packages/account/src/lib/components/auth-wrapper/auth-wrapper.component.html +++ b/npm/ng-packs/packages/account/src/lib/components/auth-wrapper/auth-wrapper.component.html @@ -1,9 +1,7 @@
- +
@@ -44,7 +44,7 @@
diff --git a/npm/ng-packs/packages/account/src/lib/components/manage-profile/manage-profile.component.ts b/npm/ng-packs/packages/account/src/lib/components/manage-profile/manage-profile.component.ts index d19a1dcd6a..f9ee2b8ff7 100644 --- a/npm/ng-packs/packages/account/src/lib/components/manage-profile/manage-profile.component.ts +++ b/npm/ng-packs/packages/account/src/lib/components/manage-profile/manage-profile.component.ts @@ -1,6 +1,7 @@ import { fadeIn } from '@abp/ng.theme.shared'; import { transition, trigger, useAnimation } from '@angular/animations'; import { Component } from '@angular/core'; +import { eAccountComponents } from '../../enums/components'; @Component({ selector: 'abp-manage-profile', @@ -9,4 +10,8 @@ import { Component } from '@angular/core'; }) export class ManageProfileComponent { selectedTab = 0; + + changePasswordKey = eAccountComponents.ChangePassword; + + personalSettingsKey = eAccountComponents.PersonalSettings; } diff --git a/npm/ng-packs/packages/account/src/lib/components/register/register.component.html b/npm/ng-packs/packages/account/src/lib/components/register/register.component.html index f803d473cd..58fafdf541 100644 --- a/npm/ng-packs/packages/account/src/lib/components/register/register.component.html +++ b/npm/ng-packs/packages/account/src/lib/components/register/register.component.html @@ -1,6 +1,6 @@ ; diff --git a/npm/ng-packs/packages/identity/src/lib/components/users/users.component.html b/npm/ng-packs/packages/identity/src/lib/components/users/users.component.html index 38b22789e9..e00dbfe866 100644 --- a/npm/ng-packs/packages/identity/src/lib/components/users/users.component.html +++ b/npm/ng-packs/packages/identity/src/lib/components/users/users.component.html @@ -262,7 +262,7 @@ visible: { value: visiblePermissions, twoWay: true } }, outputs: { visibleChange: onVisiblePermissionChange }, - componentKey: 'PermissionManagement.PermissionManagementComponent' + componentKey: permissionManagementKey }; let init = initTemplate " diff --git a/npm/ng-packs/packages/identity/src/lib/components/users/users.component.ts b/npm/ng-packs/packages/identity/src/lib/components/users/users.component.ts index 1e943a6be6..e208f9ffec 100644 --- a/npm/ng-packs/packages/identity/src/lib/components/users/users.component.ts +++ b/npm/ng-packs/packages/identity/src/lib/components/users/users.component.ts @@ -24,6 +24,7 @@ import { import { Identity } from '../../models/identity'; import { IdentityService } from '../../services/identity.service'; import { IdentityState } from '../../states/identity.state'; +import { ePermissionManagementComponents } from '@abp/ng.permission-management'; @Component({ selector: 'abp-users', templateUrl: './users.component.html', @@ -62,6 +63,8 @@ export class UsersComponent implements OnInit { sortKey = ''; + permissionManagementKey = ePermissionManagementComponents.PermissionManagement; + trackByFn: TrackByFunction = (index, item) => Object.keys(item)[0] || index; onVisiblePermissionChange = event => { diff --git a/npm/ng-packs/packages/identity/src/lib/enums/components.ts b/npm/ng-packs/packages/identity/src/lib/enums/components.ts new file mode 100644 index 0000000000..abadd38955 --- /dev/null +++ b/npm/ng-packs/packages/identity/src/lib/enums/components.ts @@ -0,0 +1,4 @@ +export const enum eIdentityComponents { + Roles = 'Identity.RolesComponent', + Users = 'Identity.UsersComponent', +} diff --git a/npm/ng-packs/packages/identity/src/lib/identity-routing.module.ts b/npm/ng-packs/packages/identity/src/lib/identity-routing.module.ts index eff6a7ce98..f7d5463fcd 100644 --- a/npm/ng-packs/packages/identity/src/lib/identity-routing.module.ts +++ b/npm/ng-packs/packages/identity/src/lib/identity-routing.module.ts @@ -10,6 +10,7 @@ import { NgModule, Type } from '@angular/core'; import { RouterModule, Routes, Router, ActivatedRoute } from '@angular/router'; import { RolesComponent } from './components/roles/roles.component'; import { UsersComponent } from './components/users/users.component'; +import { eIdentityComponents } from './enums/components'; const routes: Routes = [ { path: '', redirectTo: 'roles', pathMatch: 'full' }, @@ -24,7 +25,7 @@ const routes: Routes = [ data: { requiredPolicy: 'AbpIdentity.Roles', replaceableComponent: { - key: 'Identity.RolesComponent', + key: eIdentityComponents.Roles, defaultComponent: RolesComponent, } as ReplaceableComponents.RouteData, }, @@ -35,7 +36,7 @@ const routes: Routes = [ data: { requiredPolicy: 'AbpIdentity.Users', replaceableComponent: { - key: 'Identity.UsersComponent', + key: eIdentityComponents.Users, defaultComponent: UsersComponent, } as ReplaceableComponents.RouteData, }, diff --git a/npm/ng-packs/packages/identity/src/public-api.ts b/npm/ng-packs/packages/identity/src/public-api.ts index b401fed1c6..1a2b217931 100644 --- a/npm/ng-packs/packages/identity/src/public-api.ts +++ b/npm/ng-packs/packages/identity/src/public-api.ts @@ -4,6 +4,7 @@ export * from './lib/identity.module'; export * from './lib/actions/identity.actions'; +export * from './lib/enums/components'; export * from './lib/components'; export * from './lib/models/identity'; export * from './lib/services'; diff --git a/npm/ng-packs/packages/permission-management/src/lib/enums/components.ts b/npm/ng-packs/packages/permission-management/src/lib/enums/components.ts new file mode 100644 index 0000000000..175d39c999 --- /dev/null +++ b/npm/ng-packs/packages/permission-management/src/lib/enums/components.ts @@ -0,0 +1,3 @@ +export const enum ePermissionManagementComponents { + PermissionManagement = 'PermissionManagement.PermissionManagementComponent', +} diff --git a/npm/ng-packs/packages/permission-management/src/public-api.ts b/npm/ng-packs/packages/permission-management/src/public-api.ts index 3182363f25..c9a8445ebd 100644 --- a/npm/ng-packs/packages/permission-management/src/public-api.ts +++ b/npm/ng-packs/packages/permission-management/src/public-api.ts @@ -5,6 +5,7 @@ export * from './lib/permission-management.module'; export * from './lib/actions'; export * from './lib/components'; +export * from './lib/enums/components'; export * from './lib/models'; export * from './lib/services'; export * from './lib/states'; diff --git a/npm/ng-packs/packages/setting-management/src/lib/enums/components.ts b/npm/ng-packs/packages/setting-management/src/lib/enums/components.ts new file mode 100644 index 0000000000..7dafe76b7d --- /dev/null +++ b/npm/ng-packs/packages/setting-management/src/lib/enums/components.ts @@ -0,0 +1,3 @@ +export const enum eSettingManagementComponents { + SettingManagement = 'SettingManagement.SettingManagementComponent', +} diff --git a/npm/ng-packs/packages/setting-management/src/lib/setting-management-routing.module.ts b/npm/ng-packs/packages/setting-management/src/lib/setting-management-routing.module.ts index d9a50073e1..f394abc962 100644 --- a/npm/ng-packs/packages/setting-management/src/lib/setting-management-routing.module.ts +++ b/npm/ng-packs/packages/setting-management/src/lib/setting-management-routing.module.ts @@ -6,6 +6,7 @@ import { import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; import { SettingManagementComponent } from './components/setting-management.component'; +import { eSettingManagementComponents } from './enums/components'; const routes: Routes = [ { @@ -18,7 +19,7 @@ const routes: Routes = [ data: { requiredPolicy: 'AbpAccount.SettingManagement', replaceableComponent: { - key: 'SettingManagement.SettingManagementComponent', + key: eSettingManagementComponents.SettingManagement, defaultComponent: SettingManagementComponent, } as ReplaceableComponents.RouteData, }, diff --git a/npm/ng-packs/packages/setting-management/src/public-api.ts b/npm/ng-packs/packages/setting-management/src/public-api.ts index 8027d769f9..ac030c3ccf 100644 --- a/npm/ng-packs/packages/setting-management/src/public-api.ts +++ b/npm/ng-packs/packages/setting-management/src/public-api.ts @@ -1,2 +1,3 @@ export * from './lib/setting-management.module'; export * from './lib/components/setting-management.component'; +export * from './lib/enums/components'; diff --git a/npm/ng-packs/packages/tenant-management/src/lib/components/tenants/tenants.component.html b/npm/ng-packs/packages/tenant-management/src/lib/components/tenants/tenants.component.html index 2b0276ede8..10761a3618 100644 --- a/npm/ng-packs/packages/tenant-management/src/lib/components/tenants/tenants.component.html +++ b/npm/ng-packs/packages/tenant-management/src/lib/components/tenants/tenants.component.html @@ -141,7 +141,9 @@
- +
- + , }, diff --git a/npm/ng-packs/packages/tenant-management/src/public-api.ts b/npm/ng-packs/packages/tenant-management/src/public-api.ts index 20cecd353f..003074b2c4 100644 --- a/npm/ng-packs/packages/tenant-management/src/public-api.ts +++ b/npm/ng-packs/packages/tenant-management/src/public-api.ts @@ -1,6 +1,7 @@ export * from './lib/tenant-management.module'; export * from './lib/actions'; export * from './lib/components'; +export * from './lib/enums/components'; export * from './lib/models'; export * from './lib/services'; export * from './lib/states'; diff --git a/npm/ng-packs/packages/theme-basic/src/lib/enums/components.ts b/npm/ng-packs/packages/theme-basic/src/lib/enums/components.ts new file mode 100644 index 0000000000..e773e17464 --- /dev/null +++ b/npm/ng-packs/packages/theme-basic/src/lib/enums/components.ts @@ -0,0 +1,5 @@ +export const enum eThemeBasicComponents { + ApplicationLayout = 'Theme.ApplicationLayoutComponent', + AccountLayout = 'Theme.AccountLayoutComponent', + EmptyLayout = 'Theme.EmptyLayoutComponent', +} diff --git a/npm/ng-packs/packages/theme-basic/src/lib/services/initial.service.ts b/npm/ng-packs/packages/theme-basic/src/lib/services/initial.service.ts index 2510b77a8d..c5bc93cbf0 100644 --- a/npm/ng-packs/packages/theme-basic/src/lib/services/initial.service.ts +++ b/npm/ng-packs/packages/theme-basic/src/lib/services/initial.service.ts @@ -5,6 +5,7 @@ import styles from '../constants/styles'; import { ApplicationLayoutComponent } from '../components/application-layout/application-layout.component'; import { AccountLayoutComponent } from '../components/account-layout/account-layout.component'; import { EmptyLayoutComponent } from '../components/empty-layout/empty-layout.component'; +import { eThemeBasicComponents } from '../enums/components'; @Injectable({ providedIn: 'root' }) export class InitialService { @@ -13,15 +14,15 @@ export class InitialService { this.store.dispatch([ new AddReplaceableComponent({ - key: 'Theme.ApplicationLayoutComponent', + key: eThemeBasicComponents.ApplicationLayout, component: ApplicationLayoutComponent, }), new AddReplaceableComponent({ - key: 'Theme.AccountLayoutComponent', + key: eThemeBasicComponents.AccountLayout, component: AccountLayoutComponent, }), new AddReplaceableComponent({ - key: 'Theme.EmptyLayoutComponent', + key: eThemeBasicComponents.EmptyLayout, component: EmptyLayoutComponent, }), ]); diff --git a/npm/ng-packs/packages/theme-basic/src/public-api.ts b/npm/ng-packs/packages/theme-basic/src/public-api.ts index b1316143c0..ee01995829 100644 --- a/npm/ng-packs/packages/theme-basic/src/public-api.ts +++ b/npm/ng-packs/packages/theme-basic/src/public-api.ts @@ -5,5 +5,6 @@ export * from './lib/theme-basic.module'; export * from './lib/actions'; export * from './lib/components'; +export * from './lib/enums/components'; export * from './lib/models'; export * from './lib/states'; From da2a45b1125c8c69c100a6a3f0e8cb800654ebd1 Mon Sep 17 00:00:00 2001 From: mehmet-erim Date: Fri, 10 Apr 2020 09:48:37 +0300 Subject: [PATCH 121/334] docs: update component replacement doc resolves #3080 --- docs/en/UI/Angular/Component-Replacement.md | 30 ++++++--------------- 1 file changed, 8 insertions(+), 22 deletions(-) diff --git a/docs/en/UI/Angular/Component-Replacement.md b/docs/en/UI/Angular/Component-Replacement.md index d718b46117..d1f88c0400 100644 --- a/docs/en/UI/Angular/Component-Replacement.md +++ b/docs/en/UI/Angular/Component-Replacement.md @@ -11,15 +11,18 @@ Create a new component that you want to use instead of an ABP component. Add tha Then, open the `app.component.ts` and dispatch the `AddReplaceableComponent` action to replace your component with an ABP component as shown below: ```js -import { ..., AddReplaceableComponent } from '@abp/ng.core'; +import { ..., AddReplaceableComponent } from '@abp/ng.core'; // imported AddReplaceableComponent action +import { eIdentityComponents } from '@abp/ng.identity'; // imported eIdentityComponents enum +import { Store } from '@ngxs/store'; // imported Store +//... export class AppComponent { - constructor(..., private store: Store) {} + constructor(..., private store: Store) {} // injected Store ngOnInit() { this.store.dispatch( new AddReplaceableComponent({ component: YourNewRoleComponent, - key: 'Identity.RolesComponent', + key: eIdentityComponents.Roles, }), ); //... @@ -56,6 +59,7 @@ Open the `app.component.ts` and add the below content: ```js import { ..., AddReplaceableComponent } from '@abp/ng.core'; // imported AddReplaceableComponent +import { eThemeBasicComponents } from '@abp/ng.theme.basic'; // imported eThemeBasicComponents enum for component keys import { MyApplicationLayoutComponent } from './shared/my-application-layout/my-application-layout.component'; // imported MyApplicationLayoutComponent import { Store } from '@ngxs/store'; // imported Store //... @@ -67,7 +71,7 @@ export class AppComponent { this.store.dispatch( new AddReplaceableComponent({ component: MyApplicationLayoutComponent, - key: 'Theme.ApplicationLayoutComponent', + key: eThemeBasicComponents.AccountLayout, }), ); @@ -76,24 +80,6 @@ export class AppComponent { } ``` -### Available Replaceable Components - -| Component key | Description | -| -------------------------------------------------- | --------------------------------------------- | -| Account.LoginComponent | Login page | -| Account.RegisterComponent | Register page | -| Account.ManageProfileComponent | Manage Profile page | -| Account.AuthWrapperComponent | This component wraps register and login pages | -| Account.ChangePasswordComponent | Change password form | -| Account.PersonalSettingsComponent | Personal settings form | -| Account.TenantBoxComponentInputs | Tenant changing box | -| FeatureManagement.FeatureManagementComponent | Features modal | -| Identity.UsersComponent | Users page | -| Identity.RolesComponent | Roles page | -| PermissionManagement.PermissionManagementComponent | Permissions modal | -| SettingManagement.SettingManagementComponent | Setting Management page | -| TenantManagement.TenantsComponent | Tenants page | - ## What's Next? - [Custom Setting Page](./Custom-Setting-Page.md) From bc4c454fe2a863cb2e7d3a4e251040274925e4d4 Mon Sep 17 00:00:00 2001 From: mehmet-erim Date: Fri, 10 Apr 2020 09:53:06 +0300 Subject: [PATCH 122/334] chore: update ng-packs abp versions --- npm/ng-packs/package.json | 26 ++++---- npm/ng-packs/yarn.lock | 132 +++++++++++++++++++------------------- 2 files changed, 79 insertions(+), 79 deletions(-) diff --git a/npm/ng-packs/package.json b/npm/ng-packs/package.json index a2b9011647..4f65497d69 100644 --- a/npm/ng-packs/package.json +++ b/npm/ng-packs/package.json @@ -22,19 +22,19 @@ "generate:changelog": "conventional-changelog -p angular -i CHANGELOG.md -s" }, "devDependencies": { - "@abp/ng.account": "~2.4.1", - "@abp/ng.account.config": "~2.4.1", - "@abp/ng.core": "^2.4.1", - "@abp/ng.feature-management": "^2.4.1", - "@abp/ng.identity": "~2.4.1", - "@abp/ng.identity.config": "~2.4.1", - "@abp/ng.permission-management": "^2.4.1", - "@abp/ng.setting-management": "~2.4.1", - "@abp/ng.setting-management.config": "~2.4.1", - "@abp/ng.tenant-management": "~2.4.1", - "@abp/ng.tenant-management.config": "~2.4.1", - "@abp/ng.theme.basic": "~2.4.1", - "@abp/ng.theme.shared": "^2.4.1", + "@abp/ng.account": "~2.5.0", + "@abp/ng.account.config": "~2.5.0", + "@abp/ng.core": "~2.5.0", + "@abp/ng.feature-management": "~2.5.0", + "@abp/ng.identity": "~2.5.0", + "@abp/ng.identity.config": "~2.5.0", + "@abp/ng.permission-management": "~2.5.0", + "@abp/ng.setting-management": "~2.5.0", + "@abp/ng.setting-management.config": "~2.5.0", + "@abp/ng.tenant-management": "~2.5.0", + "@abp/ng.tenant-management.config": "~2.5.0", + "@abp/ng.theme.basic": "~2.5.0", + "@abp/ng.theme.shared": "~2.5.0", "@abp/utils": "^2.4.0", "@angular-builders/jest": "^8.2.0", "@angular-devkit/build-angular": "~0.803.21", diff --git a/npm/ng-packs/yarn.lock b/npm/ng-packs/yarn.lock index 1d93a6ef79..5e156ae867 100644 --- a/npm/ng-packs/yarn.lock +++ b/npm/ng-packs/yarn.lock @@ -2,26 +2,26 @@ # yarn lockfile v1 -"@abp/ng.account.config@^2.4.1", "@abp/ng.account.config@~2.4.1": - version "2.4.1" - resolved "https://registry.yarnpkg.com/@abp/ng.account.config/-/ng.account.config-2.4.1.tgz#871f3947d7751203ba8fd00902b5e87c2894cca1" - integrity sha512-6ikmQi+hmZi59xtEq54MZftH0i9qzxYWex4lk33woBiNXHYBKA/AzrXkksgjnQgmN5kydxGsHcq2vlAgb+WgSA== +"@abp/ng.account.config@^2.5.0", "@abp/ng.account.config@~2.5.0": + version "2.5.0" + resolved "https://registry.yarnpkg.com/@abp/ng.account.config/-/ng.account.config-2.5.0.tgz#08122916985765f62b0cd9ef2d9a8609a485131b" + integrity sha512-Ld7nsGOw3TafWaJ64umHB3NwI4tgeLKkhU6IO7/Dbx0UZvcRepND07pLPAbpgxPxSffNDmREHnA+lrtP1i96vA== dependencies: tslib "^1.9.0" -"@abp/ng.account@~2.4.1": - version "2.4.1" - resolved "https://registry.yarnpkg.com/@abp/ng.account/-/ng.account-2.4.1.tgz#09c51101b2511f0352ffd3ef56b5f2e74d81cead" - integrity sha512-mFhFPKPsmHNYKBXWxK2ht9TkXccj5xkPfn3PGSkX0QiqJZ+SrJBb3bYa2VOsQ9BstWB1/FEX3ke07MB5h4uRTQ== +"@abp/ng.account@~2.5.0": + version "2.5.0" + resolved "https://registry.yarnpkg.com/@abp/ng.account/-/ng.account-2.5.0.tgz#b5271da490136f7e23cbae21588e9fd6f8f398c7" + integrity sha512-C6RD9L0+gkyjuCSUGP9C55h+oMIoPNkSe3fF4RWkLaqb1hLriIEqyeTODHnhdV4TfEVkVCmhS88XhoNGwmFz/g== dependencies: - "@abp/ng.account.config" "^2.4.1" - "@abp/ng.theme.shared" "^2.4.1" + "@abp/ng.account.config" "^2.5.0" + "@abp/ng.theme.shared" "^2.5.0" tslib "^1.9.0" -"@abp/ng.core@^2.4.1": - version "2.4.1" - resolved "https://registry.yarnpkg.com/@abp/ng.core/-/ng.core-2.4.1.tgz#4a568ef1f0d9e33de555a8942a0ef421e754d55f" - integrity sha512-aML9iyneu8UDaKP1x4dBzr20EVXhaVO75g1A235OEqT+qYJ7Z1qXgp01u8DgeNM+jxNWc2UVYgtPf5SbMJsR4Q== +"@abp/ng.core@^2.5.0", "@abp/ng.core@~2.5.0": + version "2.5.0" + resolved "https://registry.yarnpkg.com/@abp/ng.core/-/ng.core-2.5.0.tgz#e7168615b4078e3fa494c4efcc69842acbd2c627" + integrity sha512-opYkOFCKeU17YvNJhfcG1dOwZZ4F2QGspTNTagNZ9fepmeNl0yqFamFdRM6irfEEL3cOBQhUpI2NQZP+ugLOEg== dependencies: "@abp/utils" "^2.4.0" "@angular/localize" "~9.1.0" @@ -35,86 +35,86 @@ ts-toolbelt "^6.3.6" tslib "^1.9.0" -"@abp/ng.feature-management@^2.4.1": - version "2.4.1" - resolved "https://registry.yarnpkg.com/@abp/ng.feature-management/-/ng.feature-management-2.4.1.tgz#4e7f16fcf109d76bd3eadb296a54730da770c8c1" - integrity sha512-adkQKFr1XsYAq/qpXxtLo5ULBuTer12viPLgfldEmsnsGWi/0bCVr0U4Gw+4KdsE2SjmcMriaZnL2/yVJa5rjA== +"@abp/ng.feature-management@^2.5.0", "@abp/ng.feature-management@~2.5.0": + version "2.5.0" + resolved "https://registry.yarnpkg.com/@abp/ng.feature-management/-/ng.feature-management-2.5.0.tgz#3bc4501a2abbe6b6447e5b4a2b2d86fb07ce8a59" + integrity sha512-keZ3gCDMvU/e17tsBBrZpLmpIpDm/2TTSAmCoRRy3GH4BQICXr/XJmssStNx7V7sdo6vAPiW9pcM9zI/C8IrBw== dependencies: - "@abp/ng.theme.shared" "^2.4.1" + "@abp/ng.theme.shared" "^2.5.0" tslib "^1.9.0" -"@abp/ng.identity.config@^2.4.1", "@abp/ng.identity.config@~2.4.1": - version "2.4.1" - resolved "https://registry.yarnpkg.com/@abp/ng.identity.config/-/ng.identity.config-2.4.1.tgz#74a0c3b18ba1737b83144f1b03c97e75dc1afe0b" - integrity sha512-PeieQ/GeThgxx22n3rBnqPQuCylB5+0Vog53GAhFQFXXH5W0vMDbxTARYnQr74gnAf3UYS48XzEzyvAuIz1MGg== +"@abp/ng.identity.config@^2.5.0", "@abp/ng.identity.config@~2.5.0": + version "2.5.0" + resolved "https://registry.yarnpkg.com/@abp/ng.identity.config/-/ng.identity.config-2.5.0.tgz#d5daad786ae8c6d61e887f4ec52497635abfff94" + integrity sha512-nvVkRzT3gsLZTzjjMkR20FjmmnxDC7viUNRSjp4ufGqHfWbUaNS16chrWqvr+0f7JEzeULKWfXQEjWafqLWBbg== dependencies: tslib "^1.9.0" -"@abp/ng.identity@~2.4.1": - version "2.4.1" - resolved "https://registry.yarnpkg.com/@abp/ng.identity/-/ng.identity-2.4.1.tgz#ede6ebcc1d7d2f15ce9aeeb3ab8b25bb26def5cd" - integrity sha512-4T1BnvL13UggIj0SrV5AWN1VLMnej59jaLEyjAbu1Myry9xeiQ8Grh0GOBJ6euNOKiuYtqwQlFl06NlLdHqu2g== +"@abp/ng.identity@~2.5.0": + version "2.5.0" + resolved "https://registry.yarnpkg.com/@abp/ng.identity/-/ng.identity-2.5.0.tgz#b2e2dea559ce89dce52a82cf02d612864076ab2c" + integrity sha512-RIZnYRhNMbyjaX/Nb43fgG8/hBcvfBLpd3ZpP6arJDUY4YLvN3zvGJ9d52+3nGgj9WpXZTm+/X7c8Iuu5a2ocA== dependencies: - "@abp/ng.identity.config" "^2.4.1" - "@abp/ng.permission-management" "^2.4.1" - "@abp/ng.theme.shared" "^2.4.1" + "@abp/ng.identity.config" "^2.5.0" + "@abp/ng.permission-management" "^2.5.0" + "@abp/ng.theme.shared" "^2.5.0" tslib "^1.9.0" -"@abp/ng.permission-management@^2.4.1": - version "2.4.1" - resolved "https://registry.yarnpkg.com/@abp/ng.permission-management/-/ng.permission-management-2.4.1.tgz#e58d650fbcf8a161bbce01083b35891cba3e1aa4" - integrity sha512-gNfVmXAIPQP+L5Bq4bj/LAU+mKhJqAd9AQKxDLmqmoXpNjrjxA0Y51bU/XY/mjYx+tZC2i59L+eMIOZfVmn3Dw== +"@abp/ng.permission-management@^2.5.0", "@abp/ng.permission-management@~2.5.0": + version "2.5.0" + resolved "https://registry.yarnpkg.com/@abp/ng.permission-management/-/ng.permission-management-2.5.0.tgz#c769a97aee8517ec724dc5b7756e1dfc8fe7fcf1" + integrity sha512-grmJ46Qf26cwGfDt5acL6eXXWBDgjvL/04/ZLtxsP4Hf+tSlnL/1rWz5fxMF8548sQ6vZlVIdrSa4Tz/Dh0WLw== dependencies: - "@abp/ng.theme.shared" "^2.4.1" + "@abp/ng.theme.shared" "^2.5.0" tslib "^1.9.0" -"@abp/ng.setting-management.config@^2.4.1", "@abp/ng.setting-management.config@~2.4.1": - version "2.4.1" - resolved "https://registry.yarnpkg.com/@abp/ng.setting-management.config/-/ng.setting-management.config-2.4.1.tgz#4e643934647aaf5f5ea70045364e8856a1958bf5" - integrity sha512-z76nIPa9NCUqJwS2UYYCNrOsv9r+EfJ+e32iplrN5anqSfi0q2QAbK/Qjo7PIaB6x/JsEER/zQ5gAFKfPle41w== +"@abp/ng.setting-management.config@^2.5.0", "@abp/ng.setting-management.config@~2.5.0": + version "2.5.0" + resolved "https://registry.yarnpkg.com/@abp/ng.setting-management.config/-/ng.setting-management.config-2.5.0.tgz#4841d73b9df7763084dcac45bd656fbee87c4602" + integrity sha512-mSihz0aoB5Ly+tanPE4Vh3Aam9g3nDtSQelUuFJoyRnw1HSmMmWOqnJi9UEguhCEBtww9G5P6OC8/icpHaq/3Q== dependencies: tslib "^1.9.0" -"@abp/ng.setting-management@~2.4.1": - version "2.4.1" - resolved "https://registry.yarnpkg.com/@abp/ng.setting-management/-/ng.setting-management-2.4.1.tgz#b3028d8e65866529c2bb6a22980a110fa5247b67" - integrity sha512-oA6ZUJUQFvmY7QLff/cXnmefN2hGTwhD9iumZSckvl1TitOhzJuj1uQ8kT2c0Az13a5R14Zuk44KYwn2wGFeSg== +"@abp/ng.setting-management@~2.5.0": + version "2.5.0" + resolved "https://registry.yarnpkg.com/@abp/ng.setting-management/-/ng.setting-management-2.5.0.tgz#32291ebc6610838f825cc79d091700d578586e0a" + integrity sha512-maamVGc5L/44XsRANXaVYLn9uocGUH8RUtKXZT9iKdlcsemKa7xEMzZ84lzoiAu+xAfqfJm/R7TolC/gWonUDg== dependencies: - "@abp/ng.setting-management.config" "^2.4.1" - "@abp/ng.theme.shared" "^2.4.1" + "@abp/ng.setting-management.config" "^2.5.0" + "@abp/ng.theme.shared" "^2.5.0" tslib "^1.9.0" -"@abp/ng.tenant-management.config@^2.4.1", "@abp/ng.tenant-management.config@~2.4.1": - version "2.4.1" - resolved "https://registry.yarnpkg.com/@abp/ng.tenant-management.config/-/ng.tenant-management.config-2.4.1.tgz#fe77a00fee18d2f221e68b7edd1d9d52c4a24595" - integrity sha512-0WsqESU5eXCkH9A4AVSZCOGOTo+pL8jW9raYxCbxp8A6GGxHA78UiqjLO/ZqA9ercXt9lh2s3JIbclhsOJWHBA== +"@abp/ng.tenant-management.config@^2.5.0", "@abp/ng.tenant-management.config@~2.5.0": + version "2.5.0" + resolved "https://registry.yarnpkg.com/@abp/ng.tenant-management.config/-/ng.tenant-management.config-2.5.0.tgz#00b3abae5d513d61fcc0aae6c73d64a61d087e5f" + integrity sha512-gaW9n+Fo9AH2OPw3V3qaxTvG8zIe4jjMXKIvzqk+e4djXVjLHZ3fdP+uyJqpMmaypyd2REoVCARqVFHgvZBzaA== dependencies: tslib "^1.9.0" -"@abp/ng.tenant-management@~2.4.1": - version "2.4.1" - resolved "https://registry.yarnpkg.com/@abp/ng.tenant-management/-/ng.tenant-management-2.4.1.tgz#e9bffd96b1805036d840d078a8e7c78dd027c5eb" - integrity sha512-HEyWwXrgKWdrZ84Txw+0k+PGBb/ekqMKmwytOrG3Z7fxTRqWVMP/6QbHcbJD929zR4aehAmEAfvex/210qD1rw== +"@abp/ng.tenant-management@~2.5.0": + version "2.5.0" + resolved "https://registry.yarnpkg.com/@abp/ng.tenant-management/-/ng.tenant-management-2.5.0.tgz#7452ab92d9d7f2bf1200a956e7ad8800c4ccebb1" + integrity sha512-7O7tsJl2OVbEIiSJ17r+ZJFcynOo89el0RREwihACkBz+2TeQoHo2ycZ7oPXauMy1aRjsjpkmbCJGP28OD0a6w== dependencies: - "@abp/ng.feature-management" "^2.4.1" - "@abp/ng.tenant-management.config" "^2.4.1" - "@abp/ng.theme.shared" "^2.4.1" + "@abp/ng.feature-management" "^2.5.0" + "@abp/ng.tenant-management.config" "^2.5.0" + "@abp/ng.theme.shared" "^2.5.0" tslib "^1.9.0" -"@abp/ng.theme.basic@~2.4.1": - version "2.4.1" - resolved "https://registry.yarnpkg.com/@abp/ng.theme.basic/-/ng.theme.basic-2.4.1.tgz#faf06ea09557323e77ffb648f55ff915ecc252de" - integrity sha512-fV9a6wfeWN5C1UmYGDzaT3bQMfkUzAt0T/JRaAiWTsWTUV/y69prGqD2dMEMvdIAPR3zhKK/125N6+apl/l0iQ== +"@abp/ng.theme.basic@~2.5.0": + version "2.5.0" + resolved "https://registry.yarnpkg.com/@abp/ng.theme.basic/-/ng.theme.basic-2.5.0.tgz#ef13f448ea6f356a5571d364da00e971e715cfec" + integrity sha512-+q22k5AfxgFRtGP4YO602jmeeuH2pfVBzCcJUmwRzE2xiINx4e55zCwKiFl5YvNUttcKkaNNhj9LcOXU6W42rw== dependencies: - "@abp/ng.theme.shared" "^2.4.1" + "@abp/ng.theme.shared" "^2.5.0" tslib "^1.9.0" -"@abp/ng.theme.shared@^2.4.1": - version "2.4.1" - resolved "https://registry.yarnpkg.com/@abp/ng.theme.shared/-/ng.theme.shared-2.4.1.tgz#1c0c5c1714099136a6ecd256df66602099721ef3" - integrity sha512-iXqVrpjCYkG8Dc6tocn21qDnu2i9bi625CEk7J+U7O+L0X2ECYqHJXH8DqQrEeQ0F3lun0gOXUc3wo83G15PrA== +"@abp/ng.theme.shared@^2.5.0", "@abp/ng.theme.shared@~2.5.0": + version "2.5.0" + resolved "https://registry.yarnpkg.com/@abp/ng.theme.shared/-/ng.theme.shared-2.5.0.tgz#a9c53f95f1a0bdf2fe046838e64c658ce54c5655" + integrity sha512-iRft0LWh9dzpnrKxmo0AuAXND6+o3Eov6LFpNbZD7guuZfeFVehcSX/X0ZYIpq1a/A7cfegtMEokdwRb0cGdGA== dependencies: - "@abp/ng.core" "^2.4.1" + "@abp/ng.core" "^2.5.0" "@fortawesome/fontawesome-free" "^5.12.1" "@ng-bootstrap/ng-bootstrap" "^5.3.0" "@ngx-validate/core" "^0.0.7" From af51255d3dff3c11b9cbfabe18928773f921c65a Mon Sep 17 00:00:00 2001 From: Arman Ozak Date: Fri, 10 Apr 2020 09:56:17 +0300 Subject: [PATCH 123/334] refactor: make content projection a separate service --- .../UI/Angular/Content-Projection-Service.md | 78 +++++++++++++++++++ docs/en/UI/Angular/Dom-Insertion-Service.md | 36 +-------- docs/en/docs-nav.json | 4 + .../services/content-projection.service.ts | 14 ++++ .../src/lib/services/dom-insertion.service.ts | 10 +-- .../packages/core/src/lib/services/index.ts | 1 + .../tests/content-projection.service.spec.ts | 38 +++++++++ .../lib/tests/dom-insertion.service.spec.ts | 32 +------- 8 files changed, 143 insertions(+), 70 deletions(-) create mode 100644 docs/en/UI/Angular/Content-Projection-Service.md create mode 100644 npm/ng-packs/packages/core/src/lib/services/content-projection.service.ts create mode 100644 npm/ng-packs/packages/core/src/lib/tests/content-projection.service.spec.ts diff --git a/docs/en/UI/Angular/Content-Projection-Service.md b/docs/en/UI/Angular/Content-Projection-Service.md new file mode 100644 index 0000000000..6bd30e44c6 --- /dev/null +++ b/docs/en/UI/Angular/Content-Projection-Service.md @@ -0,0 +1,78 @@ +# Content Projection + +You can use the `ContentProjectionService` in @abp/ng.core package in order to project content in an easy and explicit way. + +## Getting Started + +You do not have to provide the `ContentProjectionService` at module or component level, because it is already **provided in root**. You can inject and start using it immediately in your components, directives, or services. + +```js +import { ContentProjectionService } from '@abp/ng.core'; + +@Component({ + /* class metadata here */ +}) +class DemoComponent { + constructor(private contentProjectionService: ContentProjectionService) {} +} +``` + +## Usage + +You can use the `projectContent` method of `ContentProjectionService` to render components and templates dynamically in your project. + +### How to Project Components to Root Level + +If you pass a `RootComponentProjectionStrategy` as the first parameter of `projectContent` method, the `ContentProjectionService` will resolve the projected component and place it at the root level. If provided, it will also pass the component a context. + +```js +const strategy = PROJECTION_STRATEGY.AppendComponentToBody( + SomeOverlayComponent, + { someOverlayProp: "SOME_VALUE" } +); + +const componentRef = this.ContentProjectionService.projectContent(strategy); +``` + +In the example above, `SomeOverlayComponent` component will placed at the **end** of `` and a `ComponentRef` will be returned. Additionally, the given context will be applied, so `someOverlayProp` of the component will be set to `SOME_VALUE`. + +> You should keep the returned `ComponentRef` instance, as it is a reference to the projected component and you will need that reference to destroy the projected view and the component instance. + +### How to Project Components and Templates into a Container + +If you pass a `ComponentProjectionStrategy` or `TemplateProjectionStrategy` as the first parameter of `projectContent` method, and a `ViewContainerRef` as the second parameter of that strategy, the `ContentProjectionService` will project the component or template to the given container. If provided, it will also pass the component or the template a context. + +```js +const strategy = PROJECTION_STRATEGY.ProjectComponentToContainer( + SomeComponent, + viewContainerRefOfTarget, + { someProp: "SOME_VALUE" } +); + +const componentRef = this.ContentProjectionService.projectContent(strategy); +``` + +In this example, the `viewContainerRefOfTarget`, which is a `ViewContainerRef` instance, will be cleared and `SomeComponent` component will placed inside it. Moreover, the given context will be applied, so `someProp` of the component will be set to `SOME_VALUE`. + +> You should keep the returned `ComponentRef` or `EmbeddedViewRef`, as they are a reference to the projected content and you will need them to destroy it when necessary. + +Please refer to [ProjectionStrategy](./Projection-Strategy.md) to see all available projection strategies and how you can build your own projection strategy. + +## API + +### projectContent + +```js +projectContent | TemplateRef>( + projectionStrategy: ProjectionStrategy, + injector = this.injector, +): ComponentRef | EmbeddedViewRef +``` + +- `projectionStrategy` parameter is the primary focus here and is explained above. +- `injector` parameter is the `Injector` instance you can pass to the projected content. It is not used in `TemplateProjectionStrategy`. + + +## What's Next? + +- [TrackByService](./Track-By-Service.md) diff --git a/docs/en/UI/Angular/Dom-Insertion-Service.md b/docs/en/UI/Angular/Dom-Insertion-Service.md index 5159ae2c35..d5ea9fe3a2 100644 --- a/docs/en/UI/Angular/Dom-Insertion-Service.md +++ b/docs/en/UI/Angular/Dom-Insertion-Service.md @@ -1,4 +1,4 @@ -# How to Insert Scripts and Styles +# Dom Insertion (of Scripts and Styles) You can use the `DomInsertionService` in @abp/ng.core package in order to insert scripts and styles in an easy and explicit way. @@ -71,45 +71,17 @@ In the example above, `` element will place at t Please refer to [ContentStrategy](./Content-Strategy.md) to see all available content strategies and how you can build your own content strategy. -### How to Project Components & Templates - -If you pass a `ProjectionStrategy` as the first parameter of `projectContent` method, the `DomInsertionService` will resolve the projected component or template and place it at the designated target, such as containers or document body. If provided, it will also pass the component or the template a context. - -```js -const componentRef = this.domInsertionService.projectContent( - PROJECTION_STRATEGY.AppendComponentToBody(SomeOverlayComponent) -); -``` - -In the example above, `SomeOverlayComponent` component will placed at the **end** of `` and a `ComponentRef` will be returned. - -> You should keep the returned `ComponentRef` instance, as it is a reference to the projected component and you will need that reference to destroy the projected view and the component instance. - -```js -const componentRef = this.domInsertionService.projectContent( - PROJECTION_STRATEGY.ProjectComponentToContainer( - SomeOverlayComponent, - viewContainerRefOfTarget, - { someProp: "SOME_VALUE" } - ) -); -``` - -In this example, the `viewContainerRefOfTarget`, which is a `ViewContainerRef` instance, will be cleared and `SomeOverlayComponent` component will placed inside it. Moreover, the given context will be applied, so `someProp` of the component will be set to `SOME_VALUE`. - -Please refer to [ProjectionStrategy](./Projection-Strategy.md) to see all available projection strategies and how you can build your own projection strategy. - ## API ### insertContent ```js -injectContent(injector: Injector): ComponentRef | EmbeddedViewRef +insertContent(contentStrategy: ContentStrategy): void ``` -`injector` parameter is the `Injector` instance you can pass to the projected content. It is not used in `TemplateProjectionStrategy`. +- `contentStrategy` parameter is the primary focus here and is explained above. ## What's Next? -- [TrackByService](./Track-By-Service.md) +- [ContentProjectionService](./Content-Projection-Service.md) diff --git a/docs/en/docs-nav.json b/docs/en/docs-nav.json index 471e215e3a..20214b8447 100644 --- a/docs/en/docs-nav.json +++ b/docs/en/docs-nav.json @@ -353,6 +353,10 @@ "text": "DomInsertionService", "path": "UI/Angular/Dom-Insertion-Service.md" }, + { + "text": "ContentProjectionService", + "path": "UI/Angular/Content-Projection-Service.md" + }, { "text": "TrackByService", "path": "UI/Angular/Track-By-Service.md" diff --git a/npm/ng-packs/packages/core/src/lib/services/content-projection.service.ts b/npm/ng-packs/packages/core/src/lib/services/content-projection.service.ts new file mode 100644 index 0000000000..dfcdea330a --- /dev/null +++ b/npm/ng-packs/packages/core/src/lib/services/content-projection.service.ts @@ -0,0 +1,14 @@ +import { Injectable, Injector, TemplateRef, Type } from '@angular/core'; +import { ProjectionStrategy } from '../strategies/projection.strategy'; + +@Injectable({ providedIn: 'root' }) +export class ContentProjectionService { + constructor(private injector: Injector) {} + + projectContent | TemplateRef>( + projectionStrategy: ProjectionStrategy, + injector = this.injector, + ) { + return projectionStrategy.injectContent(injector); + } +} diff --git a/npm/ng-packs/packages/core/src/lib/services/dom-insertion.service.ts b/npm/ng-packs/packages/core/src/lib/services/dom-insertion.service.ts index 5e53a64995..c10967ebbb 100644 --- a/npm/ng-packs/packages/core/src/lib/services/dom-insertion.service.ts +++ b/npm/ng-packs/packages/core/src/lib/services/dom-insertion.service.ts @@ -1,6 +1,5 @@ -import { Injectable, Injector, TemplateRef, Type } from '@angular/core'; +import { Injectable, Injector } from '@angular/core'; import { ContentStrategy } from '../strategies/content.strategy'; -import { ProjectionStrategy } from '../strategies/projection.strategy'; import { generateHash } from '../utils'; @Injectable({ providedIn: 'root' }) @@ -17,11 +16,4 @@ export class DomInsertionService { contentStrategy.insertElement(); this.inserted.add(hash); } - - projectContent | TemplateRef>( - projectionStrategy: ProjectionStrategy, - injector = this.injector, - ) { - return projectionStrategy.injectContent(injector); - } } diff --git a/npm/ng-packs/packages/core/src/lib/services/index.ts b/npm/ng-packs/packages/core/src/lib/services/index.ts index a64e721c67..f8b016bbd1 100644 --- a/npm/ng-packs/packages/core/src/lib/services/index.ts +++ b/npm/ng-packs/packages/core/src/lib/services/index.ts @@ -1,6 +1,7 @@ export * from './application-configuration.service'; export * from './auth.service'; export * from './config-state.service'; +export * from './content-projection.service'; export * from './dom-insertion.service'; export * from './lazy-load.service'; export * from './localization.service'; diff --git a/npm/ng-packs/packages/core/src/lib/tests/content-projection.service.spec.ts b/npm/ng-packs/packages/core/src/lib/tests/content-projection.service.spec.ts new file mode 100644 index 0000000000..30f9f92e73 --- /dev/null +++ b/npm/ng-packs/packages/core/src/lib/tests/content-projection.service.spec.ts @@ -0,0 +1,38 @@ +import { Component, ComponentRef, NgModule } from '@angular/core'; +import { createServiceFactory, SpectatorService } from '@ngneat/spectator'; +import { ContentProjectionService } from '../services'; +import { PROJECTION_STRATEGY } from '../strategies'; + +describe('ContentProjectionService', () => { + @Component({ template: '
bar
' }) + class TestComponent {} + + // createServiceFactory does not accept entryComponents directly + @NgModule({ + declarations: [TestComponent], + entryComponents: [TestComponent], + }) + class TestModule {} + + let componentRef: ComponentRef; + let spectator: SpectatorService; + const createService = createServiceFactory({ + service: ContentProjectionService, + imports: [TestModule], + }); + + beforeEach(() => (spectator = createService())); + + afterEach(() => componentRef.destroy()); + + describe('#projectContent', () => { + it('should call injectContent of given projectionStrategy and return what it returns', () => { + const strategy = PROJECTION_STRATEGY.AppendComponentToBody(TestComponent); + componentRef = spectator.service.projectContent(strategy); + const foo = document.querySelector('body > ng-component > div.foo'); + + expect(componentRef).toBeInstanceOf(ComponentRef); + expect(foo.textContent).toBe('bar'); + }); + }); +}); diff --git a/npm/ng-packs/packages/core/src/lib/tests/dom-insertion.service.spec.ts b/npm/ng-packs/packages/core/src/lib/tests/dom-insertion.service.spec.ts index 8ae75c2f15..f8e8565496 100644 --- a/npm/ng-packs/packages/core/src/lib/tests/dom-insertion.service.spec.ts +++ b/npm/ng-packs/packages/core/src/lib/tests/dom-insertion.service.spec.ts @@ -1,25 +1,11 @@ -import { Component, ComponentRef, NgModule } from '@angular/core'; import { createServiceFactory, SpectatorService } from '@ngneat/spectator'; import { DomInsertionService } from '../services'; -import { CONTENT_STRATEGY, PROJECTION_STRATEGY } from '../strategies'; +import { CONTENT_STRATEGY } from '../strategies'; describe('DomInsertionService', () => { - @Component({ template: '
bar
' }) - class TestComponent {} - - // createServiceFactory does not accept entryComponents directly - @NgModule({ - declarations: [TestComponent], - entryComponents: [TestComponent], - }) - class TestModule {} - - let spectator: SpectatorService; - const createService = createServiceFactory({ - service: DomInsertionService, - imports: [TestModule], - }); let styleElements: NodeListOf; + let spectator: SpectatorService; + const createService = createServiceFactory(DomInsertionService); beforeEach(() => (spectator = createService())); @@ -56,16 +42,4 @@ describe('DomInsertionService', () => { expect(spectator.service.inserted.has(1437348290)).toBe(true); }); }); - - describe('#projectContent', () => { - it('should call injectContent of given projectionStrategy and return what it returns', () => { - const strategy = PROJECTION_STRATEGY.AppendComponentToBody(TestComponent); - const componentRef = spectator.service.projectContent(strategy); - const foo = document.querySelector('body > ng-component > div.foo'); - - expect(componentRef).toBeInstanceOf(ComponentRef); - expect(foo.textContent).toBe('bar'); - componentRef.destroy(); - }); - }); }); From 83d9ad3f08678dfeb3db9b3969ff921a52ec9cb4 Mon Sep 17 00:00:00 2001 From: Arman Ozak Date: Fri, 10 Apr 2020 10:04:04 +0300 Subject: [PATCH 124/334] refactor: remove unnecessary initializer --- .../packages/core/src/lib/tests/projection.strategy.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/npm/ng-packs/packages/core/src/lib/tests/projection.strategy.spec.ts b/npm/ng-packs/packages/core/src/lib/tests/projection.strategy.spec.ts index 1166d44f57..a0b3bb61bb 100644 --- a/npm/ng-packs/packages/core/src/lib/tests/projection.strategy.spec.ts +++ b/npm/ng-packs/packages/core/src/lib/tests/projection.strategy.spec.ts @@ -213,7 +213,7 @@ describe('TemplateProjectionStrategy', () => { describe('PROJECTION_STRATEGY', () => { const content = undefined; const containerRef = ({ length: 0 } as any) as ViewContainerRef; - let context = undefined; + let context: any; test.each` name | Strategy | containerStrategy From 1b4bfd03f48aadc8ee21a3302c5f962bb1a68899 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Levent=20Arman=20=C3=96zak?= Date: Fri, 10 Apr 2020 10:17:16 +0300 Subject: [PATCH 125/334] docs: use ApplicationLayout instead of AccountLayout key --- docs/en/UI/Angular/Component-Replacement.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/UI/Angular/Component-Replacement.md b/docs/en/UI/Angular/Component-Replacement.md index d1f88c0400..fb85aa476e 100644 --- a/docs/en/UI/Angular/Component-Replacement.md +++ b/docs/en/UI/Angular/Component-Replacement.md @@ -71,7 +71,7 @@ export class AppComponent { this.store.dispatch( new AddReplaceableComponent({ component: MyApplicationLayoutComponent, - key: eThemeBasicComponents.AccountLayout, + key: eThemeBasicComponents.ApplicationLayout, }), ); From 6ae41180056d71cf4d12d4a9b2d98adefa7d46a2 Mon Sep 17 00:00:00 2001 From: Arman Ozak Date: Fri, 10 Apr 2020 10:25:38 +0300 Subject: [PATCH 126/334] refactor: remove unused injector --- .../packages/core/src/lib/services/dom-insertion.service.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/npm/ng-packs/packages/core/src/lib/services/dom-insertion.service.ts b/npm/ng-packs/packages/core/src/lib/services/dom-insertion.service.ts index c10967ebbb..d4b30b731d 100644 --- a/npm/ng-packs/packages/core/src/lib/services/dom-insertion.service.ts +++ b/npm/ng-packs/packages/core/src/lib/services/dom-insertion.service.ts @@ -1,4 +1,4 @@ -import { Injectable, Injector } from '@angular/core'; +import { Injectable } from '@angular/core'; import { ContentStrategy } from '../strategies/content.strategy'; import { generateHash } from '../utils'; @@ -6,8 +6,6 @@ import { generateHash } from '../utils'; export class DomInsertionService { readonly inserted = new Set(); - constructor(private injector: Injector) {} - insertContent(contentStrategy: ContentStrategy) { const hash = generateHash(contentStrategy.content); From 0d1295ad7beb32dcc76e4ca5042d70104fd8e127 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Fri, 10 Apr 2020 10:28:02 +0300 Subject: [PATCH 127/334] Don't add en language file for the timeago. --- .../Mvc/UI/Packages/Timeago/TimeagoScriptContributor.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/Timeago/TimeagoScriptContributor.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/Timeago/TimeagoScriptContributor.cs index a276849db6..9edbf065cb 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/Timeago/TimeagoScriptContributor.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/Timeago/TimeagoScriptContributor.cs @@ -17,6 +17,11 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Packages.Timeago public override void ConfigureDynamicResources(BundleConfigurationContext context) { var cultureName = CultureInfo.CurrentUICulture.TwoLetterISOLanguageName; + if (cultureName.StartsWith("en")) + { + return; + } + var cultureFileName = $"/libs/timeago/locales/jquery.timeago.{cultureName}.js"; if (context.FileProvider.GetFileInfo(cultureFileName).Exists) From 0999be319d3a5c6411ed6e679ae5778a7be61a2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Fri, 10 Apr 2020 12:10:20 +0300 Subject: [PATCH 128/334] Add IHasExtraProperties Interface section --- docs/en/Object-Extensions.md | 106 ++++++++++++++++++++++++++++++++++- 1 file changed, 105 insertions(+), 1 deletion(-) diff --git a/docs/en/Object-Extensions.md b/docs/en/Object-Extensions.md index fad3ff2b0c..70a83e8ef2 100644 --- a/docs/en/Object-Extensions.md +++ b/docs/en/Object-Extensions.md @@ -1,3 +1,107 @@ # Object Extensions -TODO \ No newline at end of file +ABP Framework provides an **object extension system** to allow you to **add extra properties** to an existing object **without modifying** the related class. This allows to extend functionalities implemented by a depended [application module](Modules/Index.md), especially when you want to [extend entities](Customizing-Application-Modules-Extending-Entities.md) and [DTOs](Customizing-Application-Modules-Overriding-Services.md) defined by the module. + +> Object extension system is not normally not needed for your own objects since you can easily add regular properties to your own classes. + +## IHasExtraProperties Interface + +This is the interface to make a class extensible. It simply defines a `Dictionary` property: + +````csharp +Dictionary ExtraProperties { get; } +```` + +Then you can add or get extra properties using this dictionary. + +### Base Classes + +`IHasExtraProperties` interface is implemented by several base classes by default: + +* Implemented by the `AggregateRoot` class (see [entities](Entities.md)). +* Implemented by `ExtensibleEntityDto`, `ExtensibleAuditedEntityDto`... base [DTO](Data-Transfer-Objects.md) classes. +* Implemented by the `ExtensibleObject`, which is a simple base class can be inherited for any type of object. + +So, if you inherit from these classes, your class will also be extensible. If not, you can always implement it manually. + +### Fundamental Extension Methods + +While you can directly use the `ExtraProperties` property of a class, it is suggested to use the following extension methods while working with the extra properties. + +#### SetProperty + +Used to set the value of an extra property: + +````csharp +user.SetProperty("Title", "My Title"); +user.SetProperty("IsSuperUser", true); +```` + +`SetProperty` returns the same object, so you can chain it: + +````csharp +user.SetProperty("Title", "My Title") + .SetProperty("IsSuperUser", true); +```` + +#### GetProperty + +Used to read the value of an extra property: + +````csharp +var title = user.GetProperty("Title"); + +if (user.GetProperty("IsSuperUser")) +{ + //... +} +```` + +* `GetProperty` is a generic method and takes the object type as the generic parameter. +* Returns the default value if given property was not set before (default value is `0` for `int`, `false` for `bool`... etc). + +##### Non Primitive Property Types + +If your property type is not a primitive (int, bool, enum, string... etc) type, then you need to use non-generic version of the `GetProperty` which returns an `object`. + +#### HasProperty + +Used to check if the object has a property set before. + +#### RemoveProperty + +Used to remove a property from the object. Use this methods instead of setting a `null` value for the property. + +### Some Best Practices + +Using magic strings for the property names is dangerous since you can easily type the property name wrong - it is not type safe. Instead; + +* Define a constant for your extra property names +* Create extension methods to easily set your extra properties. + +Example: + +````csharp +public static class IdentityUserExtensions +{ + private const string TitlePropertyName = "Title"; + + public static void SetTitle(this IdentityUser user, string title) + { + user.SetProperty(TitlePropertyName, title); + } + + public static string GetTitle(this IdentityUser user) + { + return user.GetProperty(TitlePropertyName); + } +} +```` + +Then you can easily set or get the `Title` property: + +````csharp +user.SetTitle("My Title"); +var title = user.GetTitle(); +```` + From 98f97f0228970c8f8f00554790c70bdddb4b7056 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Fri, 10 Apr 2020 12:10:40 +0300 Subject: [PATCH 129/334] Rename ExtensibleObjectMapper file. --- .../{ExtendedObjectMapper.cs => ExtensibleObjectMapper.cs} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/{ExtendedObjectMapper.cs => ExtensibleObjectMapper.cs} (100%) diff --git a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ExtendedObjectMapper.cs b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ExtensibleObjectMapper.cs similarity index 100% rename from framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ExtendedObjectMapper.cs rename to framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ExtensibleObjectMapper.cs From 30622bb8f8a117562d0fd5435c869ec65ddbfe9b Mon Sep 17 00:00:00 2001 From: Mehmet Erim <34455572+mehmet-erim@users.noreply.github.com> Date: Fri, 10 Apr 2020 13:10:59 +0300 Subject: [PATCH 130/334] Update Content-Projection-Service.md --- docs/en/UI/Angular/Content-Projection-Service.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/UI/Angular/Content-Projection-Service.md b/docs/en/UI/Angular/Content-Projection-Service.md index 6bd30e44c6..664123c2fb 100644 --- a/docs/en/UI/Angular/Content-Projection-Service.md +++ b/docs/en/UI/Angular/Content-Projection-Service.md @@ -31,7 +31,7 @@ const strategy = PROJECTION_STRATEGY.AppendComponentToBody( { someOverlayProp: "SOME_VALUE" } ); -const componentRef = this.ContentProjectionService.projectContent(strategy); +const componentRef = this.contentProjectionService.projectContent(strategy); ``` In the example above, `SomeOverlayComponent` component will placed at the **end** of `` and a `ComponentRef` will be returned. Additionally, the given context will be applied, so `someOverlayProp` of the component will be set to `SOME_VALUE`. From d27ddb398b070d7a0b960d0855c7bb43de476142 Mon Sep 17 00:00:00 2001 From: mehmet-erim Date: Fri, 10 Apr 2020 14:29:42 +0300 Subject: [PATCH 131/334] refactor: add undefined control to loading.directive --- .../theme-shared/src/lib/directives/loading.directive.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/npm/ng-packs/packages/theme-shared/src/lib/directives/loading.directive.ts b/npm/ng-packs/packages/theme-shared/src/lib/directives/loading.directive.ts index 40b76cbfc8..bed4fab0da 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/directives/loading.directive.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/directives/loading.directive.ts @@ -54,7 +54,7 @@ export class LoadingDirective implements OnInit, OnDestroy { if (newValue && !this.rootNode) { this.rootNode = (this.componentRef.hostView as EmbeddedViewRef).rootNodes[0]; this.targetElement.appendChild(this.rootNode); - } else { + } else if (this.rootNode) { this.renderer.removeChild(this.rootNode.parentElement, this.rootNode); this.rootNode = null; } From 04cd0eae4d82232fc68c2fd99c1d92bfddb4b533 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Fri, 10 Apr 2020 14:46:11 +0300 Subject: [PATCH 132/334] Update Object-Extensions.md --- docs/en/Object-Extensions.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/docs/en/Object-Extensions.md b/docs/en/Object-Extensions.md index 70a83e8ef2..5841eb739c 100644 --- a/docs/en/Object-Extensions.md +++ b/docs/en/Object-Extensions.md @@ -105,3 +105,15 @@ user.SetTitle("My Title"); var title = user.GetTitle(); ```` +## Object Extension Manager + +While you can set arbitrary properties to an extensible object (which implements the `IHasExtraProperties` interface), `ObjectExtensionManager` is used to explicitly define extra properties for extensible classes. + +Explicitly defining an extra property has some use cases: + +* Allows to control how the extra property is handled on object to object mapping (see the section below). +* Allows to define metadata for the property. For example, you can map an extra property to a table field in the database while using the [EF Core](Entity-Framework-Core.md). + +### AddOrUpdate + +`AddOrUpdate` is the main method to define a new extra property or update an extra property definition. \ No newline at end of file From d316d96e3e11c9160b4da6d53d73e4587cf04b17 Mon Sep 17 00:00:00 2001 From: Arman Ozak Date: Fri, 10 Apr 2020 14:50:36 +0300 Subject: [PATCH 133/334] docs: fix mistakes in content projection service --- docs/en/UI/Angular/Content-Projection-Service.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/en/UI/Angular/Content-Projection-Service.md b/docs/en/UI/Angular/Content-Projection-Service.md index 664123c2fb..db7c52be81 100644 --- a/docs/en/UI/Angular/Content-Projection-Service.md +++ b/docs/en/UI/Angular/Content-Projection-Service.md @@ -49,10 +49,10 @@ const strategy = PROJECTION_STRATEGY.ProjectComponentToContainer( { someProp: "SOME_VALUE" } ); -const componentRef = this.ContentProjectionService.projectContent(strategy); +const componentRef = this.contentProjectionService.projectContent(strategy); ``` -In this example, the `viewContainerRefOfTarget`, which is a `ViewContainerRef` instance, will be cleared and `SomeComponent` component will placed inside it. Moreover, the given context will be applied, so `someProp` of the component will be set to `SOME_VALUE`. +In this example, the `viewContainerRefOfTarget`, which is a `ViewContainerRef` instance, will be cleared and `SomeComponent` component will be placed inside it. In addition, the given context will be applied and `someProp` of the component will be set to `SOME_VALUE`. > You should keep the returned `ComponentRef` or `EmbeddedViewRef`, as they are a reference to the projected content and you will need them to destroy it when necessary. From 0072dec0b6f782e1a306c0d714dc0dc607efaa52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Fri, 10 Apr 2020 16:18:45 +0300 Subject: [PATCH 134/334] complete the object extension manager document. --- docs/en/Object-Extensions.md | 150 +++++++++++++++++- docs/en/docs-nav.json | 4 + .../ObjectExtending/ExtensibleObjectMapper.cs | 2 - 3 files changed, 153 insertions(+), 3 deletions(-) diff --git a/docs/en/Object-Extensions.md b/docs/en/Object-Extensions.md index 5841eb739c..bbcb96374c 100644 --- a/docs/en/Object-Extensions.md +++ b/docs/en/Object-Extensions.md @@ -114,6 +114,154 @@ Explicitly defining an extra property has some use cases: * Allows to control how the extra property is handled on object to object mapping (see the section below). * Allows to define metadata for the property. For example, you can map an extra property to a table field in the database while using the [EF Core](Entity-Framework-Core.md). +> `ObjectExtensionManager` implements the singleton pattern (`ObjectExtensionManager.Instance`) and you should define object extensions before your application startup. The [application startup template](Startup-Templates/Application.md) has some pre-defined static classes to safely define object extensions inside. + ### AddOrUpdate -`AddOrUpdate` is the main method to define a new extra property or update an extra property definition. \ No newline at end of file +`AddOrUpdate` is the main method to define a extra properties or update extra properties for an object. + +Example: Define extra properties for the `IdentityUser` entity: + +````csharp +ObjectExtensionManager.Instance + .AddOrUpdate(options => + { + options.AddOrUpdateProperty("SocialSecurityNumber"); + options.AddOrUpdateProperty("IsSuperUser"); + } + ); +```` + +### AddOrUpdateProperty + +While `AddOrUpdateProperty` can be used on the `options` as shown before, if you want to define a single extra property, you can use the shortcut extension method too: + +````csharp +ObjectExtensionManager.Instance + .AddOrUpdateProperty("SocialSecurityNumber"); +```` + +Sometimes it would be practical to define a single extra property to multiple types. Instead of defining one by one, you can use the following code: + +````csharp +ObjectExtensionManager.Instance + .AddOrUpdateProperty( + new[] + { + typeof(IdentityUserDto), + typeof(IdentityUserCreateDto), + typeof(IdentityUserUpdateDto) + }, + "SocialSecurityNumber" + ); +```` + +#### Property Configuration + +`AddOrUpdateProperty` can also get an action that can perform additional configuration on the property definition. + +Example: + +````csharp +ObjectExtensionManager.Instance + .AddOrUpdateProperty( + "SocialSecurityNumber", + options => + { + options.CheckPairDefinitionOnMapping = false; + }); +```` + +> See the "Object to Object Mapping" section to understand the `CheckPairDefinitionOnMapping` option. + +`options` has a dictionary, named `Configuration` which makes the object extension definitions even extensible. It is used by the EF Core to map extra properties to table fields in the database. See the [extending entities](Customizing-Application-Modules-Extending-Entities.md) document. + +## Object to Object Mapping + +Assume that you've added an extra property to an extensible entity object and used auto [object to object mapping](Object-To-Object-Mapping.md) to map this entity to an extensible DTO class. You need to be careful in such a case, because the extra property may contain a **sensitive data** that should not be available to clients. + +This section offers some **good practices** to control your extra properties on object mapping. + +### MapExtraPropertiesTo + +`MapExtraPropertiesTo` is an extension method provided by the ABP Framework to copy extra properties from an object to another in a controlled manner. Example usage: + +````csharp +identityUser.MapExtraPropertiesTo(identityUserDto); +```` + +`MapExtraPropertiesTo` **requires to define properties** (as described above) in **both sides** (`IdentityUser` and `IdentityUserDto` in this case) in order to copy the value to the target object. Otherwise, it doesn't copy the value even if it does exists in the source object (`identityUser` in this example). There are some ways to overload this restriction. + +#### MappingPropertyDefinitionChecks + +`MapExtraPropertiesTo` gets an additional parameter to control the definition check for a single mapping operation: + +````csharp +identityUser.MapExtraPropertiesTo( + identityUserDto, + MappingPropertyDefinitionChecks.None +); +```` + +> Be careful since `MappingPropertyDefinitionChecks.None` copies all extra properties without any check. `MappingPropertyDefinitionChecks` enum has other members too. + +If you want to completely disable definition check for a property, you can do it while defining the extra property (or update an existing definition) as shown below: + +````csharp +ObjectExtensionManager.Instance + .AddOrUpdateProperty( + "SocialSecurityNumber", + options => + { + options.CheckPairDefinitionOnMapping = false; + }); +```` + +#### Ignored Properties + +You may want to ignore some properties on a specific mapping operation: + +````csharp +identityUser.MapExtraPropertiesTo( + identityUserDto, + ignoredProperties: new[] {"MySensitiveProp"} +); +```` + +Ignored properties are not copied to the target object. + +#### AutoMapper Integration + +If you're using the [AutoMapper](https://automapper.org/) library, the ABP Framework also provides an extension method to utilize the `MapExtraPropertiesTo` method defined above. + +You can use the `MapExtraProperties()` method inside your mapping profile. + +````csharp +public class MyProfile : Profile +{ + public MyProfile() + { + CreateMap() + .MapExtraProperties(); + } +} +```` + +It has the same parameters with the `MapExtraPropertiesTo` method. + +## Entity Framework Core Database Mapping + +If you're using the EF Core, you can map an extra property to a table field in the database. Example: + +````csharp +ObjectExtensionManager.Instance + .AddOrUpdateProperty( + "SocialSecurityNumber", + options => + { + options.MapEfCore(b => b.HasMaxLength(32)); + } + ); +```` + +See the [Entity Framework Core Integration document](Entity-Framework-Core.md) for more. \ No newline at end of file diff --git a/docs/en/docs-nav.json b/docs/en/docs-nav.json index 471e215e3a..f45a4192bb 100644 --- a/docs/en/docs-nav.json +++ b/docs/en/docs-nav.json @@ -155,6 +155,10 @@ { "text": "Data Filtering", "path": "Data-Filtering.md" + }, + { + "text": "Object Extensions", + "path": "Object-Extensions.md" } ] }, diff --git a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ExtensibleObjectMapper.cs b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ExtensibleObjectMapper.cs index f2b7aeecdb..671aff40f2 100644 --- a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ExtensibleObjectMapper.cs +++ b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ExtensibleObjectMapper.cs @@ -122,8 +122,6 @@ namespace Volo.Abp.ObjectExtending } } - //TODO: Move these methods to a class like ObjectExtensionHelper - public static bool CanMapProperty( [NotNull] string propertyName, MappingPropertyDefinitionChecks? definitionChecks = null, From 88768be435a86e3ece3e80c5b455fdd81341c04d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Fri, 10 Apr 2020 16:31:40 +0300 Subject: [PATCH 135/334] Update best practices guide --- .../en/Best-Practices/Application-Services.md | 26 ++++++++++++------- .../Best-Practices/Data-Transfer-Objects.md | 1 + 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/docs/en/Best-Practices/Application-Services.md b/docs/en/Best-Practices/Application-Services.md index 0979304931..876105c214 100644 --- a/docs/en/Best-Practices/Application-Services.md +++ b/docs/en/Best-Practices/Application-Services.md @@ -17,17 +17,18 @@ ##### Basic DTO -**Do** define a **basic** DTO for an entity. +**Do** define a **basic** DTO for an aggregate root. -- Include all the **primitive properties** directly on the entity. - - Exception: Can **exclude** properties for **security** reasons (like User.Password). +- Include all the **primitive properties** directly on the aggregate root. + - Exception: Can **exclude** properties for **security** reasons (like `User.Password`). - Include all the **sub collections** of the entity where every item in the collection is a simple **relation DTO**. +- Inherit from one of the **extensible entity DTO** classes for aggregate roots (and entities implement the `IHasExtraProperties`). Example: ```c# [Serializable] -public class IssueDto : FullAuditedEntityDto +public class IssueDto : ExtensibleFullAuditedEntityDto { public string Title { get; set; } public string Text { get; set; } @@ -57,7 +58,7 @@ Example: ````C# [Serializable] -public class IssueWithDetailsDto : FullAuditedEntityDto +public class IssueWithDetailsDto : ExtensibleFullAuditedEntityDto { public string Title { get; set; } public string Text { get; set; } @@ -66,14 +67,14 @@ public class IssueWithDetailsDto : FullAuditedEntityDto } [Serializable] -public class MilestoneDto : EntityDto +public class MilestoneDto : ExtensibleEntityDto { public string Name { get; set; } public bool IsClosed { get; set; } } [Serializable] -public class LabelDto : EntityDto +public class LabelDto : ExtensibleEntityDto { public string Name { get; set; } public string Color { get; set; } @@ -120,6 +121,7 @@ Task> GetListAsync(QuestionListQueryDto queryDto); * **Do** use the `CreateAsync` **method name**. * **Do** get a **specialized input** DTO to create the entity. +* **Do** inherit the DTO class from the `ExtensibleObject` (or any other class implements the `IHasExtraProperties`) to allow to pass extra properties if needed. * **Do** use **data annotations** for input validation. * Share constants between domain wherever possible (via constants defined in the **domain shared** package). * **Do** return **the detailed** DTO for new created entity. @@ -135,10 +137,11 @@ The related **DTO**: ````C# [Serializable] -public class CreateQuestionDto +public class CreateQuestionDto : ExtensibleObject { [Required] - [StringLength(QuestionConsts.MaxTitleLength, MinimumLength = QuestionConsts.MinTitleLength)] + [StringLength(QuestionConsts.MaxTitleLength, + MinimumLength = QuestionConsts.MinTitleLength)] public string Title { get; set; } [StringLength(QuestionConsts.MaxTextLength)] @@ -152,6 +155,7 @@ public class CreateQuestionDto - **Do** use the `UpdateAsync` **method name**. - **Do** get a **specialized input** DTO to update the entity. +- **Do** inherit the DTO class from the `ExtensibleObject` (or any other class implements the `IHasExtraProperties`) to allow to pass extra properties if needed. - **Do** get the Id of the entity as a separated primitive parameter. Do not include to the update DTO. - **Do** use **data annotations** for input validation. - Share constants between domain wherever possible (via constants defined in the **domain shared** package). @@ -200,6 +204,10 @@ This method votes a question and returns the current score of the question. * **Do not** use LINQ/SQL for querying data from database inside the application service methods. It's repository's responsibility to perform LINQ/SQL queries from the data source. +#### Extra Properties + +* **Do** use either `MapExtraPropertiesTo` extension method ([see](Object-Extensions.md)) or configure the object mapper (`MapExtraProperties`) to allow application developers to be able to extend the objects and services. + #### Manipulating / Deleting Entities * **Do** always get all the related entities from repositories to perform the operations on them. diff --git a/docs/en/Best-Practices/Data-Transfer-Objects.md b/docs/en/Best-Practices/Data-Transfer-Objects.md index 0c8580abb7..0fca0e86f2 100644 --- a/docs/en/Best-Practices/Data-Transfer-Objects.md +++ b/docs/en/Best-Practices/Data-Transfer-Objects.md @@ -2,6 +2,7 @@ * **Do** define DTOs in the **application contracts** package. * **Do** inherit from the pre-built **base DTO classes** where possible and necessary (like `EntityDto`, `CreationAuditedEntityDto`, `AuditedEntityDto`, `FullAuditedEntityDto` and so on). + * **Do** inherit from the **extensible DTO** classes for the **aggregate roots** (like `ExtensibleAuditedEntityDto`), because aggregate roots are extensible objects and extra properties are mapped to DTOs in this way. * **Do** define DTO members with **public getter and setter**. * **Do** use **data annotations** for **validation** on the properties of DTOs those are inputs of the service. * **Do** not add any **logic** into DTOs except implementing `IValidatableObject` when necessary. From fd8cd3a001acb86af4cdcfc604ce49a24135c279 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Fri, 10 Apr 2020 16:33:25 +0300 Subject: [PATCH 136/334] remove unused doc --- docs/en/AutoMapper-Integration.md | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 docs/en/AutoMapper-Integration.md diff --git a/docs/en/AutoMapper-Integration.md b/docs/en/AutoMapper-Integration.md deleted file mode 100644 index d197861f25..0000000000 --- a/docs/en/AutoMapper-Integration.md +++ /dev/null @@ -1,3 +0,0 @@ -## AutoMapper Integration - -TODO \ No newline at end of file From 72c679329115c0d99d43eaf5336129fe395b1001 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Fri, 10 Apr 2020 16:37:46 +0300 Subject: [PATCH 137/334] Resolved #3405 Document the object extension system. --- docs/en/Object-To-Object-Mapping.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/docs/en/Object-To-Object-Mapping.md b/docs/en/Object-To-Object-Mapping.md index 52260402f1..b7463607e9 100644 --- a/docs/en/Object-To-Object-Mapping.md +++ b/docs/en/Object-To-Object-Mapping.md @@ -145,6 +145,23 @@ options.AddProfile(validate: true); > If you have multiple profiles and need to enable validation only for a few of them, first use `AddMaps` without validation, then use `AddProfile` for each profile you want to validate. +### Mapping the Object Extensions + +[Object extension system](Object-Extensions.md) allows to define extra properties for existing classes. ABP Framework provides a mapping definition extension to properly map extra properties of two objects. + +````csharp +public class MyProfile : Profile +{ + public MyProfile() + { + CreateMap() + .MapExtraProperties(); + } +} +```` + +It is suggested to use the `MapExtraProperties()` method if both classes are extensible objects (implement the `IHasExtraProperties` interface). See the [object extension document](Object-Extensions.md) for more. + ## Advanced Topics ### IObjectMapper Interface From efaf7fe3e05063fd1568211a412c16f3f79baf45 Mon Sep 17 00:00:00 2001 From: liangshiwei Date: Fri, 10 Apr 2020 21:55:42 +0800 Subject: [PATCH 138/334] Update document --- ...-Application-Modules-Extending-Entities.md | 2 - ...Application-Modules-Overriding-Services.md | 99 +++++++++++++++++++ 2 files changed, 99 insertions(+), 2 deletions(-) diff --git a/docs/zh-Hans/Customizing-Application-Modules-Extending-Entities.md b/docs/zh-Hans/Customizing-Application-Modules-Extending-Entities.md index 4cc73989fc..76a43ea80a 100644 --- a/docs/zh-Hans/Customizing-Application-Modules-Extending-Entities.md +++ b/docs/zh-Hans/Customizing-Application-Modules-Extending-Entities.md @@ -58,8 +58,6 @@ ObjectExtensionManager.Instance ## 创建新实体映射到同一个数据库表/Collection -尽管额外属性方法**易于使用**并且适用于一些场景,但它具有[实体文档](Entities.md)中描述的一些缺点. - 另一个方法是**创建你自己的实体**映射到**同一个数据库库**(对于MongoDB数据库是collection) [应用程序启动模板](Startup-Templates/Application.md)的 `AppUser` 已经实现了这种方法. [EF Core迁移文档](Entity-Framework-Core-Migrations.md)描述了在这些情况下如何实现和管理**EF Core数据库迁移**. 这种方法同样适用于MongoDB,但你不需要处理数据库迁移问题. diff --git a/docs/zh-Hans/Customizing-Application-Modules-Overriding-Services.md b/docs/zh-Hans/Customizing-Application-Modules-Overriding-Services.md index cb40de9bdb..4b98f7cfb2 100644 --- a/docs/zh-Hans/Customizing-Application-Modules-Overriding-Services.md +++ b/docs/zh-Hans/Customizing-Application-Modules-Overriding-Services.md @@ -161,6 +161,105 @@ public class MyIdentityUserManager : IdentityUserManager 控制器,框架服务,视图组件类以及其他类型注册到依赖注入的类都可以像上面的示例那样被重写. +## 扩展数据传输对象 + +你可以如[扩展实体文档](Customizing-Application-Modules-Extending-Entities.md)所述扩展实体. 并使用上面介绍的重写相关服务**使用自定义属性****执行其他业务逻辑**. + +应用程序使用的数据传输对象(**DTO**)同样可扩展. 这样你可以使服务返回其他属性并在UI(或其他客户端)得到其他属性. + +### 示例 + +假设你已经按照[扩展实体文档](Customizing-Application-Modules-Extending-Entities.md)中的说明添加了 `SocialSecurityNumber` 并希望从 `IdentityUserAppService的GetListAsync` 方法获取用户列表时包括此属性. + +你可以使用[对象扩展系统](Object-Extensions.md)将属性添加到 `IdentityUserDto`. 在应用程序启动模板带有的 `YourProjectNameDtoExtensions` 类中编写以下代码: + +````csharp +ObjectExtensionManager.Instance + .AddOrUpdateProperty( + "SocialSecurityNumber" + ); +```` + +这段代码为 `IdentityUserDto` 类添加了 `string` 类型的 `SocialSecurityNumber` 属性. 现在你可以在RREST API客户端调用 `/api/identity/users` HTTP API(内部使用 `IdentityUserAppService`),你会在 `extraProperties` 部分看到 `SocialSecurityNumber` 值. + +````json +{ + "totalCount": 1, + "items": [{ + "tenantId": null, + "userName": "admin", + "name": "admin", + "surname": null, + "email": "admin@abp.io", + "emailConfirmed": false, + "phoneNumber": null, + "phoneNumberConfirmed": false, + "twoFactorEnabled": false, + "lockoutEnabled": true, + "lockoutEnd": null, + "concurrencyStamp": "b4c371a0ab604de28af472fa79c3b70c", + "isDeleted": false, + "deleterId": null, + "deletionTime": null, + "lastModificationTime": "2020-04-09T21:25:47.0740706", + "lastModifierId": null, + "creationTime": "2020-04-09T21:25:46.8308744", + "creatorId": null, + "id": "8edecb8f-1894-a9b1-833b-39f4725db2a3", + "extraProperties": { + "SocialSecurityNumber": "123456789" + } + }] +} +```` + +手动添加了 `123456789` 值到数据库中. + +所有预构建的模块都在DTO中支持额外属性,你可以对其轻松的配置. + +### 定义检查 + +当为实体[定义](Customizing-Application-Modules-Extending-Entities.md)额外的属性时,由于安全性它不会自动出现在所有相关的DTO中. 额外属性可能包含敏感数据并且你可能不想默认公开给客户端. + +因此如果要用于DTO,需要为相应的DTO显式定义相同的属性(如上所述). 如果要允许在用户创建时进行设置还需要为 `IdentityUserCreateDto` 定义. + +如果属性并不是安全敏感,这可能会很枯燥. 对象扩展系统允许你忽略检查定义的属性. 参阅示例: + +````csharp +ObjectExtensionManager.Instance + .AddOrUpdateProperty( + "SocialSecurityNumber", + options => + { + options.MapEfCore(b => b.HasMaxLength(32)); + options.CheckPairDefinitionOnMapping = false; + } + ); +```` + +这是定义实体属性的另一种方法( 有关 `ObjectExtensionManager` 更多信息,请参阅[文档](Object-Extensions.md)). 这次我们设置了 `CheckPairDefinitionOnMapping` 为false,在将实体映射到DTO时会跳过定义检查. + +如果你不喜欢这种方法,但想简单的向多个对象(DTO)添加单个属, `AddOrUpdateProperty` 可以使用类型数组添加额外的属性: + +````csharp +ObjectExtensionManager.Instance + .AddOrUpdateProperty( + new[] + { + typeof(IdentityUserDto), + typeof(IdentityUserCreateDto), + typeof(IdentityUserUpdateDto) + }, + "SocialSecurityNumber" + ); +```` + +### 关于用户界面 + +该系统允许你向实体和DTO添加额外的属性并执行自定义业务代码,但它与用户界面无关. + +参阅 [重写用户界面](Customizing-Application-Modules-Overriding-User-Interface.md) 指南了解关于UI部分. + ## 如何找到服务? [模块文档](Modules/Index.md) 包含了定义的主要服务列表. 另外 你也可以查看[源码](https://github.com/abpframework/abp/tree/dev/modules)找到所有的服务. \ No newline at end of file From 66595e35f55fb1d79e690a2ac8e6b5634c8b05d6 Mon Sep 17 00:00:00 2001 From: liangshiwei Date: Fri, 10 Apr 2020 22:57:10 +0800 Subject: [PATCH 139/334] Translate object extensions document --- docs/zh-Hans/AutoMapper-Integration.md | 3 - .../Best-Practices/Application-Services.md | 18 +- .../Best-Practices/Data-Transfer-Objects.md | 1 + docs/zh-Hans/Object-Extensions.md | 267 ++++++++++++++++++ docs/zh-Hans/Object-To-Object-Mapping.md | 17 ++ docs/zh-Hans/docs-nav.json | 4 + 6 files changed, 301 insertions(+), 9 deletions(-) delete mode 100644 docs/zh-Hans/AutoMapper-Integration.md create mode 100644 docs/zh-Hans/Object-Extensions.md diff --git a/docs/zh-Hans/AutoMapper-Integration.md b/docs/zh-Hans/AutoMapper-Integration.md deleted file mode 100644 index d197861f25..0000000000 --- a/docs/zh-Hans/AutoMapper-Integration.md +++ /dev/null @@ -1,3 +0,0 @@ -## AutoMapper Integration - -TODO \ No newline at end of file diff --git a/docs/zh-Hans/Best-Practices/Application-Services.md b/docs/zh-Hans/Best-Practices/Application-Services.md index 6c8d11b32b..6c681edde1 100644 --- a/docs/zh-Hans/Best-Practices/Application-Services.md +++ b/docs/zh-Hans/Best-Practices/Application-Services.md @@ -17,7 +17,7 @@ ##### 基础DTO -**推荐** 为实体定义一个**基础**DTO. +**推荐** 为聚合根定义一个**基础**DTO. - 直接包含实体中所有的**原始属性**. - 例外: 出于**安全**原因,可以**排除**某些属性(像 `User.Password`). @@ -27,7 +27,7 @@ ```c# [Serializable] -public class IssueDto : FullAuditedEntityDto +public class IssueDto : ExtensibleFullAuditedEntityDto { public string Title { get; set; } public string Text { get; set; } @@ -57,7 +57,7 @@ public class IssueLabelDto ````C# [Serializable] -public class IssueWithDetailsDto : FullAuditedEntityDto +public class IssueWithDetailsDto : ExtensibleFullAuditedEntityDto { public string Title { get; set; } public string Text { get; set; } @@ -66,14 +66,14 @@ public class IssueWithDetailsDto : FullAuditedEntityDto } [Serializable] -public class MilestoneDto : EntityDto +public class MilestoneDto : ExtensibleEntityDto { public string Name { get; set; } public bool IsClosed { get; set; } } [Serializable] -public class LabelDto : EntityDto +public class LabelDto : ExtensibleEntityDto { public string Name { get; set; } public string Color { get; set; } @@ -120,6 +120,7 @@ Task> GetListAsync(QuestionListQueryDto queryDto); * **推荐** 使用 `CreateAsync` 做为**方法名**. * **推荐** 使用**专门的输入DTO**来创建实体. +* **推荐** DTO类从 `ExtensibleObject` 类继承(或任何实现 `ExtensibleObject`的类) 以允许在需要时传递额外的属性. * **推荐** 使用 **data annotations** 进行输入验证. * 尽可能在**领域**之间共享常量(通过**domain shared** package定义的常量). * **推荐** 只需要创建实体的**最少**信息, 但是提供了其他可选属性. @@ -134,7 +135,7 @@ Task CreateAsync(CreateQuestionDto questionDto); ````C# [Serializable] -public class CreateQuestionDto +public class CreateQuestionDto : ExtensibleObject { [Required] [StringLength(QuestionConsts.MaxTitleLength, MinimumLength = QuestionConsts.MinTitleLength)] @@ -151,6 +152,7 @@ public class CreateQuestionDto - **推荐** 使用 `UpdateAsync` 做为**方法名**. - **推荐** 使用**专门的输入DTO**来更新实体. +- **推荐** DTO类从 `ExtensibleObject` 类继承(或任何实现 `ExtensibleObject`的类) 以允许在需要时传递额外的属性. - **推荐** 获取实体的id做为分离的原始参数. 不要包含更新DTO. - **推荐** 使用 **data annotations** 进行输入验证. - 尽可能在**领域**之间共享常量(通过**domain shared** package定义的常量). @@ -199,6 +201,10 @@ Task VoteAsync(Guid id, VoteType type); * **不推荐** 在应用程序服务方法中使用linq/sql查询来自数据库的数据. 让仓储负责从数据源执行linq/sql查询. +#### 额外的属性 + +* **推荐** 使用 `MapExtraPropertiesTo` 扩展方法 ([参阅](Object-Extensions.md)) 或配置对象映射 (`MapExtraProperties`) 以允许应用开发人员能够扩展对象和服务. + #### 操作/删除 实体 * **推荐** 总是从数据库中获取所有的相关实体以对他们执行操作. diff --git a/docs/zh-Hans/Best-Practices/Data-Transfer-Objects.md b/docs/zh-Hans/Best-Practices/Data-Transfer-Objects.md index 0c6017e6e7..29e51501ea 100644 --- a/docs/zh-Hans/Best-Practices/Data-Transfer-Objects.md +++ b/docs/zh-Hans/Best-Practices/Data-Transfer-Objects.md @@ -2,6 +2,7 @@ * **推荐** 在 **application.contracts** 层中定义DTO. * **推荐** 在可能和必要的情况下从预构建的 **基础DTO类** 继承 (如 `EntityDto`, `CreationAuditedEntityDto`, `AuditedEntityDto`, `FullAuditedEntityDto` 等). +* **推荐** 从**聚合根**的**扩展DTO**继承(如 `ExtensibleAuditedEntityDto`), 因为聚合根是可扩展的额外的属性使用这种方式映射到DTO. * **推荐** 定义 **public getter 和 setter** 的DTO成员 . * **推荐** 使用 **data annotations** **验证** service输入DTO的属性. * **不推荐** 在DTO中添加任何 **逻辑**, 在必要的时候可以实现 `IValidatableObject` 接口. diff --git a/docs/zh-Hans/Object-Extensions.md b/docs/zh-Hans/Object-Extensions.md new file mode 100644 index 0000000000..27957708f4 --- /dev/null +++ b/docs/zh-Hans/Object-Extensions.md @@ -0,0 +1,267 @@ +# 对象扩展 + +ABP框架提供了 **实体扩展系统** 允许你 **添加额外属性** 到已存在的对象 **无需修改相关类**. 它允许你扩展[应用程序依赖模块](Modules/Index.md)实现的功能,尤其是当你要扩展[模块定义的实体](Customizing-Application-Modules-Extending-Entities.md)和[DTO](Customizing-Application-Modules-Overriding-Services.md)时. + +> 你自己的对象通常不需要对象扩展系统,因为你可以轻松的添加常规属性到你的类中. + +## IHasExtraProperties 接口 + +这是一个使类可扩展的接口. 它定义了 `Dictionary` 属性: + +````csharp +Dictionary ExtraProperties { get; } +```` + +然后你可以使用此字典添加或获取其他属性. + +### 基类 + +默认以下基类实现了 `IHasExtraProperties` 接口: + +* 由 `AggregateRoot` 类实现 (参阅 [entities](Entities.md)). +* 由 `ExtensibleEntityDto`, `ExtensibleAuditedEntityDto`... [DTO](Data-Transfer-Objects.md)基类实现. +* 由 `ExtensibleObject` 实现, 它是一个简单的基类,任何类型的对象都可以继承. + +如果你的类从这些类继承,那么你的类也是可扩展的,如果没有,你也可以随时手动继承. + +### 基本扩展方法 + +虽然可以直接使用类的 `ExtraProperties` 属性,但建议使用以下扩展方法使用额外属性. + +#### SetProperty + +用于设置额外属性值: + +````csharp +user.SetProperty("Title", "My Title"); +user.SetProperty("IsSuperUser", true); +```` + +`SetProperty` 返回相同的对象, 你可以使用链式编程: + +````csharp +user.SetProperty("Title", "My Title") + .SetProperty("IsSuperUser", true); +```` + +#### GetProperty + +用于读取额外属性的值: + +````csharp +var title = user.GetProperty("Title"); + +if (user.GetProperty("IsSuperUser")) +{ + //... +} +```` + +* `GetProperty` 是一个泛型方法,对象类型做为泛型参数. +* 如果未设置给定的属性,则返回默认值 (`int` 的默认值为 `0` , `bool` 的默认值是 `false` ... 等). + +##### 非基本属性类型 + +如果您的属性类型不是原始类型(int,bool,枚举,字符串等),你需要使用 `GetProperty` 的非泛型版本,它会返回 `object`. + +#### HasProperty + +用于检查对象之前是否设置了属性. + +#### RemoveProperty + +用于从对象中删除属性. 使用此方法代替为属性设置 `null` 值. + +### 一些最佳实践 + +为属性名称使用魔术字符串很危险,因为你很容易输入错误的属性名称-这并不安全; + +* 为你的额外属性名称定义一个常量. +* 使用扩展方法轻松设置你的属性. + +示例: + +````csharp +public static class IdentityUserExtensions +{ + private const string TitlePropertyName = "Title"; + + public static void SetTitle(this IdentityUser user, string title) + { + user.SetProperty(TitlePropertyName, title); + } + + public static string GetTitle(this IdentityUser user) + { + return user.GetProperty(TitlePropertyName); + } +} +```` + +然后, 你可以很容易地设置或获取 `Title` 属性: + +````csharp +user.SetTitle("My Title"); +var title = user.GetTitle(); +```` + +## Object Extension Manager + +你可以为可扩展对象(实现 `IHasExtraProperties`接口)设置任意属性, `ObjectExtensionManager` 用于显式定义可扩展类的其他属性. + +显式定义额外的属性有一些用例: + +* 允许控制如何在对象到对象的映射上处理额外的属性 (参阅下面的部分). +* 允许定义属性的元数据. 例如你可以在使用[EF Core](Entity-Framework-Core.md)时将额外的属性映射到数据库中的表字段. + +> `ObjectExtensionManager` 实现单例模式 (`ObjectExtensionManager.Instance`) ,你应该在应用程序启动之前定义对象扩展. [应用程序启动模板](Startup-Templates/Application.md) 有一些预定义的静态类,可以安全在内部定义对象扩展. + +### AddOrUpdate + +`AddOrUpdate` 是定义对象额外属性或更新对象额外属性的主要方法. + +示例: 为 `IdentityUser` 实体定义额外属性: + +````csharp +ObjectExtensionManager.Instance + .AddOrUpdate(options => + { + options.AddOrUpdateProperty("SocialSecurityNumber"); + options.AddOrUpdateProperty("IsSuperUser"); + } + ); +```` + +### AddOrUpdateProperty + +虽然可以如上所示使用 `AddOrUpdateProperty`, 但如果要定义单个额外的属性,也可以使用快捷的扩展方法: + +````csharp +ObjectExtensionManager.Instance + .AddOrUpdateProperty("SocialSecurityNumber"); +```` + +有时将单个额外属性定义为多种类型是可行的. 你可以使用以下代码,而不是一个一个地定义: + +````csharp +ObjectExtensionManager.Instance + .AddOrUpdateProperty( + new[] + { + typeof(IdentityUserDto), + typeof(IdentityUserCreateDto), + typeof(IdentityUserUpdateDto) + }, + "SocialSecurityNumber" + ); +```` + +#### 属性配置 + +`AddOrUpdateProperty` 还可以为属性定义执行其他配置的操作. + +Example: + +````csharp +ObjectExtensionManager.Instance + .AddOrUpdateProperty( + "SocialSecurityNumber", + options => + { + options.CheckPairDefinitionOnMapping = false; + }); +```` + +> 参阅 "对象到对象映射" 部分了解 `CheckPairDefinitionOnMapping` 选项. + +`options` 有一个名为 `Configuration` 的字典,该字典存储对象扩展定义甚至可以扩展. EF Core使用它来将其他属性映射到数据库中的表字段. 请参阅[扩展实体文档](Customizing-Application-Modules-Extending-Entities.md). + +## 对象到对象映射 + +假设你已向可扩展的实体对象添加了额外的属性并使用了自动[对象到对象的映射](Object-To-Object-Mapping.md)将该实体映射到可扩展的DTO类. 在这种情况下你需要格外小心,因为额外属性可能包含**敏感数据**,这些数据对于客户端不可用. + +本节提供了一些**好的做法**,可以控制对象映射的额外属性。 + +### MapExtraPropertiesTo + +`MapExtraPropertiesTo` 是ABP框架提供的扩展方法,用于以受控方式将额外的属性从一个对象复制到另一个对象. 示例: + +````csharp +identityUser.MapExtraPropertiesTo(identityUserDto); +```` + +`MapExtraPropertiesTo` 需要在**两侧**(本例中是`IdentityUser` 和 `IdentityUserDto`)**定义属性**. 以将值复制到目标对象. 否则即使源对象(在此示例中为 `identityUser` )中确实存在该值,它也不会复制. 有一些重载此限制的方法. + +#### MappingPropertyDefinitionChecks + +`MapExtraPropertiesTo` 获取一个附加参数来控制单个映射操作的定义检查: + +````csharp +identityUser.MapExtraPropertiesTo( + identityUserDto, + MappingPropertyDefinitionChecks.None +); +```` + +> 要小心,因为 `MappingPropertyDefinitionChecks.None` 会复制所有的额外属性而不进行任何检查. `MappingPropertyDefinitionChecks` 枚举还有其他成员. + +如果要完全禁用属性的定义检查,可以在定义额外的属性(或更新现有定义)时进行,如下所示: + +````csharp +ObjectExtensionManager.Instance + .AddOrUpdateProperty( + "SocialSecurityNumber", + options => + { + options.CheckPairDefinitionOnMapping = false; + }); +```` + +#### 忽略属性 + +你可能要在映射操作忽略某些属性: + +````csharp +identityUser.MapExtraPropertiesTo( + identityUserDto, + ignoredProperties: new[] {"MySensitiveProp"} +); +```` + +忽略的属性不会复制到目标对象. + +#### AutoMapper集成 + +如果您使用的是[AutoMapper](https://automapper.org/)库,ABP框架还提供了一种扩展方法来利用上面定义的 `MapExtraPropertiesTo` 方法. + +你可以在映射配置文件中使用 `MapExtraProperties()` 方法. + +````csharp +public class MyProfile : Profile +{ + public MyProfile() + { + CreateMap() + .MapExtraProperties(); + } +} +```` + +它与 `MapExtraPropertiesTo()` 方法具有相同的参数。 + +## Entity Framework Core 数据库映射 + +如果你使用的是EF Core,可以将额外的属性映射到数据库中的表字段. 例: + +````csharp +ObjectExtensionManager.Instance + .AddOrUpdateProperty( + "SocialSecurityNumber", + options => + { + options.MapEfCore(b => b.HasMaxLength(32)); + } + ); +```` + +参阅 [Entity Framework Core 集成文档](Entity-Framework-Core.md) 了解更多内容. \ No newline at end of file diff --git a/docs/zh-Hans/Object-To-Object-Mapping.md b/docs/zh-Hans/Object-To-Object-Mapping.md index 67d580ae54..57b744e0bf 100644 --- a/docs/zh-Hans/Object-To-Object-Mapping.md +++ b/docs/zh-Hans/Object-To-Object-Mapping.md @@ -145,6 +145,23 @@ options.AddProfile(validate: true); > 如果你有多个配置文件,并且只需要为其中几个启用验证,那么首先使用`AddMaps`而不进行验证,然后为你想要验证的每个配置文件使用`AddProfile`. +### 映射对象扩展 + +[对象扩展系统](Object-Extensions.md) 允许为已存在的类定义额外属性. ABP 框架提供了一个映射定义扩展可以正确的映射两个对象的额外属性. + +````csharp +public class MyProfile : Profile +{ + public MyProfile() + { + CreateMap() + .MapExtraProperties(); + } +} +```` + +如果两个类都是可扩展对象(实现了 `IHasExtraProperties` 接口),建议使用 `MapExtraProperties` 方法. 更多信息请参阅[对象扩展文档](Object-Extensions.md). + ## 高级主题 ### IObjectMapper 接口 diff --git a/docs/zh-Hans/docs-nav.json b/docs/zh-Hans/docs-nav.json index f01ce04bc9..893e1c3236 100644 --- a/docs/zh-Hans/docs-nav.json +++ b/docs/zh-Hans/docs-nav.json @@ -140,6 +140,10 @@ { "text": "设置管理", "path": "Settings.md" + }, + { + "text": "对象扩展", + "path": "Object-Extensions.md" } ] }, From 43dedc8e7a604cd31a0610dfaee907180b069350 Mon Sep 17 00:00:00 2001 From: liangshiwei Date: Fri, 10 Apr 2020 22:59:56 +0800 Subject: [PATCH 140/334] Add data-filtering document nav --- docs/zh-Hans/docs-nav.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/zh-Hans/docs-nav.json b/docs/zh-Hans/docs-nav.json index 893e1c3236..59b91f8e4f 100644 --- a/docs/zh-Hans/docs-nav.json +++ b/docs/zh-Hans/docs-nav.json @@ -141,6 +141,10 @@ "text": "设置管理", "path": "Settings.md" }, + { + "text": "数据过滤", + "path": "Data-Filtering.md" + }, { "text": "对象扩展", "path": "Object-Extensions.md" From e26e7ab48d81a91dc143afe2c7f9f836873ff430 Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Fri, 10 Apr 2020 18:35:29 +0300 Subject: [PATCH 141/334] fix mac download error --- .../Building/Steps/ProjectReferenceReplaceStep.cs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/ProjectReferenceReplaceStep.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/ProjectReferenceReplaceStep.cs index 63f63bef19..c7a6cc90f0 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/ProjectReferenceReplaceStep.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/ProjectReferenceReplaceStep.cs @@ -110,7 +110,7 @@ namespace Volo.Abp.Cli.ProjectBuilding.Building.Steps var oldNodeIncludeValue = oldNode.Attributes["Include"].Value; // ReSharper disable once PossibleNullReferenceException : Can not be null because nodes are selected with include attribute filter in previous method - if (oldNodeIncludeValue.Contains(_projectName) && _entries.Any(e=>e.Name.EndsWith(Path.GetFileName(oldNodeIncludeValue)))) + if (oldNodeIncludeValue.Contains(_projectName) && _entries.Any(e=>e.Name.EndsWith(GetProjectNameWithExtensionFromProjectReference(oldNodeIncludeValue)))) { continue; } @@ -125,6 +125,16 @@ namespace Volo.Abp.Cli.ProjectBuilding.Building.Steps return doc.OuterXml; } + private string GetProjectNameWithExtensionFromProjectReference(string oldNodeIncludeValue) + { + if (string.IsNullOrWhiteSpace(oldNodeIncludeValue)) + { + return oldNodeIncludeValue; + } + + return oldNodeIncludeValue.Split('\\', '/').Last(); + } + protected abstract XmlElement GetNewReferenceNode(XmlDocument doc, string oldNodeIncludeValue); From 85f1fc5496144dea0f58f1cc3f450e08f633f6da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Fri, 10 Apr 2020 22:21:28 +0300 Subject: [PATCH 142/334] Create ObjectExtensionPropertyInfoValidationExtensions. --- ...tensionPropertyInfoValidationExtensions.cs | 68 +++++++++++++++++++ ...tExtensionPropertyInfoValidationOptions.cs | 25 +++++++ .../Abp/Validation/AbpValidationModule.cs | 1 + 3 files changed, 94 insertions(+) create mode 100644 framework/src/Volo.Abp.Validation/Volo/Abp/ObjectExtending/ObjectExtensionPropertyInfoValidationExtensions.cs create mode 100644 framework/src/Volo.Abp.Validation/Volo/Abp/ObjectExtending/ObjectExtensionPropertyInfoValidationOptions.cs diff --git a/framework/src/Volo.Abp.Validation/Volo/Abp/ObjectExtending/ObjectExtensionPropertyInfoValidationExtensions.cs b/framework/src/Volo.Abp.Validation/Volo/Abp/ObjectExtending/ObjectExtensionPropertyInfoValidationExtensions.cs new file mode 100644 index 0000000000..926e086d21 --- /dev/null +++ b/framework/src/Volo.Abp.Validation/Volo/Abp/ObjectExtending/ObjectExtensionPropertyInfoValidationExtensions.cs @@ -0,0 +1,68 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using JetBrains.Annotations; + +namespace Volo.Abp.ObjectExtending +{ + public static class ObjectExtensionPropertyInfoValidationExtensions + { + public const string ValidationConfigurationName = "Validation"; + + [NotNull] + public static ObjectExtensionPropertyInfo ConfigureValidation( + [NotNull] this ObjectExtensionPropertyInfo propertyExtension, + [NotNull] Action configureAction) + { + Check.NotNull(propertyExtension, nameof(propertyExtension)); + Check.NotNull(configureAction, nameof(configureAction)); + + configureAction(propertyExtension.GetOrAddValidationConfiguration()); + + return propertyExtension; + } + + [NotNull] + public static ObjectExtensionPropertyInfo AddValidationAttributes( + [NotNull] this ObjectExtensionPropertyInfo propertyExtension, + [NotNull] params ValidationAttribute[] validationAttributes) + { + Check.NotNull(propertyExtension, nameof(propertyExtension)); + Check.NotNullOrEmpty(validationAttributes, nameof(validationAttributes)); + + propertyExtension + .GetOrAddValidationConfiguration() + .ValidationAttributes + .AddRange(validationAttributes); + + return propertyExtension; + } + + [CanBeNull] + public static ObjectExtensionPropertyInfoValidationOptions GetValidationConfigurationOrNull( + [NotNull] this ObjectExtensionPropertyInfo propertyExtension) + { + Check.NotNull(propertyExtension, nameof(propertyExtension)); + + return propertyExtension.Configuration.GetOrDefault(ValidationConfigurationName) + as ObjectExtensionPropertyInfoValidationOptions; + } + + [NotNull] + public static ObjectExtensionPropertyInfoValidationOptions GetOrAddValidationConfiguration( + [NotNull] this ObjectExtensionPropertyInfo propertyExtension) + { + Check.NotNull(propertyExtension, nameof(propertyExtension)); + + var validationConfiguration = propertyExtension.GetValidationConfigurationOrNull(); + + if (validationConfiguration == null) + { + validationConfiguration = new ObjectExtensionPropertyInfoValidationOptions(propertyExtension); + propertyExtension.Configuration[ValidationConfigurationName] = validationConfiguration; + } + + return validationConfiguration; + } + } +} diff --git a/framework/src/Volo.Abp.Validation/Volo/Abp/ObjectExtending/ObjectExtensionPropertyInfoValidationOptions.cs b/framework/src/Volo.Abp.Validation/Volo/Abp/ObjectExtending/ObjectExtensionPropertyInfoValidationOptions.cs new file mode 100644 index 0000000000..e28efc14df --- /dev/null +++ b/framework/src/Volo.Abp.Validation/Volo/Abp/ObjectExtending/ObjectExtensionPropertyInfoValidationOptions.cs @@ -0,0 +1,25 @@ +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using JetBrains.Annotations; + +namespace Volo.Abp.ObjectExtending +{ + public class ObjectExtensionPropertyInfoValidationOptions + { + [NotNull] + public ObjectExtensionPropertyInfo ExtensionProperty { get; } + + [NotNull] + public ObjectExtensionInfo ObjectExtension => ExtensionProperty.ObjectExtension; + + [NotNull] + public List ValidationAttributes { get; } + + public ObjectExtensionPropertyInfoValidationOptions( + [NotNull] ObjectExtensionPropertyInfo extensionProperty) + { + ExtensionProperty = Check.NotNull(extensionProperty, nameof(extensionProperty)); + ValidationAttributes = new List(); + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/AbpValidationModule.cs b/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/AbpValidationModule.cs index ad2be911de..9da6766a5d 100644 --- a/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/AbpValidationModule.cs +++ b/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/AbpValidationModule.cs @@ -18,6 +18,7 @@ namespace Volo.Abp.Validation context.Services.OnRegistred(ValidationInterceptorRegistrar.RegisterIfNeeded); AutoAddObjectValidationContributors(context.Services); } + public override void ConfigureServices(ServiceConfigurationContext context) { Configure(options => From 2a061874b6936ba69e68b823cb4050f767b04a23 Mon Sep 17 00:00:00 2001 From: Arman Ozak Date: Sat, 11 Apr 2020 00:32:22 +0300 Subject: [PATCH 143/334] feat: add an empty modal container component --- .../modal/modal-container.component.ts | 12 +++++++ .../tests/modal-container.component.spec.ts | 34 +++++++++++++++++++ .../src/lib/theme-shared.module.ts | 16 +++++---- 3 files changed, 55 insertions(+), 7 deletions(-) create mode 100644 npm/ng-packs/packages/theme-shared/src/lib/components/modal/modal-container.component.ts create mode 100644 npm/ng-packs/packages/theme-shared/src/lib/tests/modal-container.component.spec.ts diff --git a/npm/ng-packs/packages/theme-shared/src/lib/components/modal/modal-container.component.ts b/npm/ng-packs/packages/theme-shared/src/lib/components/modal/modal-container.component.ts new file mode 100644 index 0000000000..bd24bd84d2 --- /dev/null +++ b/npm/ng-packs/packages/theme-shared/src/lib/components/modal/modal-container.component.ts @@ -0,0 +1,12 @@ +import { Component, ViewChild, ViewContainerRef } from '@angular/core'; + +@Component({ + selector: 'abp-modal-container', + template: ` + + `, +}) +export class ModalContainerComponent { + @ViewChild('container', { static: true, read: ViewContainerRef }) + container: ViewContainerRef; +} diff --git a/npm/ng-packs/packages/theme-shared/src/lib/tests/modal-container.component.spec.ts b/npm/ng-packs/packages/theme-shared/src/lib/tests/modal-container.component.spec.ts new file mode 100644 index 0000000000..4ee654e9bd --- /dev/null +++ b/npm/ng-packs/packages/theme-shared/src/lib/tests/modal-container.component.spec.ts @@ -0,0 +1,34 @@ +import { Component, ComponentFactoryResolver, ComponentRef } from '@angular/core'; +import { createComponentFactory, Spectator } from '@ngneat/spectator/jest'; +import { ModalContainerComponent } from '../components/modal/modal-container.component'; + +describe('ModalContainerComponent', () => { + @Component({ template: '
bar
' }) + class TestComponent {} + + let componentRef: ComponentRef; + let spectator: Spectator; + + const createComponent = createComponentFactory({ + component: ModalContainerComponent, + entryComponents: [TestComponent], + }); + + beforeEach(() => (spectator = createComponent())); + + afterEach(() => componentRef.destroy()); + + describe('#container', () => { + it('should be a ViewContainerRef', () => { + let foo = document.querySelector('div.foo'); + expect(foo).toBeNull(); + + const cfResolver = spectator.get(ComponentFactoryResolver); + const factory = cfResolver.resolveComponentFactory(TestComponent); + componentRef = spectator.component.container.createComponent(factory); + + foo = document.querySelector('div.foo'); + expect(foo.textContent).toBe('bar'); + }); + }); +}); diff --git a/npm/ng-packs/packages/theme-shared/src/lib/theme-shared.module.ts b/npm/ng-packs/packages/theme-shared/src/lib/theme-shared.module.ts index 15ba212944..f23410d6d0 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/theme-shared.module.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/theme-shared.module.ts @@ -1,4 +1,4 @@ -import { CoreModule, noop, LazyLoadService } from '@abp/ng.core'; +import { CoreModule, LazyLoadService, noop } from '@abp/ng.core'; import { DatePipe } from '@angular/common'; import { APP_INITIALIZER, Injector, ModuleWithProviders, NgModule } from '@angular/core'; import { NgbDateParserFormatter, NgbPaginationModule } from '@ng-bootstrap/ng-bootstrap'; @@ -9,23 +9,24 @@ import { ChartComponent } from './components/chart/chart.component'; import { ConfirmationComponent } from './components/confirmation/confirmation.component'; import { HttpErrorWrapperComponent } from './components/http-error-wrapper/http-error-wrapper.component'; import { LoaderBarComponent } from './components/loader-bar/loader-bar.component'; +import { LoadingComponent } from './components/loading/loading.component'; +import { ModalContainerComponent } from './components/modal/modal-container.component'; import { ModalComponent } from './components/modal/modal.component'; +import { PaginationComponent } from './components/pagination/pagination.component'; import { SortOrderIconComponent } from './components/sort-order-icon/sort-order-icon.component'; import { TableEmptyMessageComponent } from './components/table-empty-message/table-empty-message.component'; -import { ToastContainerComponent } from './components/toast-container/toast-container.component'; import { TableComponent } from './components/table/table.component'; +import { ToastContainerComponent } from './components/toast-container/toast-container.component'; import { ToastComponent } from './components/toast/toast.component'; import styles from './constants/styles'; +import { LoadingDirective } from './directives/loading.directive'; import { TableSortDirective } from './directives/table-sort.directive'; import { ErrorHandler } from './handlers/error.handler'; import { RootParams } from './models/common'; +import { THEME_SHARED_APPEND_CONTENT } from './tokens/append-content.token'; import { httpErrorConfigFactory, HTTP_ERROR_CONFIG } from './tokens/http-error.token'; import { DateParserFormatter } from './utils/date-parser-formatter'; import { chartJsLoaded$ } from './utils/widget-utils'; -import { PaginationComponent } from './components/pagination/pagination.component'; -import { LoadingComponent } from './components/loading/loading.component'; -import { LoadingDirective } from './directives/loading.directive'; -import { THEME_SHARED_APPEND_CONTENT } from './tokens/append-content.token'; /** * @@ -54,6 +55,7 @@ export function appendScript(injector: Injector) { LoaderBarComponent, LoadingComponent, ModalComponent, + ModalContainerComponent, PaginationComponent, TableComponent, TableEmptyMessageComponent, @@ -81,7 +83,7 @@ export function appendScript(injector: Injector) { TableSortDirective, ], providers: [DatePipe], - entryComponents: [HttpErrorWrapperComponent, LoadingComponent], + entryComponents: [HttpErrorWrapperComponent, LoadingComponent, ModalContainerComponent], }) export class ThemeSharedModule { constructor(private errorHandler: ErrorHandler) {} From 146c8631606a0f0b45547a996ce2a36c032907c5 Mon Sep 17 00:00:00 2001 From: Arman Ozak Date: Sat, 11 Apr 2020 00:33:49 +0300 Subject: [PATCH 144/334] feat: add a service that projects to modal container --- .../theme-shared/src/lib/services/index.ts | 1 + .../src/lib/services/modal.service.ts | 47 ++++++++++ .../src/lib/tests/modal.service.spec.ts | 87 +++++++++++++++++++ 3 files changed, 135 insertions(+) create mode 100644 npm/ng-packs/packages/theme-shared/src/lib/services/modal.service.ts create mode 100644 npm/ng-packs/packages/theme-shared/src/lib/tests/modal.service.spec.ts diff --git a/npm/ng-packs/packages/theme-shared/src/lib/services/index.ts b/npm/ng-packs/packages/theme-shared/src/lib/services/index.ts index c53455a433..c363a56894 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/services/index.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/services/index.ts @@ -1,2 +1,3 @@ export * from './confirmation.service'; +export * from './modal.service'; export * from './toaster.service'; diff --git a/npm/ng-packs/packages/theme-shared/src/lib/services/modal.service.ts b/npm/ng-packs/packages/theme-shared/src/lib/services/modal.service.ts new file mode 100644 index 0000000000..ac481f68ea --- /dev/null +++ b/npm/ng-packs/packages/theme-shared/src/lib/services/modal.service.ts @@ -0,0 +1,47 @@ +import { ContentProjectionService, PROJECTION_STRATEGY } from '@abp/ng.core'; +import { ComponentRef, Injectable, TemplateRef, ViewContainerRef } from '@angular/core'; +import { ModalContainerComponent } from '../components/modal/modal-container.component'; + +@Injectable({ + providedIn: 'root', +}) +export class ModalService { + private containerComponentRef: ComponentRef; + + constructor(private contentProjectionService: ContentProjectionService) { + this.setContainer(); + } + + private setContainer() { + this.containerComponentRef = this.contentProjectionService.projectContent( + PROJECTION_STRATEGY.AppendComponentToBody(ModalContainerComponent), + ); + + this.containerComponentRef.changeDetectorRef.detectChanges(); + } + + clearModal() { + this.getContainer().clear(); + this.detectChanges(); + } + + detectChanges() { + this.containerComponentRef.changeDetectorRef.detectChanges(); + } + + getContainer(): ViewContainerRef { + return this.containerComponentRef.instance.container; + } + + renderTemplate(template: TemplateRef, context?: T) { + const containerRef = this.getContainer(); + + const strategy = PROJECTION_STRATEGY.ProjectTemplateToContainer( + template, + containerRef, + context, + ); + + this.contentProjectionService.projectContent(strategy); + } +} diff --git a/npm/ng-packs/packages/theme-shared/src/lib/tests/modal.service.spec.ts b/npm/ng-packs/packages/theme-shared/src/lib/tests/modal.service.spec.ts new file mode 100644 index 0000000000..e1a2e8bf51 --- /dev/null +++ b/npm/ng-packs/packages/theme-shared/src/lib/tests/modal.service.spec.ts @@ -0,0 +1,87 @@ +import { Component, TemplateRef, ViewChild } from '@angular/core'; +import { createComponentFactory, Spectator } from '@ngneat/spectator/jest'; +import { ModalContainerComponent } from '../components/modal/modal-container.component'; +import { ModalService } from '../services'; + +describe('ModalContainerComponent', () => { + @Component({ + template: ` + +
bar
+
+ `, + }) + class TestComponent { + @ViewChild('ref', { static: true }) + template: TemplateRef; + + constructor(public service: ModalService) {} + } + + let spectator: Spectator; + let service: ModalService; + + const createComponent = createComponentFactory({ + component: TestComponent, + entryComponents: [ModalContainerComponent], + }); + + beforeEach(() => { + spectator = createComponent(); + service = spectator.component.service; + }); + + afterEach(() => { + service.getContainer().clear(); + service['containerComponentRef'].changeDetectorRef.detectChanges(); + service['containerComponentRef'].destroy(); + }); + + describe('#getContainer', () => { + it('should return the ViewContainerRef of ModalContainerComponent', () => { + let foo = document.querySelector('div.foo'); + expect(foo).toBeNull(); + + const containerRef = service.getContainer(); + const embeddedViewRef = containerRef.createEmbeddedView(spectator.component.template); + + foo = document.querySelector('div.foo'); + expect(foo).toBe(embeddedViewRef.rootNodes[0]); + expect(foo.textContent).toBe('bar'); + }); + }); + + describe('#renderTemplate', () => { + it('should render given template using the ViewContainerRef of ModalContainerComponent', () => { + let foo = document.querySelector('div.foo'); + expect(foo).toBeNull(); + + service.renderTemplate(spectator.component.template); + + foo = document.querySelector('div.foo'); + expect(foo.textContent).toBe('bar'); + }); + }); + + describe('#detectChanges', () => { + it('should call detectChanges on the containerComponentRef', () => { + const spy = jest.spyOn(service['containerComponentRef'].changeDetectorRef, 'detectChanges'); + + service.detectChanges(); + + expect(spy).toHaveBeenCalledTimes(1); + }); + }); + + describe('#clearModal', () => { + it('should call clear on the ViewContainerRef and detectChanges', () => { + const clear = jest.spyOn(service.getContainer(), 'clear'); + const detectChanges = jest.spyOn(service, 'detectChanges'); + + service.clearModal(); + + expect(clear).toHaveBeenCalledTimes(1); + expect(detectChanges).toHaveBeenCalledTimes(1); + }); + }); +}); From 0cf7d1d261661776d4ad62927b8586f9f0e6c0a7 Mon Sep 17 00:00:00 2001 From: Arman Ozak Date: Sat, 11 Apr 2020 00:34:09 +0300 Subject: [PATCH 145/334] feat: use modal service to project modal --- .../lib/components/modal/modal.component.html | 67 +++--- .../lib/components/modal/modal.component.ts | 60 +++-- .../src/lib/tests/modal.component.spec.ts | 224 ++++++++++++------ 3 files changed, 236 insertions(+), 115 deletions(-) diff --git a/npm/ng-packs/packages/theme-shared/src/lib/components/modal/modal.component.html b/npm/ng-packs/packages/theme-shared/src/lib/components/modal/modal.component.html index c3168bad92..b37f5b6ce3 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/components/modal/modal.component.html +++ b/npm/ng-packs/packages/theme-shared/src/lib/components/modal/modal.component.html @@ -1,34 +1,43 @@ -