Browse Source

Merge remote-tracking branch 'origin/master'

pull/628/head
Marcelo Mohr Maciel 7 years ago
parent
commit
5a2c381d7f
  1. BIN
      abp_io/src/Volo.AbpWebSite.Web/wwwroot/assets/abp_nupkg.png
  2. 10
      common.props
  3. 4
      docs/en/AspNetCore/Bundling-Minification.md
  4. 4
      docs/en/Localization.md
  5. 2
      docs/en/Module-Development-Basics.md
  6. 8
      docs/en/Multi-Tenancy.md
  7. 4
      docs/en/Virtual-File-System.md
  8. 4
      docs/zh-Hans/AspNetCore/Bundling-Minification.md
  9. 4
      docs/zh-Hans/Localization.md
  10. 2
      docs/zh-Hans/Module-Development-Basics.md
  11. 8
      docs/zh-Hans/Multi-Tenancy.md
  12. 4
      docs/zh-Hans/Virtual-File-System.md
  13. 2
      framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/AbpAspNetCoreMultiTenancyModule.cs
  14. 2
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/AbpAspNetCoreMvcUiBootstrapModule.cs
  15. 1
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/SelectItems.cs
  16. 18
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/Anchor/AnchorJsScriptBundleContributor.cs
  17. 15
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/Clipboard/ClipboardScriptBundleContributor.cs
  18. 15
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/MalihuCustomScrollbar/MalihuCustomScrollbarPluginScriptBundleContributor.cs
  19. 15
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/MalihuCustomScrollbar/MalihuCustomScrollbarPluginStyleBundleContributor.cs
  20. 15
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/Popper/PopperJsScriptBundleContributor.cs
  21. 8
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/AbpAspNetCoreMvcUIBasicThemeModule.cs
  22. 4
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/AbpAspNetCoreMvcUiThemeSharedModule.cs
  23. 4
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/Bundling/SharedThemeGlobalScriptContributor.cs
  24. 7
      framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcModule.cs
  25. 8
      framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpController.cs
  26. 2
      framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/AbpAspNetCoreModule.cs
  27. 53
      framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/DependencyInjection/HttpContextServiceScopeFactory.cs
  28. 2
      framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/AbpAuthorizationModule.cs
  29. 58
      framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/BackgroundJobExecuter.cs
  30. 8
      framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/JobExecutionContext.cs
  31. 13
      framework/src/Volo.Abp.BackgroundJobs.HangFire/Volo/Abp/BackgroundJobs/Hangfire/HangfireBackgroundJobManager.cs
  32. 19
      framework/src/Volo.Abp.BackgroundJobs.HangFire/Volo/Abp/BackgroundJobs/Hangfire/HangfireJobExecutionAdapter.cs
  33. 46
      framework/src/Volo.Abp.BackgroundJobs.RabbitMQ/Volo/Abp/BackgroundJobs/RabbitMQ/JobQueue.cs
  34. 74
      framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/BackgroundJobWorker.cs
  35. 16
      framework/src/Volo.Abp.Caching/Volo/Abp/Caching/DistributedCache.cs
  36. 4
      framework/src/Volo.Abp.Caching/Volo/Abp/Caching/IDistributedCache.cs
  37. 13
      framework/src/Volo.Abp.Core/System/AbpStringExtensions.cs
  38. 23
      framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/DefaultServiceScopeFactory.cs
  39. 9
      framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/IHybridServiceScopeFactory.cs
  40. 23
      framework/src/Volo.Abp.Core/Volo/Abp/IO/FileHelper.cs
  41. 2
      framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/AbpDddApplicationModule.cs
  42. 2
      framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/EntityChangeEventHelper.cs
  43. 6
      framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/AbpEmailingModule.cs
  44. 8
      framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContext.cs
  45. 2
      framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpEntityFrameworkCoreModule.cs
  46. 13
      framework/src/Volo.Abp.EventBus.Distributed.RabbitMQ/Volo/Abp/EventBus/Distributed/RabbitMq/RabbitMqDistributedEventBus.cs
  47. 12
      framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/AbpEventBusModule.cs
  48. 4
      framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/ActionEventHandler.cs
  49. 0
      framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/DistributedEventBusOptions.cs
  50. 13
      framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/IDistributedEventBus.cs
  51. 22
      framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/LocalDistributedEventBus.cs
  52. 4
      framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/NullDistributedEventBus.cs
  53. 18
      framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/EventBusBase.cs
  54. 114
      framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/IEventBus.cs
  55. 17
      framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/IEventHandler.cs
  56. 25
      framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/IEventPublisher.cs
  57. 111
      framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/IEventSubscriber.cs
  58. 8
      framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/IocEventHandlerFactory.cs
  59. 11
      framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Local/ILocalEventBus.cs
  60. 13
      framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Local/ILocalEventHandler.cs
  61. 14
      framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Local/LocalEventBus.cs
  62. 4
      framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Local/NullLocalEventBus.cs
  63. 2
      framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/TransientEventHandlerFactory.cs
  64. 2
      framework/src/Volo.Abp.Http/Volo/Abp/Http/AbpHttpModule.cs
  65. 25
      framework/src/Volo.Abp.Http/Volo/Abp/Http/MimeTypes.cs
  66. 4
      framework/src/Volo.Abp.Localization/Volo.Abp.Localization.csproj
  67. 6
      framework/src/Volo.Abp.Localization/Volo/Abp/Localization/AbpLocalizationModule.cs
  68. 2
      framework/src/Volo.Abp.MultiTenancy.Abstractions/Volo/Abp/MultiTenancy/AbpMultiTenancyAbstractionsModule.cs
  69. 2
      framework/src/Volo.Abp.TestBase/Volo/Abp/AbpIntegratedTest.cs
  70. 8
      framework/src/Volo.Abp.TestBase/Volo/Abp/AbpTestBaseModule.cs
  71. 13
      framework/src/Volo.Abp.TestBase/Volo/Abp/Testing/Utils/ITestCounter.cs
  72. 43
      framework/src/Volo.Abp.TestBase/Volo/Abp/Testing/Utils/TestCounter.cs
  73. 4
      framework/src/Volo.Abp.UI/Volo.Abp.UI.csproj
  74. 4
      framework/src/Volo.Abp.UI/Volo/Abp/Ui/AbpUiModule.cs
  75. 4
      framework/src/Volo.Abp.Uow/Volo/Abp/Uow/ChildUnitOfWork.cs
  76. 4
      framework/src/Volo.Abp.Uow/Volo/Abp/Uow/IUnitOfWork.cs
  77. 22
      framework/src/Volo.Abp.Uow/Volo/Abp/Uow/UnitOfWork.cs
  78. 7
      framework/src/Volo.Abp.Uow/Volo/Abp/Uow/UnitOfWorkManager.cs
  79. 2
      framework/src/Volo.Abp.Validation/Volo/Abp/Validation/AbpValidationException.cs
  80. 2
      framework/src/Volo.Abp.Validation/Volo/Abp/Validation/IHasValidationErrors.cs
  81. 2
      framework/test/Volo.Abp.AspNetCore.MultiTenancy.Tests/Volo/Abp/AspNetCore/App/AppModule.cs
  82. 4
      framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo.Abp.AspNetCore.Mvc.Tests.csproj
  83. 16
      framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcTestModule.cs
  84. 3
      framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Localization/Resource/en.json
  85. 3
      framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Localization/Resource/tr.json
  86. 12
      framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Validation/ValidationTestController_Tests.cs
  87. 4
      framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/publish-ignore.json
  88. 4
      framework/test/Volo.Abp.AspNetCore.Mvc.Versioning.Tests/Volo/Abp/AspNetCore/Mvc/Versioning/AbpAspNetCoreMvcVersioningTestModule.cs
  89. 2
      framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/AbpAuthorizationTestModule.cs
  90. 2
      framework/test/Volo.Abp.AutoMapper.Tests/Volo/Abp/AutoMapper/AutoMapper_ConfigurationValidation_Tests.cs
  91. 2
      framework/test/Volo.Abp.AutoMapper.Tests/Volo/Abp/AutoMapper/AutofacTestModule.cs
  92. 1
      framework/test/Volo.Abp.BackgroundJobs.Tests/Volo/Abp/BackgroundJobs/BackgroundJobExecuter_Tests.cs
  93. 8
      framework/test/Volo.Abp.Core.Tests/System/StringExtensions_Tests.cs
  94. 41
      framework/test/Volo.Abp.Core.Tests/Volo/Abp/DependencyInjection/HybridServiceScopeFactory_Tests.cs
  95. 15
      framework/test/Volo.Abp.Core.Tests/Volo/Abp/IO/FileHelper_Tests.cs
  96. 2
      framework/test/Volo.Abp.Data.Tests/Volo/Abp/Data/ConnectionStringResolver_Tests.cs
  97. 4
      framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/AbpEmailingTestModule.cs
  98. 2
      framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/AbpEntityFrameworkCoreTestModule.cs
  99. 7
      framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/EntityFrameworkCoreTestBase.cs
  100. 9
      framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/Uow/Uow_Completed_Tests.cs

BIN
abp_io/src/Volo.AbpWebSite.Web/wwwroot/assets/abp_nupkg.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

10
common.props

@ -1,13 +1,13 @@
<Project>
<PropertyGroup>
<LangVersion>latest</LangVersion>
<Version>0.8.0</Version>
<Version>0.9.0</Version>
<NoWarn>$(NoWarn);CS1591</NoWarn>
<PackageIconUrl>http://www.aspnetboilerplate.com/images/abp_nupkg.png</PackageIconUrl>
<PackageProjectUrl>http://abp.io</PackageProjectUrl>
<PackageLicenseUrl>https://github.com/volosoft/abp/blob/master/LICENSE</PackageLicenseUrl>
<PackageIconUrl>https://abp.io/assets/abp_nupkg.png</PackageIconUrl>
<PackageProjectUrl>https://abp.io</PackageProjectUrl>
<PackageLicenseUrl>https://github.com/abpframework/abp/blob/master/LICENSE</PackageLicenseUrl>
<RepositoryType>git</RepositoryType>
<RepositoryUrl>https://github.com/volosoft/abp/</RepositoryUrl>
<RepositoryUrl>https://github.com/abpframework/abp/</RepositoryUrl>
</PropertyGroup>
<ItemGroup>

4
docs/en/AspNetCore/Bundling-Minification.md

@ -114,7 +114,7 @@ public class MyWebModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.Configure<BundlingOptions>(options =>
Configure<BundlingOptions>(options =>
{
options
.ScriptBundles
@ -152,7 +152,7 @@ public class MyWebExtensionModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.Configure<BundlingOptions>(options =>
Configure<BundlingOptions>(options =>
{
options
.ScriptBundles

4
docs/en/Localization.md

@ -46,12 +46,12 @@ public class MyModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.Configure<VirtualFileSystemOptions>(options =>
Configure<VirtualFileSystemOptions>(options =>
{
options.FileSets.AddEmbedded<MyModule>();
});
context.Services.Configure<AbpLocalizationOptions>(options =>
Configure<AbpLocalizationOptions>(options =>
{
options.Resources
.Add<TestResource>("en")

2
docs/en/Module-Development-Basics.md

@ -42,7 +42,7 @@ public class BlogModule : AbpModule
public override void ConfigureServices(ServiceConfigurationContext context)
{
//Configure default connection string for the application
context.Services.Configure<DbConnectionOptions>(options =>
Configure<DbConnectionOptions>(options =>
{
options.ConnectionStrings.Default = "......";
});

8
docs/en/Multi-Tenancy.md

@ -138,7 +138,7 @@ namespace MyCompany.MyProject
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.Configure<TenantResolveOptions>(options =>
Configure<TenantResolveOptions>(options =>
{
options.TenantResolvers.Add(new MyCustomTenantResolver());
});
@ -194,7 +194,7 @@ namespace MyCompany.MyProject
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.Configure<ConfigurationTenantStoreOptions>(options =>
Configure<ConfigurationTenantStoreOptions>(options =>
{
options.Tenants = new[]
{
@ -240,7 +240,7 @@ namespace MyCompany.MyProject
{
var configuration = BuildConfiguration();
context.Services.Configure<ConfigurationTenantStoreOptions>(configuration);
Configure<ConfigurationTenantStoreOptions>(configuration);
}
private static IConfigurationRoot BuildConfiguration()
@ -361,7 +361,7 @@ namespace MyCompany.MyProject
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.Configure<TenantResolveOptions>(options =>
Configure<TenantResolveOptions>(options =>
{
//Subdomain format: {0}.mydomain.com (adding as the highest priority resolver)
options.TenantResolvers.Insert(0, new DomainTenantResolver("{0}.mydomain.com"));

4
docs/en/Virtual-File-System.md

@ -58,7 +58,7 @@ namespace MyCompany.MyProject
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.Configure<VirtualFileSystemOptions>(options =>
Configure<VirtualFileSystemOptions>(options =>
{
//Register all embedded files of this assembly to the virtual file system
options.FileSets.AddEmbedded<MyModule>();
@ -122,7 +122,7 @@ public class MyWebAppModule : AbpModule
if (hostingEnvironment.IsDevelopment()) //only for development time
{
context.Services.Configure<VirtualFileSystemOptions>(options =>
Configure<VirtualFileSystemOptions>(options =>
{
//ReplaceEmbeddedByPyhsical gets the root folder of the MyModule project
options.FileSets.ReplaceEmbeddedByPyhsical<MyModule>(

4
docs/zh-Hans/AspNetCore/Bundling-Minification.md

@ -115,7 +115,7 @@ public class MyWebModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.Configure<BundlingOptions>(options =>
Configure<BundlingOptions>(options =>
{
options
.ScriptBundles
@ -153,7 +153,7 @@ public class MyWebExtensionModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.Configure<BundlingOptions>(options =>
Configure<BundlingOptions>(options =>
{
options
.ScriptBundles

4
docs/zh-Hans/Localization.md

@ -46,12 +46,12 @@ public class MyModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.Configure<VirtualFileSystemOptions>(options =>
Configure<VirtualFileSystemOptions>(options =>
{
options.FileSets.AddEmbedded<MyModule>();
});
context.Services.Configure<AbpLocalizationOptions>(options =>
Configure<AbpLocalizationOptions>(options =>
{
options.Resources
.Add<TestResource>("en")

2
docs/zh-Hans/Module-Development-Basics.md

@ -42,7 +42,7 @@ public class BlogModule : AbpModule
public override void ConfigureServices(ServiceConfigurationContext context)
{
//为应用程序配置默认的连接字符串
context.Services.Configure<DbConnectionOptions>(options =>
Configure<DbConnectionOptions>(options =>
{
options.ConnectionStrings.Default = "......";
});

8
docs/zh-Hans/Multi-Tenancy.md

@ -139,7 +139,7 @@ namespace MyCompany.MyProject
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.Configure<TenantResolveOptions>(options =>
Configure<TenantResolveOptions>(options =>
{
options.TenantResolvers.Add(new MyCustomTenantResolver());
});
@ -194,7 +194,7 @@ namespace MyCompany.MyProject
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.Configure<ConfigurationTenantStoreOptions>(options =>
Configure<ConfigurationTenantStoreOptions>(options =>
{
options.Tenants = new[]
{
@ -240,7 +240,7 @@ namespace MyCompany.MyProject
{
var configuration = BuildConfiguration();
context.Services.Configure<ConfigurationTenantStoreOptions>(configuration);
Configure<ConfigurationTenantStoreOptions>(configuration);
}
private static IConfigurationRoot BuildConfiguration()
@ -362,7 +362,7 @@ namespace MyCompany.MyProject
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.Configure<TenantResolveOptions>(options =>
Configure<TenantResolveOptions>(options =>
{
//子域名格式: {0}.mydomain.com (作为最高优先级解析器添加)
options.TenantResolvers.Insert(0, new DomainTenantResolver("{0}.mydomain.com"));

4
docs/zh-Hans/Virtual-File-System.md

@ -59,7 +59,7 @@ namespace MyCompany.MyProject
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.Configure<VirtualFileSystemOptions>(options =>
Configure<VirtualFileSystemOptions>(options =>
{
//Register all embedded files of this assembly to the virtual file system
options.FileSets.AddEmbedded<MyModule>();
@ -123,7 +123,7 @@ public class MyWebAppModule : AbpModule
if (hostingEnvironment.IsDevelopment()) //only for development time
{
context.Services.Configure<VirtualFileSystemOptions>(options =>
Configure<VirtualFileSystemOptions>(options =>
{
//ReplaceEmbeddedByPyhsical gets the root folder of the MyModule project
options.FileSets.ReplaceEmbeddedByPyhsical<MyModule>(

2
framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/AbpAspNetCoreMultiTenancyModule.cs

@ -12,7 +12,7 @@ namespace Volo.Abp.AspNetCore.MultiTenancy
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.Configure<TenantResolveOptions>(options =>
Configure<TenantResolveOptions>(options =>
{
options.TenantResolvers.Add(new QueryStringTenantResolveContributer());
options.TenantResolvers.Add(new RouteTenantResolveContributer());

2
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/AbpAspNetCoreMvcUiBootstrapModule.cs

@ -9,7 +9,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.Configure<VirtualFileSystemOptions>(options =>
Configure<VirtualFileSystemOptions>(options =>
{
options.FileSets.AddEmbedded<AbpAspNetCoreMvcUiBootstrapModule>("Volo.Abp.AspNetCore.Mvc.UI.Bootstrap");
});

1
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/SelectItems.cs

@ -31,7 +31,6 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form
}
}
// ReSharper disable once AssignNullToNotNullAttribute
var selectItems = (properties.First().Model as IEnumerable<SelectListItem>).ToList();
return selectItems;

18
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/Anchor/AnchorJsScriptBundleContributor.cs

@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Text;
using Volo.Abp.AspNetCore.Mvc.UI.Bundling;
using Volo.Abp.AspNetCore.Mvc.UI.Packages.JQuery;
using Volo.Abp.Modularity;
namespace Volo.Abp.AspNetCore.Mvc.UI.Packages.Anchor
{
[DependsOn(typeof(JQueryScriptContributor))]
public class AnchorJsScriptBundleContributor : BundleContributor
{
public override void ConfigureBundle(BundleConfigurationContext context)
{
context.Files.AddIfNotContains("/libs/anchor-js/anchor.js");
}
}
}

15
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/Clipboard/ClipboardScriptBundleContributor.cs

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Text;
using Volo.Abp.AspNetCore.Mvc.UI.Bundling;
namespace Volo.Abp.AspNetCore.Mvc.UI.Packages.Clipboard
{
public class ClipboardScriptBundleContributor : BundleContributor
{
public override void ConfigureBundle(BundleConfigurationContext context)
{
context.Files.AddIfNotContains("/libs/clipboard/clipboard.js");
}
}
}

15
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/MalihuCustomScrollbar/MalihuCustomScrollbarPluginScriptBundleContributor.cs

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Text;
using Volo.Abp.AspNetCore.Mvc.UI.Bundling;
namespace Volo.Abp.AspNetCore.Mvc.UI.Packages.MalihuCustomScrollbar
{
public class MalihuCustomScrollbarPluginScriptBundleContributor : BundleContributor
{
public override void ConfigureBundle(BundleConfigurationContext context)
{
context.Files.AddIfNotContains("/libs/malihu-custom-scrollbar-plugin/jquery.mCustomScrollbar.concat.min.js");
}
}
}

15
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/MalihuCustomScrollbar/MalihuCustomScrollbarPluginStyleBundleContributor.cs

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Text;
using Volo.Abp.AspNetCore.Mvc.UI.Bundling;
namespace Volo.Abp.AspNetCore.Mvc.UI.Packages.MalihuCustomScrollbar
{
public class MalihuCustomScrollbarPluginStyleBundleContributor : BundleContributor
{
public override void ConfigureBundle(BundleConfigurationContext context)
{
context.Files.AddIfNotContains("/libs/malihu-custom-scrollbar-plugin/jquery.mCustomScrollbar.css");
}
}
}

15
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/Popper/PopperJsScriptBundleContributor.cs

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Text;
using Volo.Abp.AspNetCore.Mvc.UI.Bundling;
namespace Volo.Abp.AspNetCore.Mvc.UI.Packages.Popper
{
public class PopperJsScriptBundleContributor : BundleContributor
{
public override void ConfigureBundle(BundleConfigurationContext context)
{
context.Files.AddIfNotContains("/libs/popper.js/popper.min.js");
}
}
}

8
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/AbpAspNetCoreMvcUIBasicThemeModule.cs

@ -18,7 +18,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.Configure<ThemingOptions>(options =>
Configure<ThemingOptions>(options =>
{
options.Themes.Add<BasicTheme>();
@ -28,17 +28,17 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic
}
});
context.Services.Configure<VirtualFileSystemOptions>(options =>
Configure<VirtualFileSystemOptions>(options =>
{
options.FileSets.AddEmbedded<AbpAspNetCoreMvcUiBasicThemeModule>("Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic");
});
context.Services.Configure<ToolbarOptions>(options =>
Configure<ToolbarOptions>(options =>
{
options.Contributors.Add(new BasicThemeMainTopToolbarContributor());
});
context.Services.Configure<BundlingOptions>(options =>
Configure<BundlingOptions>(options =>
{
options
.StyleBundles

4
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/AbpAspNetCoreMvcUiThemeSharedModule.cs

@ -16,12 +16,12 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.Configure<VirtualFileSystemOptions>(options =>
Configure<VirtualFileSystemOptions>(options =>
{
options.FileSets.AddEmbedded<AbpAspNetCoreMvcUiThemeSharedModule>("Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared");
});
context.Services.Configure<BundlingOptions>(options =>
Configure<BundlingOptions>(options =>
{
options
.StyleBundles

4
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/Bundling/SharedThemeGlobalScriptContributor.cs

@ -1,10 +1,14 @@
using Volo.Abp.AspNetCore.Mvc.UI.Bundling;
using Volo.Abp.AspNetCore.Mvc.UI.Packages.Anchor;
using Volo.Abp.AspNetCore.Mvc.UI.Packages.Bootstrap;
using Volo.Abp.AspNetCore.Mvc.UI.Packages.Clipboard;
using Volo.Abp.AspNetCore.Mvc.UI.Packages.DatatablesNetBs4;
using Volo.Abp.AspNetCore.Mvc.UI.Packages.JQuery;
using Volo.Abp.AspNetCore.Mvc.UI.Packages.JQueryForm;
using Volo.Abp.AspNetCore.Mvc.UI.Packages.JQueryValidationUnobtrusive;
using Volo.Abp.AspNetCore.Mvc.UI.Packages.Lodash;
using Volo.Abp.AspNetCore.Mvc.UI.Packages.MalihuCustomScrollbar;
using Volo.Abp.AspNetCore.Mvc.UI.Packages.Popper;
using Volo.Abp.AspNetCore.Mvc.UI.Packages.Select2;
using Volo.Abp.AspNetCore.Mvc.UI.Packages.SweetAlert;
using Volo.Abp.AspNetCore.Mvc.UI.Packages.Timeago;

7
framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcModule.cs

@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.ApplicationParts;
using Microsoft.AspNetCore.Mvc.Razor;
using Microsoft.Extensions.DependencyInjection;
@ -56,14 +57,14 @@ namespace Volo.Abp.AspNetCore.Mvc
)
);
context.Services.Configure<ApiDescriptionModelOptions>(options =>
Configure<ApiDescriptionModelOptions>(options =>
{
options.IgnoredInterfaces.AddIfNotContains(typeof(IAsyncActionFilter));
options.IgnoredInterfaces.AddIfNotContains(typeof(IFilterMetadata));
options.IgnoredInterfaces.AddIfNotContains(typeof(IActionFilter));
});
context.Services.Configure<AbpAspNetCoreMvcOptions>(options =>
Configure<AbpAspNetCoreMvcOptions>(options =>
{
options.ConventionalControllers.Create(typeof(AbpAspNetCoreMvcModule).Assembly, o =>
{
@ -105,7 +106,7 @@ namespace Volo.Abp.AspNetCore.Mvc
partManager.FeatureProviders.Add(new AbpConventionalControllerFeatureProvider(application));
context.Services.Configure<MvcOptions>(mvcOptions =>
Configure<MvcOptions>(mvcOptions =>
{
mvcOptions.AddAbp(context.Services);
});

8
framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpController.cs

@ -4,6 +4,7 @@ using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Volo.Abp.Aspects;
using Volo.Abp.AspNetCore.Mvc.Validation;
using Volo.Abp.Guids;
using Volo.Abp.MultiTenancy;
using Volo.Abp.ObjectMapping;
@ -31,8 +32,15 @@ namespace Volo.Abp.AspNetCore.Mvc
public IClock Clock { get; set; }
public IModelStateValidator ModelValidator { get; set; }
public List<string> AppliedCrossCuttingConcerns { get; } = new List<string>();
protected virtual void ValidateModel()
{
ModelValidator?.Validate(ModelState);
}
protected ILogger Logger => _lazyLogger.Value;
private Lazy<ILogger> _lazyLogger => new Lazy<ILogger>(() => LoggerFactory?.CreateLogger(GetType().FullName) ?? NullLogger.Instance, true);
}

2
framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/AbpAspNetCoreModule.cs

@ -32,7 +32,7 @@ namespace Volo.Abp.AspNetCore
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.Configure<AbpAuditingOptions>(options =>
Configure<AbpAuditingOptions>(options =>
{
options.Contributors.Add(new AspNetCoreAuditLogContributor());
});

53
framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/DependencyInjection/HttpContextServiceScopeFactory.cs

@ -0,0 +1,53 @@
using System;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.AspNetCore.DependencyInjection
{
[ExposeServices(
typeof(IHybridServiceScopeFactory),
typeof(HttpContextServiceScopeFactory)
)]
[Dependency(ReplaceServices = true)]
public class HttpContextServiceScopeFactory : IHybridServiceScopeFactory, ITransientDependency
{
protected IHttpContextAccessor HttpContextAccessor { get; }
protected IServiceScopeFactory ServiceScopeFactory { get; }
public HttpContextServiceScopeFactory(
IHttpContextAccessor httpContextAccessor,
IServiceScopeFactory serviceScopeFactory)
{
HttpContextAccessor = httpContextAccessor;
ServiceScopeFactory = serviceScopeFactory;
}
public virtual IServiceScope CreateScope()
{
var httpContext = HttpContextAccessor.HttpContext;
if (httpContext == null)
{
return ServiceScopeFactory.CreateScope();
}
return new NonDisposedHttpContextServiceScope(httpContext.RequestServices);
}
protected class NonDisposedHttpContextServiceScope : IServiceScope
{
public IServiceProvider ServiceProvider { get; }
public NonDisposedHttpContextServiceScope(IServiceProvider serviceProvider)
{
ServiceProvider = serviceProvider;
}
public void Dispose()
{
}
}
}
}

2
framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/AbpAuthorizationModule.cs

@ -24,7 +24,7 @@ namespace Volo.Abp.Authorization
context.Services.AddSingleton<IAuthorizationHandler, PermissionRequirementHandler>();
context.Services.Configure<PermissionOptions>(options =>
Configure<PermissionOptions>(options =>
{
options.ValueProviders.Add<UserPermissionValueProvider>();
options.ValueProviders.Add<RolePermissionValueProvider>();

58
framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/BackgroundJobExecuter.cs

@ -1,8 +1,7 @@
using System;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options;
using System;
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.BackgroundJobs
@ -11,14 +10,10 @@ namespace Volo.Abp.BackgroundJobs
{
public ILogger<BackgroundJobExecuter> Logger { protected get; set; }
protected IServiceProvider ServiceProvider { get; }
protected BackgroundJobOptions Options { get; }
public BackgroundJobExecuter(
IServiceProvider serviceProvider,
IOptions<BackgroundJobOptions> options)
public BackgroundJobExecuter(IOptions<BackgroundJobOptions> options)
{
ServiceProvider = serviceProvider;
Options = options.Value;
Logger = NullLogger<BackgroundJobExecuter>.Instance;
@ -26,34 +21,31 @@ namespace Volo.Abp.BackgroundJobs
public virtual void Execute(JobExecutionContext context)
{
using (var scope = ServiceProvider.CreateScope())
var job = context.ServiceProvider.GetService(context.JobType);
if (job == null)
{
var job = scope.ServiceProvider.GetService(context.JobType);
if (job == null)
{
throw new AbpException("The job type is not registered to DI: " + context.JobType);
}
throw new AbpException("The job type is not registered to DI: " + context.JobType);
}
var jobExecuteMethod = context.JobType.GetMethod(nameof(IBackgroundJob<object>.Execute));
if (jobExecuteMethod == null)
{
throw new AbpException($"Given job type does not implement {typeof(IBackgroundJob<>).Name}. The job type was: " + context.JobType);
}
try
{
jobExecuteMethod.Invoke(job, new[] { context.JobArgs });
}
catch (Exception ex)
var jobExecuteMethod = context.JobType.GetMethod(nameof(IBackgroundJob<object>.Execute));
if (jobExecuteMethod == null)
{
throw new AbpException($"Given job type does not implement {typeof(IBackgroundJob<>).Name}. The job type was: " + context.JobType);
}
try
{
jobExecuteMethod.Invoke(job, new[] { context.JobArgs });
}
catch (Exception ex)
{
Logger.LogException(ex);
throw new BackgroundJobExecutionException("A background job execution is failed. See inner exception for details.", ex)
{
Logger.LogException(ex);
throw new BackgroundJobExecutionException("A background job execution is failed. See inner exception for details.", ex)
{
JobType = context.JobType.AssemblyQualifiedName,
JobArgs = context.JobArgs
};
}
JobType = context.JobType.AssemblyQualifiedName,
JobArgs = context.JobArgs
};
}
}
}

8
framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/JobExecutionContext.cs

@ -1,15 +1,19 @@
using System;
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.BackgroundJobs
{
public class JobExecutionContext
public class JobExecutionContext : IServiceProviderAccessor
{
public IServiceProvider ServiceProvider { get; }
public Type JobType { get; }
public object JobArgs { get; }
public JobExecutionContext(Type jobType, object jobArgs)
public JobExecutionContext(IServiceProvider serviceProvider, Type jobType, object jobArgs)
{
ServiceProvider = serviceProvider;
JobType = jobType;
JobArgs = jobArgs;
}

13
framework/src/Volo.Abp.BackgroundJobs.HangFire/Volo/Abp/BackgroundJobs/Hangfire/HangfireBackgroundJobManager.cs

@ -13,11 +13,20 @@ namespace Volo.Abp.BackgroundJobs.Hangfire
{
if (!delay.HasValue)
{
return Task.FromResult(BackgroundJob.Enqueue<HangfireJobExecutionAdapter<TArgs>>(adapter => adapter.Execute(args)));
return Task.FromResult(
BackgroundJob.Enqueue<HangfireJobExecutionAdapter<TArgs>>(
adapter => adapter.Execute(args)
)
);
}
else
{
return Task.FromResult(BackgroundJob.Schedule<HangfireJobExecutionAdapter<TArgs>>(adapter => adapter.Execute(args), delay.Value));
return Task.FromResult(
BackgroundJob.Schedule<HangfireJobExecutionAdapter<TArgs>>(
adapter => adapter.Execute(args),
delay.Value
)
);
}
}
}

19
framework/src/Volo.Abp.BackgroundJobs.HangFire/Volo/Abp/BackgroundJobs/Hangfire/HangfireJobExecutionAdapter.cs

@ -1,23 +1,32 @@
using Microsoft.Extensions.Options;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
namespace Volo.Abp.BackgroundJobs.Hangfire
{
public class HangfireJobExecutionAdapter<TArgs>
{
protected BackgroundJobOptions Options { get; }
protected IServiceScopeFactory ServiceScopeFactory { get; }
protected IBackgroundJobExecuter JobExecuter { get; }
public HangfireJobExecutionAdapter(IOptions<BackgroundJobOptions> options, IBackgroundJobExecuter jobExecuter)
public HangfireJobExecutionAdapter(
IOptions<BackgroundJobOptions> options,
IBackgroundJobExecuter jobExecuter,
IServiceScopeFactory serviceScopeFactory)
{
JobExecuter = jobExecuter;
ServiceScopeFactory = serviceScopeFactory;
Options = options.Value;
}
public void Execute(TArgs args)
{
var jobType = Options.GetJob(typeof(TArgs)).JobType;
var context = new JobExecutionContext(jobType, args);
JobExecuter.Execute(context);
using (var scope = ServiceScopeFactory.CreateScope())
{
var jobType = Options.GetJob(typeof(TArgs)).JobType;
var context = new JobExecutionContext(scope.ServiceProvider, jobType, args);
JobExecuter.Execute(context);
}
}
}
}

46
framework/src/Volo.Abp.BackgroundJobs.RabbitMQ/Volo/Abp/BackgroundJobs/RabbitMQ/JobQueue.cs

@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options;
@ -28,6 +29,7 @@ namespace Volo.Abp.BackgroundJobs.RabbitMQ
protected IChannelPool ChannelPool { get; }
protected IRabbitMqSerializer Serializer { get; }
protected IBackgroundJobExecuter JobExecuter { get; }
protected IServiceScopeFactory ServiceScopeFactory { get; }
protected AsyncLock SyncObj = new AsyncLock();
protected bool IsDiposed { get; private set; }
@ -37,12 +39,14 @@ namespace Volo.Abp.BackgroundJobs.RabbitMQ
IOptions<RabbitMqBackgroundJobOptions> rabbitMqBackgroundJobOptions,
IChannelPool channelPool,
IRabbitMqSerializer serializer,
IBackgroundJobExecuter jobExecuter)
IBackgroundJobExecuter jobExecuter,
IServiceScopeFactory serviceScopeFactory)
{
BackgroundJobOptions = backgroundJobOptions.Value;
RabbitMqBackgroundJobOptions = rabbitMqBackgroundJobOptions.Value;
Serializer = serializer;
JobExecuter = jobExecuter;
ServiceScopeFactory = serviceScopeFactory;
ChannelPool = channelPool;
JobConfiguration = BackgroundJobOptions.GetJob(typeof(TArgs));
@ -167,25 +171,29 @@ namespace Volo.Abp.BackgroundJobs.RabbitMQ
protected virtual void MessageReceived(object sender, BasicDeliverEventArgs ea)
{
var context = new JobExecutionContext(
JobConfiguration.JobType,
Serializer.Deserialize(ea.Body, typeof(TArgs))
);
try
{
JobExecuter.Execute(context);
ChannelAccessor.Channel.BasicAck(deliveryTag: ea.DeliveryTag, multiple: false);
}
catch (BackgroundJobExecutionException)
using (var scope = ServiceScopeFactory.CreateScope())
{
//TODO: Reject like that?
ChannelAccessor.Channel.BasicReject(deliveryTag: ea.DeliveryTag, requeue: true);
}
catch (Exception)
{
//TODO: Reject like that?
ChannelAccessor.Channel.BasicReject(deliveryTag: ea.DeliveryTag, requeue: false);
var context = new JobExecutionContext(
scope.ServiceProvider,
JobConfiguration.JobType,
Serializer.Deserialize(ea.Body, typeof(TArgs))
);
try
{
JobExecuter.Execute(context);
ChannelAccessor.Channel.BasicAck(deliveryTag: ea.DeliveryTag, multiple: false);
}
catch (BackgroundJobExecutionException)
{
//TODO: Reject like that?
ChannelAccessor.Channel.BasicReject(deliveryTag: ea.DeliveryTag, requeue: true);
}
catch (Exception)
{
//TODO: Reject like that?
ChannelAccessor.Channel.BasicReject(deliveryTag: ea.DeliveryTag, requeue: false);
}
}
}

74
framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/BackgroundJobWorker.cs

@ -1,4 +1,5 @@
using System;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Volo.Abp.BackgroundWorkers;
@ -11,26 +12,26 @@ namespace Volo.Abp.BackgroundJobs
public class BackgroundJobWorker : PeriodicBackgroundWorkerBase, IBackgroundJobWorker, ISingletonDependency
{
protected IBackgroundJobExecuter JobExecuter { get; }
protected IBackgroundJobStore Store { get; }
protected BackgroundJobOptions JobOptions { get; }
protected BackgroundJobWorkerOptions WorkerOptions { get; }
protected IClock Clock { get; }
protected IBackgroundJobSerializer Serializer { get; }
protected IServiceScopeFactory ServiceScopeFactory { get; }
public BackgroundJobWorker(
IBackgroundJobStore store,
AbpTimer timer,
IBackgroundJobExecuter jobExecuter,
IBackgroundJobSerializer serializer,
IOptions<BackgroundJobOptions> jobOptions,
IOptions<BackgroundJobWorkerOptions> workerOptions,
IClock clock)
IClock clock,
IServiceScopeFactory serviceScopeFactory)
: base(timer)
{
JobExecuter = jobExecuter;
Serializer = serializer;
Clock = clock;
Store = store;
ServiceScopeFactory = serviceScopeFactory;
WorkerOptions = workerOptions.Value;
JobOptions = jobOptions.Value;
Timer.Period = WorkerOptions.JobPollPeriod;
@ -38,53 +39,60 @@ namespace Volo.Abp.BackgroundJobs
protected override void DoWork()
{
var waitingJobs = AsyncHelper.RunSync(() => Store.GetWaitingJobsAsync(WorkerOptions.MaxJobFetchCount));
foreach (var jobInfo in waitingJobs)
using (var scope = ServiceScopeFactory.CreateScope())
{
jobInfo.TryCount++;
jobInfo.LastTryTime = Clock.Now;
var store = scope.ServiceProvider.GetRequiredService<IBackgroundJobStore>();
var waitingJobs = AsyncHelper.RunSync(
() => store.GetWaitingJobsAsync(WorkerOptions.MaxJobFetchCount)
);
try
foreach (var jobInfo in waitingJobs)
{
var jobConfiguration = JobOptions.GetJob(jobInfo.JobName);
var jobArgs = Serializer.Deserialize(jobInfo.JobArgs, jobConfiguration.ArgsType);
var context = new JobExecutionContext(jobConfiguration.JobType, jobArgs);
jobInfo.TryCount++;
jobInfo.LastTryTime = Clock.Now;
try
{
JobExecuter.Execute(context);
AsyncHelper.RunSync(() => Store.DeleteAsync(jobInfo.Id));
}
catch (BackgroundJobExecutionException)
{
var nextTryTime = CalculateNextTryTime(jobInfo);
if (nextTryTime.HasValue)
var jobConfiguration = JobOptions.GetJob(jobInfo.JobName);
var jobArgs = Serializer.Deserialize(jobInfo.JobArgs, jobConfiguration.ArgsType);
var context = new JobExecutionContext(scope.ServiceProvider, jobConfiguration.JobType, jobArgs);
try
{
jobInfo.NextTryTime = nextTryTime.Value;
JobExecuter.Execute(context);
AsyncHelper.RunSync(() => store.DeleteAsync(jobInfo.Id));
}
else
catch (BackgroundJobExecutionException)
{
jobInfo.IsAbandoned = true;
}
var nextTryTime = CalculateNextTryTime(jobInfo);
if (nextTryTime.HasValue)
{
jobInfo.NextTryTime = nextTryTime.Value;
}
else
{
jobInfo.IsAbandoned = true;
}
TryUpdate(jobInfo);
TryUpdate(store, jobInfo);
}
}
catch (Exception ex)
{
Logger.LogException(ex);
jobInfo.IsAbandoned = true;
TryUpdate(store, jobInfo);
}
}
catch (Exception ex)
{
Logger.LogException(ex);
jobInfo.IsAbandoned = true;
TryUpdate(jobInfo);
}
}
}
protected virtual void TryUpdate(BackgroundJobInfo jobInfo)
protected virtual void TryUpdate(IBackgroundJobStore store, BackgroundJobInfo jobInfo)
{
try
{
Store.UpdateAsync(jobInfo);
store.UpdateAsync(jobInfo);
}
catch (Exception updateEx)
{

16
framework/src/Volo.Abp.Caching/Volo/Abp/Caching/DistributedCache.cs

@ -63,7 +63,10 @@ namespace Volo.Abp.Caching
return ObjectSerializer.Deserialize<TCacheItem>(cachedBytes);
}
public TCacheItem GetOrAdd(string key, Func<TCacheItem> factory)
public TCacheItem GetOrAdd(
string key,
Func<TCacheItem> factory,
Func<DistributedCacheEntryOptions> optionsFactory = null)
{
var value = Get(key);
if (value != null)
@ -80,14 +83,17 @@ namespace Volo.Abp.Caching
}
value = factory();
Set(key, value);
Set(key, value, optionsFactory?.Invoke());
}
return value;
}
public async Task<TCacheItem> GetOrAddAsync(string key, Func<Task<TCacheItem>> factory, CancellationToken token = default)
public async Task<TCacheItem> GetOrAddAsync(
string key,
Func<Task<TCacheItem>> factory,
Func<DistributedCacheEntryOptions> optionsFactory = null,
CancellationToken token = default)
{
var value = await GetAsync(key, token);
if (value != null)
@ -104,7 +110,7 @@ namespace Volo.Abp.Caching
}
value = await factory();
await SetAsync(key, value, token: token);
await SetAsync(key, value, optionsFactory?.Invoke(), token);
}
return value;

4
framework/src/Volo.Abp.Caching/Volo/Abp/Caching/IDistributedCache.cs

@ -20,12 +20,14 @@ namespace Volo.Abp.Caching
TCacheItem GetOrAdd(
string key,
Func<TCacheItem> factory
Func<TCacheItem> factory,
Func<DistributedCacheEntryOptions> optionsFactory = null
);
Task<TCacheItem> GetOrAddAsync(
[NotNull] string key,
Func<Task<TCacheItem>> factory,
Func<DistributedCacheEntryOptions> optionsFactory = null,
CancellationToken token = default
);

13
framework/src/Volo.Abp.Core/System/AbpStringExtensions.cs

@ -192,6 +192,19 @@ namespace System
return str;
}
public static string ReplaceFirst(this string str, string search, string replace, StringComparison comparisonType = StringComparison.Ordinal)
{
Check.NotNull(str, nameof(str));
var pos = str.IndexOf(search, comparisonType);
if (pos < 0)
{
return str;
}
return str.Substring(0, pos) + replace + str.Substring(pos + search.Length);
}
/// <summary>
/// Gets a substring of a string from end of the string.
/// </summary>

23
framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/DefaultServiceScopeFactory.cs

@ -0,0 +1,23 @@
using Microsoft.Extensions.DependencyInjection;
namespace Volo.Abp.DependencyInjection
{
[ExposeServices(
typeof(IHybridServiceScopeFactory),
typeof(DefaultServiceScopeFactory)
)]
public class DefaultServiceScopeFactory : IHybridServiceScopeFactory, ITransientDependency
{
protected IServiceScopeFactory Factory { get; }
public DefaultServiceScopeFactory(IServiceScopeFactory factory)
{
Factory = factory;
}
public IServiceScope CreateScope()
{
return Factory.CreateScope();
}
}
}

9
framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/IHybridServiceScopeFactory.cs

@ -0,0 +1,9 @@
using Microsoft.Extensions.DependencyInjection;
namespace Volo.Abp.DependencyInjection
{
public interface IHybridServiceScopeFactory : IServiceScopeFactory
{
}
}

23
framework/src/Volo.Abp.Core/Volo/Abp/IO/FileHelper.cs

@ -1,4 +1,5 @@
using System.IO;
using JetBrains.Annotations;
namespace Volo.Abp.IO
{
@ -18,5 +19,27 @@ namespace Volo.Abp.IO
File.Delete(filePath);
}
}
/// <summary>
/// Gets extension of a file.
/// </summary>
/// <param name="fileNameWithExtension"></param>
/// <returns>
/// Returns extension without dot.
/// Returns null if given <paramref name="fileNameWithExtension"></paramref> does not include dot.
/// </returns>
[CanBeNull]
public static string GetExtension([NotNull] string fileNameWithExtension)
{
Check.NotNull(fileNameWithExtension, nameof(fileNameWithExtension));
var lastDotIndex = fileNameWithExtension.LastIndexOf('.');
if (lastDotIndex < 0)
{
return null;
}
return fileNameWithExtension.Substring(lastDotIndex + 1);
}
}
}

2
framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/AbpDddApplicationModule.cs

@ -23,7 +23,7 @@ namespace Volo.Abp.Application
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.Configure<ApiDescriptionModelOptions>(options =>
Configure<ApiDescriptionModelOptions>(options =>
{
options.IgnoredInterfaces.AddIfNotContains(typeof(IRemoteService));
options.IgnoredInterfaces.AddIfNotContains(typeof(IApplicationService));

2
framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/EntityChangeEventHelper.cs

@ -126,7 +126,7 @@ namespace Volo.Abp.Domain.Entities.Events
}
}
protected virtual async Task TriggerEventWithEntity(IEventPublisher eventPublisher, Type genericEventType, object entity, bool triggerInCurrentUnitOfWork)
protected virtual async Task TriggerEventWithEntity(IEventBus eventPublisher, Type genericEventType, object entity, bool triggerInCurrentUnitOfWork)
{
var entityType = ProxyHelper.UnProxy(entity).GetType();
var eventType = genericEventType.MakeGenericType(entityType);

6
framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/AbpEmailingModule.cs

@ -19,12 +19,12 @@ namespace Volo.Abp.Emailing
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.Configure<SettingOptions>(options =>
Configure<SettingOptions>(options =>
{
options.DefinitionProviders.Add<EmailSettingProvider>();
});
context.Services.Configure<VirtualFileSystemOptions>(options =>
Configure<VirtualFileSystemOptions>(options =>
{
options.FileSets.AddEmbedded<AbpEmailingModule>();
});
@ -34,7 +34,7 @@ namespace Volo.Abp.Emailing
options.AddJob<BackgroundEmailSendingJob>();
});
context.Services.Configure<EmailTemplateOptions>(options =>
Configure<EmailTemplateOptions>(options =>
{
options.Templates
.Add(

8
framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContext.cs

@ -84,12 +84,8 @@ namespace Volo.Abp.EntityFrameworkCore
//TODO: Reduce duplications with SaveChangesAsync
//TODO: Instead of adding entity changes to audit log, write them to uow and add to audit log only if uow succeed
ChangeTracker.DetectChanges();
try
{
ChangeTracker.AutoDetectChangesEnabled = false; //TODO: Why this is needed?
var auditLog = AuditingManager?.Current?.Log;
List<EntityChangeInfo> entityChangeList = null;
@ -124,12 +120,8 @@ namespace Volo.Abp.EntityFrameworkCore
public override async Task<int> SaveChangesAsync(bool acceptAllChangesOnSuccess, CancellationToken cancellationToken = default)
{
ChangeTracker.DetectChanges();
try
{
ChangeTracker.AutoDetectChangesEnabled = false; //TODO: Why this is needed?
var auditLog = AuditingManager?.Current?.Log;
List<EntityChangeInfo> entityChangeList = null;

2
framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpEntityFrameworkCoreModule.cs

@ -12,7 +12,7 @@ namespace Volo.Abp.EntityFrameworkCore
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.Configure<AbpDbContextOptions>(options =>
Configure<AbpDbContextOptions>(options =>
{
options.PreConfigure(abpDbContextConfigurationContext =>
{

13
framework/src/Volo.Abp.EventBus.Distributed.RabbitMQ/Volo/Abp/EventBus/Distributed/RabbitMq/RabbitMqDistributedEventBus.cs

@ -30,18 +30,18 @@ namespace Volo.Abp.EventBus.Distributed.RabbitMq
protected ConcurrentDictionary<Type, List<IEventHandlerFactory>> HandlerFactories { get; } //TODO: Accessing to the List<IEventHandlerFactory> may not be thread-safe!
protected ConcurrentDictionary<string, Type> EventTypes { get; }
protected IModel ConsumerChannel;
protected IServiceProvider ServiceProvider { get; }
protected IHybridServiceScopeFactory ServiceScopeFactory { get; }
public RabbitMqDistributedEventBus(
IOptions<RabbitMqDistributedEventBusOptions> options,
IConnectionPool connectionPool,
IRabbitMqSerializer serializer,
IServiceProvider serviceProvider,
IHybridServiceScopeFactory serviceScopeFactory,
IOptions<DistributedEventBusOptions> distributedEventBusOptions)
{
ConnectionPool = connectionPool;
Serializer = serializer;
ServiceProvider = serviceProvider;
ServiceScopeFactory = serviceScopeFactory;
DistributedEventBusOptions = distributedEventBusOptions.Value;
RabbitMqDistributedEventBusOptions = options.Value;
@ -67,7 +67,7 @@ namespace Volo.Abp.EventBus.Distributed.RabbitMq
var genericArgs = @interface.GetGenericArguments();
if (genericArgs.Length == 1)
{
Subscribe(genericArgs[0], new IocEventHandlerFactory(ServiceProvider, handler));
Subscribe(genericArgs[0], new IocEventHandlerFactory(ServiceScopeFactory, handler));
}
}
}
@ -124,6 +124,11 @@ namespace Volo.Abp.EventBus.Distributed.RabbitMq
channel.BasicAck(ea.DeliveryTag, multiple: false);
}
public IDisposable Subscribe<TEvent>(IDistributedEventHandler<TEvent> handler) where TEvent : class
{
return Subscribe(typeof(TEvent), handler);
}
public override IDisposable Subscribe(Type eventType, IEventHandlerFactory factory)
{
var handlerFactories = GetOrCreateHandlerFactories(eventType);

12
framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/AbpEventBusModule.cs

@ -1,7 +1,6 @@
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
using Volo.Abp.EventBus.Distributed;
using Volo.Abp.EventBus.Local;
using Volo.Abp.Modularity;
@ -23,15 +22,14 @@ namespace Volo.Abp.EventBus
services.OnRegistred(context =>
{
if (ReflectionHelper.IsAssignableToGenericType(context.ImplementationType, typeof(IEventHandler<>)))
if (ReflectionHelper.IsAssignableToGenericType(context.ImplementationType, typeof(ILocalEventHandler<>)))
{
localHandlers.Add(context.ImplementationType);
}
//TODO: Distrbiuted event bus is disabled since it's not properly working yet for v0.8 release
//else if (ReflectionHelper.IsAssignableToGenericType(context.ImplementationType, typeof(IDistributedEventHandler<>)))
//{
// distributedHandlers.Add(context.ImplementationType);
//}
else if (ReflectionHelper.IsAssignableToGenericType(context.ImplementationType, typeof(IDistributedEventHandler<>)))
{
distributedHandlers.Add(context.ImplementationType);
}
});
services.Configure<LocalEventBusOptions>(options =>

4
framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/ActionEventHandler.cs

@ -5,11 +5,11 @@ using Volo.Abp.DependencyInjection;
namespace Volo.Abp.EventBus
{
/// <summary>
/// This event handler is an adapter to be able to use an action as <see cref="IEventHandler{TEvent}"/> implementation.
/// This event handler is an adapter to be able to use an action as <see cref="ILocalEventHandler{TEvent}"/> implementation.
/// </summary>
/// <typeparam name="TEvent">Event type</typeparam>
public class ActionEventHandler<TEvent> :
IEventHandler<TEvent>,
ILocalEventHandler<TEvent>,
ITransientDependency
{
/// <summary>

0
framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/LocalEventBusOptions.cs → framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/DistributedEventBusOptions.cs

13
framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/IDistributedEventBus.cs

@ -1,7 +1,16 @@
namespace Volo.Abp.EventBus.Distributed
using System;
namespace Volo.Abp.EventBus.Distributed
{
public interface IDistributedEventBus : IEventBus
{
/// <summary>
/// Registers to an event.
/// Same (given) instance of the handler is used for all event occurrences.
/// </summary>
/// <typeparam name="TEvent">Event type</typeparam>
/// <param name="handler">Object to handle the event</param>
IDisposable Subscribe<TEvent>(IDistributedEventHandler<TEvent> handler)
where TEvent : class;
}
}

22
framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/LocalDistributedEventBus.cs

@ -10,19 +10,19 @@ namespace Volo.Abp.EventBus.Distributed
{
[Dependency(TryRegister = true)]
[ExposeServices(typeof(IDistributedEventBus), typeof(LocalDistributedEventBus))]
public class LocalDistributedEventBus : IDistributedEventBus, ITransientDependency
public class LocalDistributedEventBus : IDistributedEventBus, ISingletonDependency
{
private readonly ILocalEventBus _localEventBus;
protected IServiceProvider ServiceProvider { get; }
protected IHybridServiceScopeFactory ServiceScopeFactory { get; }
protected DistributedEventBusOptions DistributedEventBusOptions { get; }
public LocalDistributedEventBus(
ILocalEventBus localEventBus,
IServiceProvider serviceProvider,
ILocalEventBus localEventBus,
IHybridServiceScopeFactory serviceScopeFactory,
IOptions<DistributedEventBusOptions> distributedEventBusOptions)
{
_localEventBus = localEventBus;
ServiceProvider = serviceProvider;
ServiceScopeFactory = serviceScopeFactory;
DistributedEventBusOptions = distributedEventBusOptions.Value;
Subscribe(distributedEventBusOptions.Value.Handlers);
}
@ -42,18 +42,24 @@ namespace Volo.Abp.EventBus.Distributed
var genericArgs = @interface.GetGenericArguments();
if (genericArgs.Length == 1)
{
Subscribe(genericArgs[0], new IocEventHandlerFactory(ServiceProvider, handler));
Subscribe(genericArgs[0], new IocEventHandlerFactory(ServiceScopeFactory, handler));
}
}
}
}
/// <inheritdoc/>
public virtual IDisposable Subscribe<TEvent>(IDistributedEventHandler<TEvent> handler) where TEvent : class
{
return Subscribe(typeof(TEvent), handler);
}
public IDisposable Subscribe<TEvent>(Func<TEvent, Task> action) where TEvent : class
{
return _localEventBus.Subscribe(action);
}
public IDisposable Subscribe<TEvent>(IEventHandler<TEvent> handler) where TEvent : class
public IDisposable Subscribe<TEvent>(ILocalEventHandler<TEvent> handler) where TEvent : class
{
return _localEventBus.Subscribe(handler);
}
@ -83,7 +89,7 @@ namespace Volo.Abp.EventBus.Distributed
_localEventBus.Unsubscribe(action);
}
public void Unsubscribe<TEvent>(IEventHandler<TEvent> handler) where TEvent : class
public void Unsubscribe<TEvent>(ILocalEventHandler<TEvent> handler) where TEvent : class
{
_localEventBus.Unsubscribe(handler);
}

4
framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/NullLocalEventBus.cs → framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/NullDistributedEventBus.cs

@ -17,7 +17,7 @@ namespace Volo.Abp.EventBus.Distributed
return NullDisposable.Instance;
}
public IDisposable Subscribe<TEvent>(IEventHandler<TEvent> handler) where TEvent : class
public IDisposable Subscribe<TEvent>(IDistributedEventHandler<TEvent> handler) where TEvent : class
{
return NullDisposable.Instance;
}
@ -47,7 +47,7 @@ namespace Volo.Abp.EventBus.Distributed
}
public void Unsubscribe<TEvent>(IEventHandler<TEvent> handler) where TEvent : class
public void Unsubscribe<TEvent>(ILocalEventHandler<TEvent> handler) where TEvent : class
{
}

18
framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/EventBusBase.cs

@ -8,7 +8,7 @@ using System.Threading.Tasks;
using Volo.Abp.EventBus.Distributed;
using Volo.Abp.Reflection;
namespace Volo.Abp.EventBus.Local
namespace Volo.Abp.EventBus
{
public abstract class EventBusBase : IEventBus
{
@ -18,12 +18,6 @@ namespace Volo.Abp.EventBus.Local
return Subscribe(typeof(TEvent), new ActionEventHandler<TEvent>(action));
}
/// <inheritdoc/>
public virtual IDisposable Subscribe<TEvent>(IEventHandler<TEvent> handler) where TEvent : class
{
return Subscribe(typeof(TEvent), handler);
}
/// <inheritdoc/>
public virtual IDisposable Subscribe<TEvent, THandler>()
where TEvent : class
@ -49,7 +43,7 @@ namespace Volo.Abp.EventBus.Local
public abstract void Unsubscribe<TEvent>(Func<TEvent, Task> action) where TEvent : class;
/// <inheritdoc/>
public virtual void Unsubscribe<TEvent>(IEventHandler<TEvent> handler) where TEvent : class
public virtual void Unsubscribe<TEvent>(ILocalEventHandler<TEvent> handler) where TEvent : class
{
Unsubscribe(typeof(TEvent), handler);
}
@ -138,12 +132,12 @@ namespace Volo.Abp.EventBus.Local
{
var handlerType = eventHandlerWrapper.EventHandler.GetType();
if (ReflectionHelper.IsAssignableToGenericType(handlerType, typeof(IEventHandler<>)))
if (ReflectionHelper.IsAssignableToGenericType(handlerType, typeof(ILocalEventHandler<>)))
{
var method = typeof(IEventHandler<>) //TODO: to a static field
var method = typeof(ILocalEventHandler<>)
.MakeGenericType(eventType)
.GetMethod(
nameof(IEventHandler<object>.HandleEventAsync),
nameof(ILocalEventHandler<object>.HandleEventAsync),
new[] { eventType }
);
@ -151,7 +145,7 @@ namespace Volo.Abp.EventBus.Local
}
else if (ReflectionHelper.IsAssignableToGenericType(handlerType, typeof(IDistributedEventHandler<>)))
{
var method = typeof(IDistributedEventHandler<>) //TODO: to a static field
var method = typeof(IDistributedEventHandler<>)
.MakeGenericType(eventType)
.GetMethod(
nameof(IDistributedEventHandler<object>.HandleEventAsync),

114
framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/IEventBus.cs

@ -1,7 +1,119 @@
using System;
using System.Threading.Tasks;
namespace Volo.Abp.EventBus
{
public interface IEventBus : IEventSubscriber, IEventPublisher
public interface IEventBus
{
/// <summary>
/// Triggers an event asynchronously.
/// </summary>
/// <typeparam name="TEvent">Event type</typeparam>
/// <param name="eventData">Related data for the event</param>
/// <returns>The task to handle async operation</returns>
Task PublishAsync<TEvent>(TEvent eventData)
where TEvent : class;
/// <summary>
/// Triggers an event asynchronously.
/// </summary>
/// <param name="eventType">Event type</param>
/// <param name="eventData">Related data for the event</param>
/// <returns>The task to handle async operation</returns>
Task PublishAsync(Type eventType, object eventData);
/// <summary>
/// Registers to an event.
/// Given action is called for all event occurrences.
/// </summary>
/// <param name="action">Action to handle events</param>
/// <typeparam name="TEvent">Event type</typeparam>
IDisposable Subscribe<TEvent>(Func<TEvent, Task> action)
where TEvent : class;
/// <summary>
/// Registers to an event.
/// A new instance of <see cref="THandler"/> object is created for every event occurrence.
/// </summary>
/// <typeparam name="TEvent">Event type</typeparam>
/// <typeparam name="THandler">Type of the event handler</typeparam>
IDisposable Subscribe<TEvent, THandler>()
where TEvent : class
where THandler : IEventHandler, new();
/// <summary>
/// Registers to an event.
/// Same (given) instance of the handler is used for all event occurrences.
/// </summary>
/// <param name="eventType">Event type</param>
/// <param name="handler">Object to handle the event</param>
IDisposable Subscribe(Type eventType, IEventHandler handler);
/// <summary>
/// Registers to an event.
/// Given factory is used to create/release handlers
/// </summary>
/// <typeparam name="TEvent">Event type</typeparam>
/// <param name="factory">A factory to create/release handlers</param>
IDisposable Subscribe<TEvent>(IEventHandlerFactory factory)
where TEvent : class;
/// <summary>
/// Registers to an event.
/// </summary>
/// <param name="eventType">Event type</param>
/// <param name="factory">A factory to create/release handlers</param>
IDisposable Subscribe(Type eventType, IEventHandlerFactory factory);
/// <summary>
/// Unregisters from an event.
/// </summary>
/// <typeparam name="TEvent">Event type</typeparam>
/// <param name="action"></param>
void Unsubscribe<TEvent>(Func<TEvent, Task> action)
where TEvent : class;
/// <summary>
/// Unregisters from an event.
/// </summary>
/// <typeparam name="TEvent">Event type</typeparam>
/// <param name="handler">Handler object that is registered before</param>
void Unsubscribe<TEvent>(ILocalEventHandler<TEvent> handler)
where TEvent : class;
/// <summary>
/// Unregisters from an event.
/// </summary>
/// <param name="eventType">Event type</param>
/// <param name="handler">Handler object that is registered before</param>
void Unsubscribe(Type eventType, IEventHandler handler);
/// <summary>
/// Unregisters from an event.
/// </summary>
/// <typeparam name="TEvent">Event type</typeparam>
/// <param name="factory">Factory object that is registered before</param>
void Unsubscribe<TEvent>(IEventHandlerFactory factory)
where TEvent : class;
/// <summary>
/// Unregisters from an event.
/// </summary>
/// <param name="eventType">Event type</param>
/// <param name="factory">Factory object that is registered before</param>
void Unsubscribe(Type eventType, IEventHandlerFactory factory);
/// <summary>
/// Unregisters all event handlers of given event type.
/// </summary>
/// <typeparam name="TEvent">Event type</typeparam>
void UnsubscribeAll<TEvent>()
where TEvent : class;
/// <summary>
/// Unregisters all event handlers of given event type.
/// </summary>
/// <param name="eventType">Event type</param>
void UnsubscribeAll(Type eventType);
}
}

17
framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/IEventHandler.cs

@ -1,26 +1,13 @@
using System.Threading.Tasks;
using Volo.Abp.EventBus.Distributed;
namespace Volo.Abp.EventBus
{
/// <summary>
/// Undirect base interface for all event handlers.
/// Implement <see cref="IEventHandler{TEvent}"/> instead of this one.
/// Implement <see cref="ILocalEventHandler{TEvent}"/> or <see cref="IDistributedEventHandler{TEvent}"/> instead of this one.
/// </summary>
public interface IEventHandler
{
}
/// <summary>
/// Defines an interface of a class that handles events asynchrounously of type <see cref="IEventHandler{TEvent}"/>.
/// </summary>
/// <typeparam name="TEvent">Event type to handle</typeparam>
public interface IEventHandler<in TEvent> : IEventHandler
{
/// <summary>
/// Handler handles the event by implementing this method.
/// </summary>
/// <param name="eventData">Event data</param>
Task HandleEventAsync(TEvent eventData);
}
}

25
framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/IEventPublisher.cs

@ -1,25 +0,0 @@
using System;
using System.Threading.Tasks;
namespace Volo.Abp.EventBus
{
public interface IEventPublisher
{
/// <summary>
/// Triggers an event asynchronously.
/// </summary>
/// <typeparam name="TEvent">Event type</typeparam>
/// <param name="eventData">Related data for the event</param>
/// <returns>The task to handle async operation</returns>
Task PublishAsync<TEvent>(TEvent eventData)
where TEvent : class;
/// <summary>
/// Triggers an event asynchronously.
/// </summary>
/// <param name="eventType">Event type</param>
/// <param name="eventData">Related data for the event</param>
/// <returns>The task to handle async operation</returns>
Task PublishAsync(Type eventType, object eventData);
}
}

111
framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/IEventSubscriber.cs

@ -1,111 +0,0 @@
using System;
using System.Threading.Tasks;
namespace Volo.Abp.EventBus
{
public interface IEventSubscriber
{
/// <summary>
/// Registers to an event.
/// Given action is called for all event occurrences.
/// </summary>
/// <param name="action">Action to handle events</param>
/// <typeparam name="TEvent">Event type</typeparam>
IDisposable Subscribe<TEvent>(Func<TEvent, Task> action)
where TEvent : class;
/// <summary>
/// Registers to an event.
/// Same (given) instance of the handler is used for all event occurrences.
/// </summary>
/// <typeparam name="TEvent">Event type</typeparam>
/// <param name="handler">Object to handle the event</param>
IDisposable Subscribe<TEvent>(IEventHandler<TEvent> handler)
where TEvent : class;
/// <summary>
/// Registers to an event.
/// A new instance of <see cref="THandler"/> object is created for every event occurrence.
/// </summary>
/// <typeparam name="TEvent">Event type</typeparam>
/// <typeparam name="THandler">Type of the event handler</typeparam>
IDisposable Subscribe<TEvent, THandler>()
where TEvent : class
where THandler : IEventHandler, new();
/// <summary>
/// Registers to an event.
/// Same (given) instance of the handler is used for all event occurrences.
/// </summary>
/// <param name="eventType">Event type</param>
/// <param name="handler">Object to handle the event</param>
IDisposable Subscribe(Type eventType, IEventHandler handler);
/// <summary>
/// Registers to an event.
/// Given factory is used to create/release handlers
/// </summary>
/// <typeparam name="TEvent">Event type</typeparam>
/// <param name="factory">A factory to create/release handlers</param>
IDisposable Subscribe<TEvent>(IEventHandlerFactory factory)
where TEvent : class;
/// <summary>
/// Registers to an event.
/// </summary>
/// <param name="eventType">Event type</param>
/// <param name="factory">A factory to create/release handlers</param>
IDisposable Subscribe(Type eventType, IEventHandlerFactory factory);
/// <summary>
/// Unregisters from an event.
/// </summary>
/// <typeparam name="TEvent">Event type</typeparam>
/// <param name="action"></param>
void Unsubscribe<TEvent>(Func<TEvent, Task> action)
where TEvent : class;
/// <summary>
/// Unregisters from an event.
/// </summary>
/// <typeparam name="TEvent">Event type</typeparam>
/// <param name="handler">Handler object that is registered before</param>
void Unsubscribe<TEvent>(IEventHandler<TEvent> handler)
where TEvent : class;
/// <summary>
/// Unregisters from an event.
/// </summary>
/// <param name="eventType">Event type</param>
/// <param name="handler">Handler object that is registered before</param>
void Unsubscribe(Type eventType, IEventHandler handler);
/// <summary>
/// Unregisters from an event.
/// </summary>
/// <typeparam name="TEvent">Event type</typeparam>
/// <param name="factory">Factory object that is registered before</param>
void Unsubscribe<TEvent>(IEventHandlerFactory factory)
where TEvent : class;
/// <summary>
/// Unregisters from an event.
/// </summary>
/// <param name="eventType">Event type</param>
/// <param name="factory">Factory object that is registered before</param>
void Unsubscribe(Type eventType, IEventHandlerFactory factory);
/// <summary>
/// Unregisters all event handlers of given event type.
/// </summary>
/// <typeparam name="TEvent">Event type</typeparam>
void UnsubscribeAll<TEvent>()
where TEvent : class;
/// <summary>
/// Unregisters all event handlers of given event type.
/// </summary>
/// <param name="eventType">Event type</param>
void UnsubscribeAll(Type eventType);
}
}

8
framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/IocEventHandlerFactory.cs

@ -1,5 +1,6 @@
using System;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.EventBus
{
@ -13,13 +14,10 @@ namespace Volo.Abp.EventBus
protected IServiceScope ServiceScope { get; }
//TODO: Consider to inject IServiceScopeFactory instead
public IocEventHandlerFactory(IServiceProvider serviceProvider, Type handlerType)
public IocEventHandlerFactory(IHybridServiceScopeFactory scopeFactory, Type handlerType)
{
HandlerType = handlerType;
ServiceScope = serviceProvider
.GetRequiredService<IServiceScopeFactory>()
.CreateScope();
ServiceScope = scopeFactory.CreateScope();
}
/// <summary>

11
framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Local/ILocalEventBus.cs

@ -1,3 +1,5 @@
using System;
namespace Volo.Abp.EventBus.Local
{
/// <summary>
@ -5,6 +7,13 @@ namespace Volo.Abp.EventBus.Local
/// </summary>
public interface ILocalEventBus : IEventBus
{
/// <summary>
/// Registers to an event.
/// Same (given) instance of the handler is used for all event occurrences.
/// </summary>
/// <typeparam name="TEvent">Event type</typeparam>
/// <param name="handler">Object to handle the event</param>
IDisposable Subscribe<TEvent>(ILocalEventHandler<TEvent> handler)
where TEvent : class;
}
}

13
framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Local/ILocalEventHandler.cs

@ -0,0 +1,13 @@
using System.Threading.Tasks;
namespace Volo.Abp.EventBus
{
public interface ILocalEventHandler<in TEvent> : IEventHandler
{
/// <summary>
/// Handler handles the event by implementing this method.
/// </summary>
/// <param name="eventData">Event data</param>
Task HandleEventAsync(TEvent eventData);
}
}

14
framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Local/LocalEventBus.cs

@ -28,13 +28,13 @@ namespace Volo.Abp.EventBus.Local
protected ConcurrentDictionary<Type, List<IEventHandlerFactory>> HandlerFactories { get; }
protected IServiceProvider ServiceProvider { get; }
protected IHybridServiceScopeFactory ServiceScopeFactory { get; }
public LocalEventBus(
IOptions<LocalEventBusOptions> options,
IServiceProvider serviceProvider)
IHybridServiceScopeFactory serviceScopeFactory)
{
ServiceProvider = serviceProvider;
ServiceScopeFactory = serviceScopeFactory;
Options = options.Value;
Logger = NullLogger<LocalEventBus>.Instance;
@ -57,12 +57,18 @@ namespace Volo.Abp.EventBus.Local
var genericArgs = @interface.GetGenericArguments();
if (genericArgs.Length == 1)
{
Subscribe(genericArgs[0], new IocEventHandlerFactory(ServiceProvider, handler));
Subscribe(genericArgs[0], new IocEventHandlerFactory(ServiceScopeFactory, handler));
}
}
}
}
/// <inheritdoc/>
public virtual IDisposable Subscribe<TEvent>(ILocalEventHandler<TEvent> handler) where TEvent : class
{
return Subscribe(typeof(TEvent), handler);
}
/// <inheritdoc/>
public override IDisposable Subscribe(Type eventType, IEventHandlerFactory factory)
{

4
framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Local/NullLocalEventBus.cs

@ -17,7 +17,7 @@ namespace Volo.Abp.EventBus.Local
return NullDisposable.Instance;
}
public IDisposable Subscribe<TEvent>(IEventHandler<TEvent> handler) where TEvent : class
public IDisposable Subscribe<TEvent>(ILocalEventHandler<TEvent> handler) where TEvent : class
{
return NullDisposable.Instance;
}
@ -47,7 +47,7 @@ namespace Volo.Abp.EventBus.Local
}
public void Unsubscribe<TEvent>(IEventHandler<TEvent> handler) where TEvent : class
public void Unsubscribe<TEvent>(ILocalEventHandler<TEvent> handler) where TEvent : class
{
}

2
framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/TransientEventHandlerFactory.cs

@ -9,7 +9,7 @@ namespace Volo.Abp.EventBus
/// <remarks>
/// This class always creates a new transient instance of handler.
/// </remarks>
internal class TransientEventHandlerFactory<THandler> : IEventHandlerFactory
public class TransientEventHandlerFactory<THandler> : IEventHandlerFactory
where THandler : IEventHandler, new()
{
/// <summary>

2
framework/src/Volo.Abp.Http/Volo/Abp/Http/AbpHttpModule.cs

@ -12,7 +12,7 @@ namespace Volo.Abp.Http
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.Configure<AbpApiProxyScriptingOptions>(options =>
Configure<AbpApiProxyScriptingOptions>(options =>
{
options.Generators[JQueryProxyScriptGenerator.Name] = typeof(JQueryProxyScriptGenerator);
});

25
framework/src/Volo.Abp.Http/Volo/Abp/Http/MimeTypes.cs

@ -1,4 +1,6 @@
namespace Volo.Abp.Http
using System;
namespace Volo.Abp.Http
{
/* Taken from https://gist.github.com/markwhitaker/b29c0142360714688a7cf863ab33e5c9 */
@ -83,5 +85,26 @@
public const string Quicktime = "video/quicktime";
public const string Webm = "video/webm";
}
public static string GetByExtension(string extension)
{
extension = extension.RemovePreFix(".").ToLowerInvariant();
switch (extension)
{
case "png":
return Image.Png;
case "gif":
return Image.Gif;
case "jpg":
case "jpeg":
return Image.Jpeg;
//TODO: Add other extensions too..
default:
return Application.OctetStream;
}
}
}
}

4
framework/src/Volo.Abp.Localization/Volo.Abp.Localization.csproj

@ -17,10 +17,6 @@
<EmbeddedResource Include="Volo\Abp\Localization\Resources\**\*.json" />
</ItemGroup>
<ItemGroup>
<None Remove="Volo\Abp\Localization\Resources\AbpValidation\pt-BR.json" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
</ItemGroup>

6
framework/src/Volo.Abp.Localization/Volo/Abp/Localization/AbpLocalizationModule.cs

@ -16,19 +16,19 @@ namespace Volo.Abp.Localization
{
AbpStringLocalizerFactory.Replace(context.Services);
context.Services.Configure<VirtualFileSystemOptions>(options =>
Configure<VirtualFileSystemOptions>(options =>
{
options.FileSets.AddEmbedded<AbpLocalizationModule>("Volo.Abp", "Volo/Abp");
});
context.Services.Configure<AbpLocalizationOptions>(options =>
Configure<AbpLocalizationOptions>(options =>
{
options.Resources
.Add<AbpValidationResource>("en")
.AddVirtualJson("/Localization/Resources/AbpValidation");
});
context.Services.Configure<SettingOptions>(options =>
Configure<SettingOptions>(options =>
{
options.DefinitionProviders.Add<LocalizationSettingProvider>();
});

2
framework/src/Volo.Abp.MultiTenancy.Abstractions/Volo/Abp/MultiTenancy/AbpMultiTenancyAbstractionsModule.cs

@ -11,7 +11,7 @@ namespace Volo.Abp.MultiTenancy
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.Configure<SettingOptions>(options =>
Configure<SettingOptions>(options =>
{
options.ValueProviders.Add<TenantSettingValueProvider>();
});

2
framework/src/Volo.Abp.TestBase/Volo/Abp/AbpIntegratedTest.cs

@ -4,6 +4,8 @@ using Volo.Abp.Modularity;
namespace Volo.Abp
{
//TODO: Move to "Testing" namespace
public abstract class AbpIntegratedTest<TStartupModule> : AbpTestBaseWithServiceProvider, IDisposable
where TStartupModule : IAbpModule
{

8
framework/src/Volo.Abp.TestBase/Volo/Abp/AbpTestBaseModule.cs

@ -1,13 +1,9 @@
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Modularity;
using Volo.Abp.Modularity;
namespace Volo.Abp
{
public class AbpTestBaseModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
}
}
}

13
framework/src/Volo.Abp.TestBase/Volo/Abp/Testing/Utils/ITestCounter.cs

@ -0,0 +1,13 @@
namespace Volo.Abp.Testing.Utils
{
public interface ITestCounter
{
int Add(string name, int count);
int Decrement(string name);
int Increment(string name);
int GetValue(string name);
}
}

43
framework/src/Volo.Abp.TestBase/Volo/Abp/Testing/Utils/TestCounter.cs

@ -0,0 +1,43 @@
using System.Collections.Generic;
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.Testing.Utils
{
public class TestCounter : ITestCounter, ISingletonDependency
{
private readonly Dictionary<string, int> _values;
public TestCounter()
{
_values = new Dictionary<string, int>();
}
public int Increment(string name)
{
return Add(name, 1);
}
public int Decrement(string name)
{
return Add(name, -1);
}
public int Add(string name, int count)
{
lock (_values)
{
var newValue = _values.GetOrDefault(name) + count;
_values[name] = newValue;
return newValue;
}
}
public int GetValue(string name)
{
lock (_values)
{
return _values.GetOrDefault(name);
}
}
}
}

4
framework/src/Volo.Abp.UI/Volo.Abp.UI.csproj

@ -16,10 +16,6 @@
<ItemGroup>
<EmbeddedResource Include="Localization\**\*.json" />
</ItemGroup>
<ItemGroup>
<None Remove="Localization\Resources\AbpUi\pt-BR.json" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Volo.Abp.Localization\Volo.Abp.Localization.csproj" />

4
framework/src/Volo.Abp.UI/Volo/Abp/Ui/AbpUiModule.cs

@ -13,12 +13,12 @@ namespace Volo.Abp.UI
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.Configure<VirtualFileSystemOptions>(options =>
Configure<VirtualFileSystemOptions>(options =>
{
options.FileSets.AddEmbedded<AbpUiModule>();
});
context.Services.Configure<AbpLocalizationOptions>(options =>
Configure<AbpLocalizationOptions>(options =>
{
options.Resources.Add<AbpUiResource>("en").AddVirtualJson("/Localization/Resources/AbpUi");
});

4
framework/src/Volo.Abp.Uow/Volo/Abp/Uow/ChildUnitOfWork.cs

@ -15,6 +15,10 @@ namespace Volo.Abp.Uow
public bool IsReserved => _parent.IsReserved;
public bool IsDisposed => _parent.IsDisposed;
public bool IsCompleted => _parent.IsCompleted;
public string ReservationName => _parent.ReservationName;
public event EventHandler<UnitOfWorkFailedEventArgs> Failed;

4
framework/src/Volo.Abp.Uow/Volo/Abp/Uow/IUnitOfWork.cs

@ -20,6 +20,10 @@ namespace Volo.Abp.Uow
bool IsReserved { get; }
bool IsDisposed { get; }
bool IsCompleted { get; }
string ReservationName { get; }
void SetOuter([CanBeNull] IUnitOfWork outer);

22
framework/src/Volo.Abp.Uow/Volo/Abp/Uow/UnitOfWork.cs

@ -18,6 +18,10 @@ namespace Volo.Abp.Uow
public bool IsReserved { get; set; }
public bool IsDisposed { get; private set; }
public bool IsCompleted { get; private set; }
public string ReservationName { get; set; }
protected List<Func<Task>> CompletedHandlers { get; } = new List<Func<Task>>();
@ -32,8 +36,7 @@ namespace Volo.Abp.Uow
private readonly UnitOfWorkDefaultOptions _defaultOptions;
private Exception _exception;
private bool _isCompleted;
private bool _isDisposed;
private bool _isCompleting;
private bool _isRolledback;
public UnitOfWork(IServiceProvider serviceProvider, IOptions<UnitOfWorkDefaultOptions> options)
@ -101,8 +104,10 @@ namespace Volo.Abp.Uow
try
{
_isCompleting = true;
SaveChanges();
CommitTransactions();
IsCompleted = true;
OnCompleted();
}
catch (Exception ex)
@ -123,8 +128,10 @@ namespace Volo.Abp.Uow
try
{
_isCompleting = true;
await SaveChangesAsync(cancellationToken);
await CommitTransactionsAsync();
IsCompleted = true;
await OnCompletedAsync();
}
catch (Exception ex)
@ -250,16 +257,16 @@ namespace Volo.Abp.Uow
public virtual void Dispose()
{
if (_isDisposed)
if (IsDisposed)
{
return;
}
_isDisposed = true;
IsDisposed = true;
DisposeTransactions();
if (!_isCompleted || _exception != null)
if (!IsCompleted || _exception != null)
{
OnFailed();
}
@ -283,15 +290,12 @@ namespace Volo.Abp.Uow
private void PreventMultipleComplete()
{
if (_isCompleted)
if (IsCompleted || _isCompleting)
{
throw new AbpException("Complete is called before!");
}
_isCompleted = true;
}
protected virtual void RollbackAll()
{
foreach (var databaseApi in _databaseApis.Values)

7
framework/src/Volo.Abp.Uow/Volo/Abp/Uow/UnitOfWorkManager.cs

@ -23,9 +23,10 @@ namespace Volo.Abp.Uow
{
Check.NotNull(options, nameof(options));
if (!requiresNew && _ambientUnitOfWork.UnitOfWork != null && !_ambientUnitOfWork.UnitOfWork.IsReserved)
var currentUow = Current;
if (currentUow != null && !requiresNew)
{
return new ChildUnitOfWork(_ambientUnitOfWork.UnitOfWork);
return new ChildUnitOfWork(currentUow);
}
var unitOfWork = CreateNewUnitOfWork();
@ -86,7 +87,7 @@ namespace Volo.Abp.Uow
var uow = _ambientUnitOfWork.UnitOfWork;
//Skip reserved unit of work
while (uow != null && uow.IsReserved)
while (uow != null && (uow.IsReserved || uow.IsDisposed || uow.IsCompleted))
{
uow = uow.Outer;
}

2
framework/src/Volo.Abp.Validation/Volo/Abp/Validation/AbpValidationException.cs

@ -20,7 +20,7 @@ namespace Volo.Abp.Validation
/// <summary>
/// Detailed list of validation errors for this exception.
/// </summary>
public IList<ValidationResult> ValidationErrors { get; set; }
public IList<ValidationResult> ValidationErrors { get; }
/// <summary>
/// Exception severity.

2
framework/src/Volo.Abp.Validation/Volo/Abp/Validation/IHasValidationErrors.cs

@ -5,6 +5,6 @@ namespace Volo.Abp.Validation
{
public interface IHasValidationErrors
{
IList<ValidationResult> ValidationErrors { get; set; }
IList<ValidationResult> ValidationErrors { get; }
}
}

2
framework/test/Volo.Abp.AspNetCore.MultiTenancy.Tests/Volo/Abp/AspNetCore/App/AppModule.cs

@ -19,7 +19,7 @@ namespace Volo.Abp.AspNetCore.App
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.Configure<TenantResolveOptions>(options =>
Configure<TenantResolveOptions>(options =>
{
options.AddDomainTenantResolver("{0}.abp.io");
});

4
framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo.Abp.AspNetCore.Mvc.Tests.csproj

@ -19,10 +19,6 @@
<EmbeddedResource Include="Volo\Abp\AspNetCore\Mvc\Localization\Resource\*.json" />
</ItemGroup>
<ItemGroup>
<None Remove="Volo\Abp\AspNetCore\Mvc\Localization\Resource\pt-BR.json" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.1.0" />
<PackageReference Include="Microsoft.AspNetCore.Authentication" Version="2.1.0" />

16
framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcTestModule.cs

@ -1,4 +1,5 @@
using System;
using Localization.Resources.AbpUi;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.AspNetCore.Modularity;
@ -9,9 +10,11 @@ using Volo.Abp.AspNetCore.TestBase;
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.Autofac;
using Volo.Abp.Localization;
using Volo.Abp.Localization.Resources.AbpValidation;
using Volo.Abp.MemoryDb;
using Volo.Abp.Modularity;
using Volo.Abp.TestApp;
using Volo.Abp.UI;
using Volo.Abp.VirtualFileSystem;
namespace Volo.Abp.AspNetCore.Mvc
@ -45,7 +48,7 @@ namespace Volo.Abp.AspNetCore.Mvc
});
});
context.Services.Configure<AbpAspNetCoreMvcOptions>(options =>
Configure<AbpAspNetCoreMvcOptions>(options =>
{
options.ConventionalControllers.Create(typeof(TestAppModule).Assembly, opts =>
{
@ -56,21 +59,24 @@ namespace Volo.Abp.AspNetCore.Mvc
});
});
context.Services.Configure<PermissionOptions>(options =>
Configure<PermissionOptions>(options =>
{
options.DefinitionProviders.Add<TestPermissionDefinitionProvider>();
});
context.Services.Configure<VirtualFileSystemOptions>(options =>
Configure<VirtualFileSystemOptions>(options =>
{
options.FileSets.AddEmbedded<AbpAspNetCoreMvcTestModule>();
});
context.Services.Configure<AbpLocalizationOptions>(options =>
Configure<AbpLocalizationOptions>(options =>
{
options.Resources
.Add<MvcTestResource>("en")
.AddVirtualJson("/Volo/Abp/AspNetCore/Mvc/Localization/Resource");
.AddBaseTypes(
typeof(AbpUiResource),
typeof(AbpValidationResource)
).AddVirtualJson("/Volo/Abp/AspNetCore/Mvc/Localization/Resource");
});
}

3
framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Localization/Resource/en.json

@ -1,6 +1,7 @@
{
"culture": "en",
"texts": {
"BirthDate": "Birth date"
"BirthDate": "Birth date",
"Value1": "Value One"
}
}

3
framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Localization/Resource/tr.json

@ -1,6 +1,7 @@
{
"culture": "tr",
"texts": {
"BirthDate": "Dogum gunu"
"BirthDate": "Dogum gunu",
"Value1": "Değer Bir"
}
}

12
framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Validation/ValidationTestController_Tests.cs

@ -2,6 +2,7 @@
using System.Threading.Tasks;
using Shouldly;
using Volo.Abp.Http;
using Volo.Abp.Localization;
using Xunit;
namespace Volo.Abp.AspNetCore.Mvc.Validation
@ -22,6 +23,17 @@ namespace Volo.Abp.AspNetCore.Mvc.Validation
result.Error.ValidationErrors.Length.ShouldBeGreaterThan(0);
}
[Fact]
public async Task Should_Return_Localized_Validation_Errors()
{
using (AbpCultureHelper.Use("tr"))
{
var result = await GetResponseAsObjectAsync<RemoteServiceErrorResponse>("/api/validation-test/object-result-action?value1=a", HttpStatusCode.BadRequest); //value1 has min length of 2 chars.
result.Error.ValidationErrors.Length.ShouldBeGreaterThan(0);
result.Error.ValidationErrors[0].Message.ShouldBe("Değer Bir alanı en az '2' uzunluğunda bir metin ya da dizi olmalıdır.");
}
}
[Fact]
public async Task Should_Not_Validate_Action_Result_Success()
{

4
framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/publish-ignore.json

@ -1,3 +1,3 @@
{
}
"app_offline.htm": {}
}

4
framework/test/Volo.Abp.AspNetCore.Mvc.Versioning.Tests/Volo/Abp/AspNetCore/Mvc/Versioning/AbpAspNetCoreMvcVersioningTestModule.cs

@ -19,7 +19,7 @@ namespace Volo.Abp.AspNetCore.Mvc.Versioning
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.Configure<AbpAspNetCoreMvcOptions>(options =>
Configure<AbpAspNetCoreMvcOptions>(options =>
{
//2.0 Version
options.ConventionalControllers.Create(typeof(AbpAspNetCoreMvcVersioningTestModule).Assembly, opts =>
@ -49,7 +49,7 @@ namespace Volo.Abp.AspNetCore.Mvc.Versioning
context.Services.AddHttpClientProxies(typeof(AbpAspNetCoreMvcVersioningTestModule).Assembly);
context.Services.Configure<RemoteServiceOptions>(options =>
Configure<RemoteServiceOptions>(options =>
{
options.RemoteServices.Default = new RemoteServiceConfiguration("/");
});

2
framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/AbpAuthorizationTestModule.cs

@ -23,7 +23,7 @@ namespace Volo.Abp.Authorization
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.Configure<PermissionOptions>(options =>
Configure<PermissionOptions>(options =>
{
options.DefinitionProviders.TryAdd<AuthorizationTestPermissionDefinitionProvider>();
});

2
framework/test/Volo.Abp.AutoMapper.Tests/Volo/Abp/AutoMapper/AutoMapper_ConfigurationValidation_Tests.cs

@ -28,7 +28,7 @@ namespace Volo.Abp.AutoMapper
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.Configure<AbpAutoMapperOptions>(options =>
Configure<AbpAutoMapperOptions>(options =>
{
options.UseStaticMapper = false;

2
framework/test/Volo.Abp.AutoMapper.Tests/Volo/Abp/AutoMapper/AutofacTestModule.cs

@ -8,7 +8,7 @@ namespace Volo.Abp.AutoMapper
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.Configure<AbpAutoMapperOptions>(options =>
Configure<AbpAutoMapperOptions>(options =>
{
options.UseStaticMapper = false;
});

1
framework/test/Volo.Abp.BackgroundJobs.Tests/Volo/Abp/BackgroundJobs/BackgroundJobExecuter_Tests.cs

@ -25,6 +25,7 @@ namespace Volo.Abp.BackgroundJobs
_backgroundJobExecuter.Execute(
new JobExecutionContext(
ServiceProvider,
typeof(MyJob),
new MyJobArgs("42")
)

8
framework/test/Volo.Abp.Core.Tests/System/StringExtensions_Tests.cs

@ -187,6 +187,14 @@ namespace System
"Https://abp.io".RemovePreFix(StringComparison.OrdinalIgnoreCase, "https://").ShouldBe("abp.io");
}
[Fact]
public void ReplaceFirst_Tests()
{
"Test string".ReplaceFirst("s", "X").ShouldBe("TeXt string");
"Test test test".ReplaceFirst("test", "XX").ShouldBe("Test XX test");
"Test test test".ReplaceFirst("test", "XX", StringComparison.OrdinalIgnoreCase).ShouldBe("XX test test");
}
[Fact]
public void ToEnum_Test()
{

41
framework/test/Volo.Abp.Core.Tests/Volo/Abp/DependencyInjection/HybridServiceScopeFactory_Tests.cs

@ -0,0 +1,41 @@
using System;
using Microsoft.Extensions.DependencyInjection;
using Shouldly;
using Volo.Abp.Modularity;
using Xunit;
namespace Volo.Abp.DependencyInjection
{
public class HybridServiceScopeFactory_Tests
{
[Fact]
public void Should_Use_Default_ServiceScopeFactory_By_Default()
{
using (var application = AbpApplicationFactory.Create<IndependentEmptyModule>())
{
application.Services.AddType(typeof(MyService));
application.Initialize();
var serviceScopeFactory = application.ServiceProvider.GetRequiredService<IHybridServiceScopeFactory>();
using (var scope = serviceScopeFactory.CreateScope())
{
scope.ServiceProvider.GetRequiredService<MyService>();
}
MyService.DisposeCount.ShouldBe(1);
}
}
private class MyService : ITransientDependency, IDisposable
{
public static int DisposeCount { get; private set; }
public void Dispose()
{
++DisposeCount;
}
}
}
}

15
framework/test/Volo.Abp.Core.Tests/Volo/Abp/IO/FileHelper_Tests.cs

@ -0,0 +1,15 @@
using Shouldly;
using Xunit;
namespace Volo.Abp.IO
{
public class FileHelper_Tests
{
[Fact]
public void GetExtension()
{
FileHelper.GetExtension("test").ShouldBeNull();
FileHelper.GetExtension("te.st").ShouldBe("st");
}
}
}

2
framework/test/Volo.Abp.Data.Tests/Volo/Abp/Data/ConnectionStringResolver_Tests.cs

@ -42,7 +42,7 @@ namespace Volo.Abp.Data
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.Configure<DbConnectionOptions>(options =>
Configure<DbConnectionOptions>(options =>
{
options.ConnectionStrings.Default = DefaultConnString;
options.ConnectionStrings[Database1Name] = Database1ConnString;

4
framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/AbpEmailingTestModule.cs

@ -13,12 +13,12 @@ namespace Volo.Abp.Emailing
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.Configure<VirtualFileSystemOptions>(options =>
Configure<VirtualFileSystemOptions>(options =>
{
options.FileSets.AddEmbedded<AbpEmailingTestModule>();
});
context.Services.Configure<EmailTemplateOptions>(options =>
Configure<EmailTemplateOptions>(options =>
{
options.Templates["template1"] =
new EmailTemplateDefinition("template1")

2
framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/AbpEntityFrameworkCoreTestModule.cs

@ -34,7 +34,7 @@ namespace Volo.Abp.EntityFrameworkCore
var sqliteConnection = CreateDatabaseAndGetConnection();
context.Services.Configure<AbpDbContextOptions>(options =>
Configure<AbpDbContextOptions>(options =>
{
options.Configure(abpDbContextConfigurationContext =>
{

7
framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/EntityFrameworkCoreTestBase.cs

@ -1,9 +1,4 @@
using System;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Uow;
namespace Volo.Abp.EntityFrameworkCore
namespace Volo.Abp.EntityFrameworkCore
{
public abstract class EntityFrameworkCoreTestBase : AbpIntegratedTest<AbpEntityFrameworkCoreTestModule>
{

9
framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/Uow/Uow_Completed_Tests.cs

@ -0,0 +1,9 @@
using Volo.Abp.TestApp.Testing;
namespace Volo.Abp.EntityFrameworkCore.Uow
{
public class Uow_Completed_Tests : Uow_Completed_Tests<AbpEntityFrameworkCoreTestModule>
{
}
}

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save