Browse Source

Merge remote-tracking branch 'origin/master'

pull/628/head
Marcelo Mohr Maciel 8 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> <Project>
<PropertyGroup> <PropertyGroup>
<LangVersion>latest</LangVersion> <LangVersion>latest</LangVersion>
<Version>0.8.0</Version> <Version>0.9.0</Version>
<NoWarn>$(NoWarn);CS1591</NoWarn> <NoWarn>$(NoWarn);CS1591</NoWarn>
<PackageIconUrl>http://www.aspnetboilerplate.com/images/abp_nupkg.png</PackageIconUrl> <PackageIconUrl>https://abp.io/assets/abp_nupkg.png</PackageIconUrl>
<PackageProjectUrl>http://abp.io</PackageProjectUrl> <PackageProjectUrl>https://abp.io</PackageProjectUrl>
<PackageLicenseUrl>https://github.com/volosoft/abp/blob/master/LICENSE</PackageLicenseUrl> <PackageLicenseUrl>https://github.com/abpframework/abp/blob/master/LICENSE</PackageLicenseUrl>
<RepositoryType>git</RepositoryType> <RepositoryType>git</RepositoryType>
<RepositoryUrl>https://github.com/volosoft/abp/</RepositoryUrl> <RepositoryUrl>https://github.com/abpframework/abp/</RepositoryUrl>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>

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

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

4
docs/en/Localization.md

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

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

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

8
docs/en/Multi-Tenancy.md

@ -138,7 +138,7 @@ namespace MyCompany.MyProject
{ {
public override void ConfigureServices(ServiceConfigurationContext context) public override void ConfigureServices(ServiceConfigurationContext context)
{ {
context.Services.Configure<TenantResolveOptions>(options => Configure<TenantResolveOptions>(options =>
{ {
options.TenantResolvers.Add(new MyCustomTenantResolver()); options.TenantResolvers.Add(new MyCustomTenantResolver());
}); });
@ -194,7 +194,7 @@ namespace MyCompany.MyProject
{ {
public override void ConfigureServices(ServiceConfigurationContext context) public override void ConfigureServices(ServiceConfigurationContext context)
{ {
context.Services.Configure<ConfigurationTenantStoreOptions>(options => Configure<ConfigurationTenantStoreOptions>(options =>
{ {
options.Tenants = new[] options.Tenants = new[]
{ {
@ -240,7 +240,7 @@ namespace MyCompany.MyProject
{ {
var configuration = BuildConfiguration(); var configuration = BuildConfiguration();
context.Services.Configure<ConfigurationTenantStoreOptions>(configuration); Configure<ConfigurationTenantStoreOptions>(configuration);
} }
private static IConfigurationRoot BuildConfiguration() private static IConfigurationRoot BuildConfiguration()
@ -361,7 +361,7 @@ namespace MyCompany.MyProject
{ {
public override void ConfigureServices(ServiceConfigurationContext context) 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) //Subdomain format: {0}.mydomain.com (adding as the highest priority resolver)
options.TenantResolvers.Insert(0, new DomainTenantResolver("{0}.mydomain.com")); 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) 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 //Register all embedded files of this assembly to the virtual file system
options.FileSets.AddEmbedded<MyModule>(); options.FileSets.AddEmbedded<MyModule>();
@ -122,7 +122,7 @@ public class MyWebAppModule : AbpModule
if (hostingEnvironment.IsDevelopment()) //only for development time if (hostingEnvironment.IsDevelopment()) //only for development time
{ {
context.Services.Configure<VirtualFileSystemOptions>(options => Configure<VirtualFileSystemOptions>(options =>
{ {
//ReplaceEmbeddedByPyhsical gets the root folder of the MyModule project //ReplaceEmbeddedByPyhsical gets the root folder of the MyModule project
options.FileSets.ReplaceEmbeddedByPyhsical<MyModule>( 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) public override void ConfigureServices(ServiceConfigurationContext context)
{ {
context.Services.Configure<BundlingOptions>(options => Configure<BundlingOptions>(options =>
{ {
options options
.ScriptBundles .ScriptBundles
@ -153,7 +153,7 @@ public class MyWebExtensionModule : AbpModule
{ {
public override void ConfigureServices(ServiceConfigurationContext context) public override void ConfigureServices(ServiceConfigurationContext context)
{ {
context.Services.Configure<BundlingOptions>(options => Configure<BundlingOptions>(options =>
{ {
options options
.ScriptBundles .ScriptBundles

4
docs/zh-Hans/Localization.md

@ -46,12 +46,12 @@ public class MyModule : AbpModule
{ {
public override void ConfigureServices(ServiceConfigurationContext context) public override void ConfigureServices(ServiceConfigurationContext context)
{ {
context.Services.Configure<VirtualFileSystemOptions>(options => Configure<VirtualFileSystemOptions>(options =>
{ {
options.FileSets.AddEmbedded<MyModule>(); options.FileSets.AddEmbedded<MyModule>();
}); });
context.Services.Configure<AbpLocalizationOptions>(options => Configure<AbpLocalizationOptions>(options =>
{ {
options.Resources options.Resources
.Add<TestResource>("en") .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) public override void ConfigureServices(ServiceConfigurationContext context)
{ {
//为应用程序配置默认的连接字符串 //为应用程序配置默认的连接字符串
context.Services.Configure<DbConnectionOptions>(options => Configure<DbConnectionOptions>(options =>
{ {
options.ConnectionStrings.Default = "......"; options.ConnectionStrings.Default = "......";
}); });

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

@ -139,7 +139,7 @@ namespace MyCompany.MyProject
{ {
public override void ConfigureServices(ServiceConfigurationContext context) public override void ConfigureServices(ServiceConfigurationContext context)
{ {
context.Services.Configure<TenantResolveOptions>(options => Configure<TenantResolveOptions>(options =>
{ {
options.TenantResolvers.Add(new MyCustomTenantResolver()); options.TenantResolvers.Add(new MyCustomTenantResolver());
}); });
@ -194,7 +194,7 @@ namespace MyCompany.MyProject
{ {
public override void ConfigureServices(ServiceConfigurationContext context) public override void ConfigureServices(ServiceConfigurationContext context)
{ {
context.Services.Configure<ConfigurationTenantStoreOptions>(options => Configure<ConfigurationTenantStoreOptions>(options =>
{ {
options.Tenants = new[] options.Tenants = new[]
{ {
@ -240,7 +240,7 @@ namespace MyCompany.MyProject
{ {
var configuration = BuildConfiguration(); var configuration = BuildConfiguration();
context.Services.Configure<ConfigurationTenantStoreOptions>(configuration); Configure<ConfigurationTenantStoreOptions>(configuration);
} }
private static IConfigurationRoot BuildConfiguration() private static IConfigurationRoot BuildConfiguration()
@ -362,7 +362,7 @@ namespace MyCompany.MyProject
{ {
public override void ConfigureServices(ServiceConfigurationContext context) public override void ConfigureServices(ServiceConfigurationContext context)
{ {
context.Services.Configure<TenantResolveOptions>(options => Configure<TenantResolveOptions>(options =>
{ {
//子域名格式: {0}.mydomain.com (作为最高优先级解析器添加) //子域名格式: {0}.mydomain.com (作为最高优先级解析器添加)
options.TenantResolvers.Insert(0, new DomainTenantResolver("{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) 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 //Register all embedded files of this assembly to the virtual file system
options.FileSets.AddEmbedded<MyModule>(); options.FileSets.AddEmbedded<MyModule>();
@ -123,7 +123,7 @@ public class MyWebAppModule : AbpModule
if (hostingEnvironment.IsDevelopment()) //only for development time if (hostingEnvironment.IsDevelopment()) //only for development time
{ {
context.Services.Configure<VirtualFileSystemOptions>(options => Configure<VirtualFileSystemOptions>(options =>
{ {
//ReplaceEmbeddedByPyhsical gets the root folder of the MyModule project //ReplaceEmbeddedByPyhsical gets the root folder of the MyModule project
options.FileSets.ReplaceEmbeddedByPyhsical<MyModule>( 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) public override void ConfigureServices(ServiceConfigurationContext context)
{ {
context.Services.Configure<TenantResolveOptions>(options => Configure<TenantResolveOptions>(options =>
{ {
options.TenantResolvers.Add(new QueryStringTenantResolveContributer()); options.TenantResolvers.Add(new QueryStringTenantResolveContributer());
options.TenantResolvers.Add(new RouteTenantResolveContributer()); 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) public override void ConfigureServices(ServiceConfigurationContext context)
{ {
context.Services.Configure<VirtualFileSystemOptions>(options => Configure<VirtualFileSystemOptions>(options =>
{ {
options.FileSets.AddEmbedded<AbpAspNetCoreMvcUiBootstrapModule>("Volo.Abp.AspNetCore.Mvc.UI.Bootstrap"); 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(); var selectItems = (properties.First().Model as IEnumerable<SelectListItem>).ToList();
return selectItems; 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) public override void ConfigureServices(ServiceConfigurationContext context)
{ {
context.Services.Configure<ThemingOptions>(options => Configure<ThemingOptions>(options =>
{ {
options.Themes.Add<BasicTheme>(); 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"); options.FileSets.AddEmbedded<AbpAspNetCoreMvcUiBasicThemeModule>("Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic");
}); });
context.Services.Configure<ToolbarOptions>(options => Configure<ToolbarOptions>(options =>
{ {
options.Contributors.Add(new BasicThemeMainTopToolbarContributor()); options.Contributors.Add(new BasicThemeMainTopToolbarContributor());
}); });
context.Services.Configure<BundlingOptions>(options => Configure<BundlingOptions>(options =>
{ {
options options
.StyleBundles .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) 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"); options.FileSets.AddEmbedded<AbpAspNetCoreMvcUiThemeSharedModule>("Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared");
}); });
context.Services.Configure<BundlingOptions>(options => Configure<BundlingOptions>(options =>
{ {
options options
.StyleBundles .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.Bundling;
using Volo.Abp.AspNetCore.Mvc.UI.Packages.Anchor;
using Volo.Abp.AspNetCore.Mvc.UI.Packages.Bootstrap; 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.DatatablesNetBs4;
using Volo.Abp.AspNetCore.Mvc.UI.Packages.JQuery; using Volo.Abp.AspNetCore.Mvc.UI.Packages.JQuery;
using Volo.Abp.AspNetCore.Mvc.UI.Packages.JQueryForm; using Volo.Abp.AspNetCore.Mvc.UI.Packages.JQueryForm;
using Volo.Abp.AspNetCore.Mvc.UI.Packages.JQueryValidationUnobtrusive; using Volo.Abp.AspNetCore.Mvc.UI.Packages.JQueryValidationUnobtrusive;
using Volo.Abp.AspNetCore.Mvc.UI.Packages.Lodash; 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.Select2;
using Volo.Abp.AspNetCore.Mvc.UI.Packages.SweetAlert; using Volo.Abp.AspNetCore.Mvc.UI.Packages.SweetAlert;
using Volo.Abp.AspNetCore.Mvc.UI.Packages.Timeago; 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.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.ApplicationParts; using Microsoft.AspNetCore.Mvc.ApplicationParts;
using Microsoft.AspNetCore.Mvc.Razor; using Microsoft.AspNetCore.Mvc.Razor;
using Microsoft.Extensions.DependencyInjection; 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(IAsyncActionFilter));
options.IgnoredInterfaces.AddIfNotContains(typeof(IFilterMetadata)); options.IgnoredInterfaces.AddIfNotContains(typeof(IFilterMetadata));
options.IgnoredInterfaces.AddIfNotContains(typeof(IActionFilter)); options.IgnoredInterfaces.AddIfNotContains(typeof(IActionFilter));
}); });
context.Services.Configure<AbpAspNetCoreMvcOptions>(options => Configure<AbpAspNetCoreMvcOptions>(options =>
{ {
options.ConventionalControllers.Create(typeof(AbpAspNetCoreMvcModule).Assembly, o => options.ConventionalControllers.Create(typeof(AbpAspNetCoreMvcModule).Assembly, o =>
{ {
@ -105,7 +106,7 @@ namespace Volo.Abp.AspNetCore.Mvc
partManager.FeatureProviders.Add(new AbpConventionalControllerFeatureProvider(application)); partManager.FeatureProviders.Add(new AbpConventionalControllerFeatureProvider(application));
context.Services.Configure<MvcOptions>(mvcOptions => Configure<MvcOptions>(mvcOptions =>
{ {
mvcOptions.AddAbp(context.Services); 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;
using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Logging.Abstractions;
using Volo.Abp.Aspects; using Volo.Abp.Aspects;
using Volo.Abp.AspNetCore.Mvc.Validation;
using Volo.Abp.Guids; using Volo.Abp.Guids;
using Volo.Abp.MultiTenancy; using Volo.Abp.MultiTenancy;
using Volo.Abp.ObjectMapping; using Volo.Abp.ObjectMapping;
@ -31,8 +32,15 @@ namespace Volo.Abp.AspNetCore.Mvc
public IClock Clock { get; set; } public IClock Clock { get; set; }
public IModelStateValidator ModelValidator { get; set; }
public List<string> AppliedCrossCuttingConcerns { get; } = new List<string>(); public List<string> AppliedCrossCuttingConcerns { get; } = new List<string>();
protected virtual void ValidateModel()
{
ModelValidator?.Validate(ModelState);
}
protected ILogger Logger => _lazyLogger.Value; protected ILogger Logger => _lazyLogger.Value;
private Lazy<ILogger> _lazyLogger => new Lazy<ILogger>(() => LoggerFactory?.CreateLogger(GetType().FullName) ?? NullLogger.Instance, true); 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) public override void ConfigureServices(ServiceConfigurationContext context)
{ {
context.Services.Configure<AbpAuditingOptions>(options => Configure<AbpAuditingOptions>(options =>
{ {
options.Contributors.Add(new AspNetCoreAuditLogContributor()); 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.AddSingleton<IAuthorizationHandler, PermissionRequirementHandler>();
context.Services.Configure<PermissionOptions>(options => Configure<PermissionOptions>(options =>
{ {
options.ValueProviders.Add<UserPermissionValueProvider>(); options.ValueProviders.Add<UserPermissionValueProvider>();
options.ValueProviders.Add<RolePermissionValueProvider>(); 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.Logging;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using System;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
namespace Volo.Abp.BackgroundJobs namespace Volo.Abp.BackgroundJobs
@ -11,14 +10,10 @@ namespace Volo.Abp.BackgroundJobs
{ {
public ILogger<BackgroundJobExecuter> Logger { protected get; set; } public ILogger<BackgroundJobExecuter> Logger { protected get; set; }
protected IServiceProvider ServiceProvider { get; }
protected BackgroundJobOptions Options { get; } protected BackgroundJobOptions Options { get; }
public BackgroundJobExecuter( public BackgroundJobExecuter(IOptions<BackgroundJobOptions> options)
IServiceProvider serviceProvider,
IOptions<BackgroundJobOptions> options)
{ {
ServiceProvider = serviceProvider;
Options = options.Value; Options = options.Value;
Logger = NullLogger<BackgroundJobExecuter>.Instance; Logger = NullLogger<BackgroundJobExecuter>.Instance;
@ -26,34 +21,31 @@ namespace Volo.Abp.BackgroundJobs
public virtual void Execute(JobExecutionContext context) 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); throw new AbpException("The job type is not registered to DI: " + context.JobType);
if (job == null) }
{
throw new AbpException("The job type is not registered to DI: " + context.JobType);
}
var jobExecuteMethod = context.JobType.GetMethod(nameof(IBackgroundJob<object>.Execute)); var jobExecuteMethod = context.JobType.GetMethod(nameof(IBackgroundJob<object>.Execute));
if (jobExecuteMethod == null) if (jobExecuteMethod == null)
{ {
throw new AbpException($"Given job type does not implement {typeof(IBackgroundJob<>).Name}. The job type was: " + context.JobType); throw new AbpException($"Given job type does not implement {typeof(IBackgroundJob<>).Name}. The job type was: " + context.JobType);
} }
try try
{ {
jobExecuteMethod.Invoke(job, new[] { context.JobArgs }); jobExecuteMethod.Invoke(job, new[] { context.JobArgs });
} }
catch (Exception ex) catch (Exception ex)
{
Logger.LogException(ex);
throw new BackgroundJobExecutionException("A background job execution is failed. See inner exception for details.", ex)
{ {
Logger.LogException(ex); JobType = context.JobType.AssemblyQualifiedName,
JobArgs = context.JobArgs
throw new BackgroundJobExecutionException("A background job execution is failed. See inner exception for details.", ex) };
{
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 System;
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.BackgroundJobs namespace Volo.Abp.BackgroundJobs
{ {
public class JobExecutionContext public class JobExecutionContext : IServiceProviderAccessor
{ {
public IServiceProvider ServiceProvider { get; }
public Type JobType { get; } public Type JobType { get; }
public object JobArgs { get; } public object JobArgs { get; }
public JobExecutionContext(Type jobType, object jobArgs) public JobExecutionContext(IServiceProvider serviceProvider, Type jobType, object jobArgs)
{ {
ServiceProvider = serviceProvider;
JobType = jobType; JobType = jobType;
JobArgs = jobArgs; 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) 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 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 namespace Volo.Abp.BackgroundJobs.Hangfire
{ {
public class HangfireJobExecutionAdapter<TArgs> public class HangfireJobExecutionAdapter<TArgs>
{ {
protected BackgroundJobOptions Options { get; } protected BackgroundJobOptions Options { get; }
protected IServiceScopeFactory ServiceScopeFactory { get; }
protected IBackgroundJobExecuter JobExecuter { get; } protected IBackgroundJobExecuter JobExecuter { get; }
public HangfireJobExecutionAdapter(IOptions<BackgroundJobOptions> options, IBackgroundJobExecuter jobExecuter) public HangfireJobExecutionAdapter(
IOptions<BackgroundJobOptions> options,
IBackgroundJobExecuter jobExecuter,
IServiceScopeFactory serviceScopeFactory)
{ {
JobExecuter = jobExecuter; JobExecuter = jobExecuter;
ServiceScopeFactory = serviceScopeFactory;
Options = options.Value; Options = options.Value;
} }
public void Execute(TArgs args) public void Execute(TArgs args)
{ {
var jobType = Options.GetJob(typeof(TArgs)).JobType; using (var scope = ServiceScopeFactory.CreateScope())
var context = new JobExecutionContext(jobType, args); {
JobExecuter.Execute(context); 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.Collections.Generic;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
@ -28,6 +29,7 @@ namespace Volo.Abp.BackgroundJobs.RabbitMQ
protected IChannelPool ChannelPool { get; } protected IChannelPool ChannelPool { get; }
protected IRabbitMqSerializer Serializer { get; } protected IRabbitMqSerializer Serializer { get; }
protected IBackgroundJobExecuter JobExecuter { get; } protected IBackgroundJobExecuter JobExecuter { get; }
protected IServiceScopeFactory ServiceScopeFactory { get; }
protected AsyncLock SyncObj = new AsyncLock(); protected AsyncLock SyncObj = new AsyncLock();
protected bool IsDiposed { get; private set; } protected bool IsDiposed { get; private set; }
@ -37,12 +39,14 @@ namespace Volo.Abp.BackgroundJobs.RabbitMQ
IOptions<RabbitMqBackgroundJobOptions> rabbitMqBackgroundJobOptions, IOptions<RabbitMqBackgroundJobOptions> rabbitMqBackgroundJobOptions,
IChannelPool channelPool, IChannelPool channelPool,
IRabbitMqSerializer serializer, IRabbitMqSerializer serializer,
IBackgroundJobExecuter jobExecuter) IBackgroundJobExecuter jobExecuter,
IServiceScopeFactory serviceScopeFactory)
{ {
BackgroundJobOptions = backgroundJobOptions.Value; BackgroundJobOptions = backgroundJobOptions.Value;
RabbitMqBackgroundJobOptions = rabbitMqBackgroundJobOptions.Value; RabbitMqBackgroundJobOptions = rabbitMqBackgroundJobOptions.Value;
Serializer = serializer; Serializer = serializer;
JobExecuter = jobExecuter; JobExecuter = jobExecuter;
ServiceScopeFactory = serviceScopeFactory;
ChannelPool = channelPool; ChannelPool = channelPool;
JobConfiguration = BackgroundJobOptions.GetJob(typeof(TArgs)); JobConfiguration = BackgroundJobOptions.GetJob(typeof(TArgs));
@ -167,25 +171,29 @@ namespace Volo.Abp.BackgroundJobs.RabbitMQ
protected virtual void MessageReceived(object sender, BasicDeliverEventArgs ea) protected virtual void MessageReceived(object sender, BasicDeliverEventArgs ea)
{ {
var context = new JobExecutionContext( using (var scope = ServiceScopeFactory.CreateScope())
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? var context = new JobExecutionContext(
ChannelAccessor.Channel.BasicReject(deliveryTag: ea.DeliveryTag, requeue: true); scope.ServiceProvider,
} JobConfiguration.JobType,
catch (Exception) Serializer.Deserialize(ea.Body, typeof(TArgs))
{ );
//TODO: Reject like that?
ChannelAccessor.Channel.BasicReject(deliveryTag: ea.DeliveryTag, requeue: false); 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 System;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Volo.Abp.BackgroundWorkers; using Volo.Abp.BackgroundWorkers;
@ -11,26 +12,26 @@ namespace Volo.Abp.BackgroundJobs
public class BackgroundJobWorker : PeriodicBackgroundWorkerBase, IBackgroundJobWorker, ISingletonDependency public class BackgroundJobWorker : PeriodicBackgroundWorkerBase, IBackgroundJobWorker, ISingletonDependency
{ {
protected IBackgroundJobExecuter JobExecuter { get; } protected IBackgroundJobExecuter JobExecuter { get; }
protected IBackgroundJobStore Store { get; }
protected BackgroundJobOptions JobOptions { get; } protected BackgroundJobOptions JobOptions { get; }
protected BackgroundJobWorkerOptions WorkerOptions { get; } protected BackgroundJobWorkerOptions WorkerOptions { get; }
protected IClock Clock { get; } protected IClock Clock { get; }
protected IBackgroundJobSerializer Serializer { get; } protected IBackgroundJobSerializer Serializer { get; }
protected IServiceScopeFactory ServiceScopeFactory { get; }
public BackgroundJobWorker( public BackgroundJobWorker(
IBackgroundJobStore store,
AbpTimer timer, AbpTimer timer,
IBackgroundJobExecuter jobExecuter, IBackgroundJobExecuter jobExecuter,
IBackgroundJobSerializer serializer, IBackgroundJobSerializer serializer,
IOptions<BackgroundJobOptions> jobOptions, IOptions<BackgroundJobOptions> jobOptions,
IOptions<BackgroundJobWorkerOptions> workerOptions, IOptions<BackgroundJobWorkerOptions> workerOptions,
IClock clock) IClock clock,
IServiceScopeFactory serviceScopeFactory)
: base(timer) : base(timer)
{ {
JobExecuter = jobExecuter; JobExecuter = jobExecuter;
Serializer = serializer; Serializer = serializer;
Clock = clock; Clock = clock;
Store = store; ServiceScopeFactory = serviceScopeFactory;
WorkerOptions = workerOptions.Value; WorkerOptions = workerOptions.Value;
JobOptions = jobOptions.Value; JobOptions = jobOptions.Value;
Timer.Period = WorkerOptions.JobPollPeriod; Timer.Period = WorkerOptions.JobPollPeriod;
@ -38,53 +39,60 @@ namespace Volo.Abp.BackgroundJobs
protected override void DoWork() protected override void DoWork()
{ {
var waitingJobs = AsyncHelper.RunSync(() => Store.GetWaitingJobsAsync(WorkerOptions.MaxJobFetchCount)); using (var scope = ServiceScopeFactory.CreateScope())
foreach (var jobInfo in waitingJobs)
{ {
jobInfo.TryCount++; var store = scope.ServiceProvider.GetRequiredService<IBackgroundJobStore>();
jobInfo.LastTryTime = Clock.Now;
var waitingJobs = AsyncHelper.RunSync(
() => store.GetWaitingJobsAsync(WorkerOptions.MaxJobFetchCount)
);
try foreach (var jobInfo in waitingJobs)
{ {
var jobConfiguration = JobOptions.GetJob(jobInfo.JobName); jobInfo.TryCount++;
var jobArgs = Serializer.Deserialize(jobInfo.JobArgs, jobConfiguration.ArgsType); jobInfo.LastTryTime = Clock.Now;
var context = new JobExecutionContext(jobConfiguration.JobType, jobArgs);
try try
{ {
JobExecuter.Execute(context); var jobConfiguration = JobOptions.GetJob(jobInfo.JobName);
AsyncHelper.RunSync(() => Store.DeleteAsync(jobInfo.Id)); var jobArgs = Serializer.Deserialize(jobInfo.JobArgs, jobConfiguration.ArgsType);
} var context = new JobExecutionContext(scope.ServiceProvider, jobConfiguration.JobType, jobArgs);
catch (BackgroundJobExecutionException)
{ try
var nextTryTime = CalculateNextTryTime(jobInfo);
if (nextTryTime.HasValue)
{ {
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 try
{ {
Store.UpdateAsync(jobInfo); store.UpdateAsync(jobInfo);
} }
catch (Exception updateEx) 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); 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); var value = Get(key);
if (value != null) if (value != null)
@ -80,14 +83,17 @@ namespace Volo.Abp.Caching
} }
value = factory(); value = factory();
Set(key, value); Set(key, value, optionsFactory?.Invoke());
} }
return value; 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); var value = await GetAsync(key, token);
if (value != null) if (value != null)
@ -104,7 +110,7 @@ namespace Volo.Abp.Caching
} }
value = await factory(); value = await factory();
await SetAsync(key, value, token: token); await SetAsync(key, value, optionsFactory?.Invoke(), token);
} }
return value; return value;

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

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

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

@ -192,6 +192,19 @@ namespace System
return str; 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> /// <summary>
/// Gets a substring of a string from end of the string. /// Gets a substring of a string from end of the string.
/// </summary> /// </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 System.IO;
using JetBrains.Annotations;
namespace Volo.Abp.IO namespace Volo.Abp.IO
{ {
@ -18,5 +19,27 @@ namespace Volo.Abp.IO
File.Delete(filePath); 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) public override void ConfigureServices(ServiceConfigurationContext context)
{ {
context.Services.Configure<ApiDescriptionModelOptions>(options => Configure<ApiDescriptionModelOptions>(options =>
{ {
options.IgnoredInterfaces.AddIfNotContains(typeof(IRemoteService)); options.IgnoredInterfaces.AddIfNotContains(typeof(IRemoteService));
options.IgnoredInterfaces.AddIfNotContains(typeof(IApplicationService)); 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 entityType = ProxyHelper.UnProxy(entity).GetType();
var eventType = genericEventType.MakeGenericType(entityType); 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) public override void ConfigureServices(ServiceConfigurationContext context)
{ {
context.Services.Configure<SettingOptions>(options => Configure<SettingOptions>(options =>
{ {
options.DefinitionProviders.Add<EmailSettingProvider>(); options.DefinitionProviders.Add<EmailSettingProvider>();
}); });
context.Services.Configure<VirtualFileSystemOptions>(options => Configure<VirtualFileSystemOptions>(options =>
{ {
options.FileSets.AddEmbedded<AbpEmailingModule>(); options.FileSets.AddEmbedded<AbpEmailingModule>();
}); });
@ -34,7 +34,7 @@ namespace Volo.Abp.Emailing
options.AddJob<BackgroundEmailSendingJob>(); options.AddJob<BackgroundEmailSendingJob>();
}); });
context.Services.Configure<EmailTemplateOptions>(options => Configure<EmailTemplateOptions>(options =>
{ {
options.Templates options.Templates
.Add( .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: 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 //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 try
{ {
ChangeTracker.AutoDetectChangesEnabled = false; //TODO: Why this is needed?
var auditLog = AuditingManager?.Current?.Log; var auditLog = AuditingManager?.Current?.Log;
List<EntityChangeInfo> entityChangeList = null; List<EntityChangeInfo> entityChangeList = null;
@ -124,12 +120,8 @@ namespace Volo.Abp.EntityFrameworkCore
public override async Task<int> SaveChangesAsync(bool acceptAllChangesOnSuccess, CancellationToken cancellationToken = default) public override async Task<int> SaveChangesAsync(bool acceptAllChangesOnSuccess, CancellationToken cancellationToken = default)
{ {
ChangeTracker.DetectChanges();
try try
{ {
ChangeTracker.AutoDetectChangesEnabled = false; //TODO: Why this is needed?
var auditLog = AuditingManager?.Current?.Log; var auditLog = AuditingManager?.Current?.Log;
List<EntityChangeInfo> entityChangeList = null; 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) public override void ConfigureServices(ServiceConfigurationContext context)
{ {
context.Services.Configure<AbpDbContextOptions>(options => Configure<AbpDbContextOptions>(options =>
{ {
options.PreConfigure(abpDbContextConfigurationContext => 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<Type, List<IEventHandlerFactory>> HandlerFactories { get; } //TODO: Accessing to the List<IEventHandlerFactory> may not be thread-safe!
protected ConcurrentDictionary<string, Type> EventTypes { get; } protected ConcurrentDictionary<string, Type> EventTypes { get; }
protected IModel ConsumerChannel; protected IModel ConsumerChannel;
protected IServiceProvider ServiceProvider { get; } protected IHybridServiceScopeFactory ServiceScopeFactory { get; }
public RabbitMqDistributedEventBus( public RabbitMqDistributedEventBus(
IOptions<RabbitMqDistributedEventBusOptions> options, IOptions<RabbitMqDistributedEventBusOptions> options,
IConnectionPool connectionPool, IConnectionPool connectionPool,
IRabbitMqSerializer serializer, IRabbitMqSerializer serializer,
IServiceProvider serviceProvider, IHybridServiceScopeFactory serviceScopeFactory,
IOptions<DistributedEventBusOptions> distributedEventBusOptions) IOptions<DistributedEventBusOptions> distributedEventBusOptions)
{ {
ConnectionPool = connectionPool; ConnectionPool = connectionPool;
Serializer = serializer; Serializer = serializer;
ServiceProvider = serviceProvider; ServiceScopeFactory = serviceScopeFactory;
DistributedEventBusOptions = distributedEventBusOptions.Value; DistributedEventBusOptions = distributedEventBusOptions.Value;
RabbitMqDistributedEventBusOptions = options.Value; RabbitMqDistributedEventBusOptions = options.Value;
@ -67,7 +67,7 @@ namespace Volo.Abp.EventBus.Distributed.RabbitMq
var genericArgs = @interface.GetGenericArguments(); var genericArgs = @interface.GetGenericArguments();
if (genericArgs.Length == 1) 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); 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) public override IDisposable Subscribe(Type eventType, IEventHandlerFactory factory)
{ {
var handlerFactories = GetOrCreateHandlerFactories(eventType); var handlerFactories = GetOrCreateHandlerFactories(eventType);

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

@ -1,7 +1,6 @@
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using Volo.Abp.EventBus.Distributed; using Volo.Abp.EventBus.Distributed;
using Volo.Abp.EventBus.Local; using Volo.Abp.EventBus.Local;
using Volo.Abp.Modularity; using Volo.Abp.Modularity;
@ -23,15 +22,14 @@ namespace Volo.Abp.EventBus
services.OnRegistred(context => services.OnRegistred(context =>
{ {
if (ReflectionHelper.IsAssignableToGenericType(context.ImplementationType, typeof(IEventHandler<>))) if (ReflectionHelper.IsAssignableToGenericType(context.ImplementationType, typeof(ILocalEventHandler<>)))
{ {
localHandlers.Add(context.ImplementationType); 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<>)))
//else if (ReflectionHelper.IsAssignableToGenericType(context.ImplementationType, typeof(IDistributedEventHandler<>))) {
//{ distributedHandlers.Add(context.ImplementationType);
// distributedHandlers.Add(context.ImplementationType); }
//}
}); });
services.Configure<LocalEventBusOptions>(options => 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 namespace Volo.Abp.EventBus
{ {
/// <summary> /// <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> /// </summary>
/// <typeparam name="TEvent">Event type</typeparam> /// <typeparam name="TEvent">Event type</typeparam>
public class ActionEventHandler<TEvent> : public class ActionEventHandler<TEvent> :
IEventHandler<TEvent>, ILocalEventHandler<TEvent>,
ITransientDependency ITransientDependency
{ {
/// <summary> /// <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 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)] [Dependency(TryRegister = true)]
[ExposeServices(typeof(IDistributedEventBus), typeof(LocalDistributedEventBus))] [ExposeServices(typeof(IDistributedEventBus), typeof(LocalDistributedEventBus))]
public class LocalDistributedEventBus : IDistributedEventBus, ITransientDependency public class LocalDistributedEventBus : IDistributedEventBus, ISingletonDependency
{ {
private readonly ILocalEventBus _localEventBus; private readonly ILocalEventBus _localEventBus;
protected IServiceProvider ServiceProvider { get; } protected IHybridServiceScopeFactory ServiceScopeFactory { get; }
protected DistributedEventBusOptions DistributedEventBusOptions { get; } protected DistributedEventBusOptions DistributedEventBusOptions { get; }
public LocalDistributedEventBus( public LocalDistributedEventBus(
ILocalEventBus localEventBus, ILocalEventBus localEventBus,
IServiceProvider serviceProvider, IHybridServiceScopeFactory serviceScopeFactory,
IOptions<DistributedEventBusOptions> distributedEventBusOptions) IOptions<DistributedEventBusOptions> distributedEventBusOptions)
{ {
_localEventBus = localEventBus; _localEventBus = localEventBus;
ServiceProvider = serviceProvider; ServiceScopeFactory = serviceScopeFactory;
DistributedEventBusOptions = distributedEventBusOptions.Value; DistributedEventBusOptions = distributedEventBusOptions.Value;
Subscribe(distributedEventBusOptions.Value.Handlers); Subscribe(distributedEventBusOptions.Value.Handlers);
} }
@ -42,18 +42,24 @@ namespace Volo.Abp.EventBus.Distributed
var genericArgs = @interface.GetGenericArguments(); var genericArgs = @interface.GetGenericArguments();
if (genericArgs.Length == 1) 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 public IDisposable Subscribe<TEvent>(Func<TEvent, Task> action) where TEvent : class
{ {
return _localEventBus.Subscribe(action); 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); return _localEventBus.Subscribe(handler);
} }
@ -83,7 +89,7 @@ namespace Volo.Abp.EventBus.Distributed
_localEventBus.Unsubscribe(action); _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); _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; 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; 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.EventBus.Distributed;
using Volo.Abp.Reflection; using Volo.Abp.Reflection;
namespace Volo.Abp.EventBus.Local namespace Volo.Abp.EventBus
{ {
public abstract class EventBusBase : IEventBus public abstract class EventBusBase : IEventBus
{ {
@ -18,12 +18,6 @@ namespace Volo.Abp.EventBus.Local
return Subscribe(typeof(TEvent), new ActionEventHandler<TEvent>(action)); 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/> /// <inheritdoc/>
public virtual IDisposable Subscribe<TEvent, THandler>() public virtual IDisposable Subscribe<TEvent, THandler>()
where TEvent : class where TEvent : class
@ -49,7 +43,7 @@ namespace Volo.Abp.EventBus.Local
public abstract void Unsubscribe<TEvent>(Func<TEvent, Task> action) where TEvent : class; public abstract void Unsubscribe<TEvent>(Func<TEvent, Task> action) where TEvent : class;
/// <inheritdoc/> /// <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); Unsubscribe(typeof(TEvent), handler);
} }
@ -138,12 +132,12 @@ namespace Volo.Abp.EventBus.Local
{ {
var handlerType = eventHandlerWrapper.EventHandler.GetType(); 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) .MakeGenericType(eventType)
.GetMethod( .GetMethod(
nameof(IEventHandler<object>.HandleEventAsync), nameof(ILocalEventHandler<object>.HandleEventAsync),
new[] { eventType } new[] { eventType }
); );
@ -151,7 +145,7 @@ namespace Volo.Abp.EventBus.Local
} }
else if (ReflectionHelper.IsAssignableToGenericType(handlerType, typeof(IDistributedEventHandler<>))) else if (ReflectionHelper.IsAssignableToGenericType(handlerType, typeof(IDistributedEventHandler<>)))
{ {
var method = typeof(IDistributedEventHandler<>) //TODO: to a static field var method = typeof(IDistributedEventHandler<>)
.MakeGenericType(eventType) .MakeGenericType(eventType)
.GetMethod( .GetMethod(
nameof(IDistributedEventHandler<object>.HandleEventAsync), 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 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 namespace Volo.Abp.EventBus
{ {
/// <summary> /// <summary>
/// Undirect base interface for all event handlers. /// 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> /// </summary>
public interface IEventHandler 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 System;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.EventBus namespace Volo.Abp.EventBus
{ {
@ -13,13 +14,10 @@ namespace Volo.Abp.EventBus
protected IServiceScope ServiceScope { get; } protected IServiceScope ServiceScope { get; }
//TODO: Consider to inject IServiceScopeFactory instead public IocEventHandlerFactory(IHybridServiceScopeFactory scopeFactory, Type handlerType)
public IocEventHandlerFactory(IServiceProvider serviceProvider, Type handlerType)
{ {
HandlerType = handlerType; HandlerType = handlerType;
ServiceScope = serviceProvider ServiceScope = scopeFactory.CreateScope();
.GetRequiredService<IServiceScopeFactory>()
.CreateScope();
} }
/// <summary> /// <summary>

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

@ -1,3 +1,5 @@
using System;
namespace Volo.Abp.EventBus.Local namespace Volo.Abp.EventBus.Local
{ {
/// <summary> /// <summary>
@ -5,6 +7,13 @@ namespace Volo.Abp.EventBus.Local
/// </summary> /// </summary>
public interface ILocalEventBus : IEventBus 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 ConcurrentDictionary<Type, List<IEventHandlerFactory>> HandlerFactories { get; }
protected IServiceProvider ServiceProvider { get; } protected IHybridServiceScopeFactory ServiceScopeFactory { get; }
public LocalEventBus( public LocalEventBus(
IOptions<LocalEventBusOptions> options, IOptions<LocalEventBusOptions> options,
IServiceProvider serviceProvider) IHybridServiceScopeFactory serviceScopeFactory)
{ {
ServiceProvider = serviceProvider; ServiceScopeFactory = serviceScopeFactory;
Options = options.Value; Options = options.Value;
Logger = NullLogger<LocalEventBus>.Instance; Logger = NullLogger<LocalEventBus>.Instance;
@ -57,12 +57,18 @@ namespace Volo.Abp.EventBus.Local
var genericArgs = @interface.GetGenericArguments(); var genericArgs = @interface.GetGenericArguments();
if (genericArgs.Length == 1) 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/> /// <inheritdoc/>
public override IDisposable Subscribe(Type eventType, IEventHandlerFactory factory) 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; 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; 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> /// <remarks>
/// This class always creates a new transient instance of handler. /// This class always creates a new transient instance of handler.
/// </remarks> /// </remarks>
internal class TransientEventHandlerFactory<THandler> : IEventHandlerFactory public class TransientEventHandlerFactory<THandler> : IEventHandlerFactory
where THandler : IEventHandler, new() where THandler : IEventHandler, new()
{ {
/// <summary> /// <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) public override void ConfigureServices(ServiceConfigurationContext context)
{ {
context.Services.Configure<AbpApiProxyScriptingOptions>(options => Configure<AbpApiProxyScriptingOptions>(options =>
{ {
options.Generators[JQueryProxyScriptGenerator.Name] = typeof(JQueryProxyScriptGenerator); 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 */ /* Taken from https://gist.github.com/markwhitaker/b29c0142360714688a7cf863ab33e5c9 */
@ -83,5 +85,26 @@
public const string Quicktime = "video/quicktime"; public const string Quicktime = "video/quicktime";
public const string Webm = "video/webm"; 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" /> <EmbeddedResource Include="Volo\Abp\Localization\Resources\**\*.json" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<None Remove="Volo\Abp\Localization\Resources\AbpValidation\pt-BR.json" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" /> <PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
</ItemGroup> </ItemGroup>

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

@ -16,19 +16,19 @@ namespace Volo.Abp.Localization
{ {
AbpStringLocalizerFactory.Replace(context.Services); AbpStringLocalizerFactory.Replace(context.Services);
context.Services.Configure<VirtualFileSystemOptions>(options => Configure<VirtualFileSystemOptions>(options =>
{ {
options.FileSets.AddEmbedded<AbpLocalizationModule>("Volo.Abp", "Volo/Abp"); options.FileSets.AddEmbedded<AbpLocalizationModule>("Volo.Abp", "Volo/Abp");
}); });
context.Services.Configure<AbpLocalizationOptions>(options => Configure<AbpLocalizationOptions>(options =>
{ {
options.Resources options.Resources
.Add<AbpValidationResource>("en") .Add<AbpValidationResource>("en")
.AddVirtualJson("/Localization/Resources/AbpValidation"); .AddVirtualJson("/Localization/Resources/AbpValidation");
}); });
context.Services.Configure<SettingOptions>(options => Configure<SettingOptions>(options =>
{ {
options.DefinitionProviders.Add<LocalizationSettingProvider>(); 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) public override void ConfigureServices(ServiceConfigurationContext context)
{ {
context.Services.Configure<SettingOptions>(options => Configure<SettingOptions>(options =>
{ {
options.ValueProviders.Add<TenantSettingValueProvider>(); 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 namespace Volo.Abp
{ {
//TODO: Move to "Testing" namespace
public abstract class AbpIntegratedTest<TStartupModule> : AbpTestBaseWithServiceProvider, IDisposable public abstract class AbpIntegratedTest<TStartupModule> : AbpTestBaseWithServiceProvider, IDisposable
where TStartupModule : IAbpModule 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 namespace Volo.Abp
{ {
public class AbpTestBaseModule : AbpModule 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> <ItemGroup>
<EmbeddedResource Include="Localization\**\*.json" /> <EmbeddedResource Include="Localization\**\*.json" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<None Remove="Localization\Resources\AbpUi\pt-BR.json" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Volo.Abp.Localization\Volo.Abp.Localization.csproj" /> <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) public override void ConfigureServices(ServiceConfigurationContext context)
{ {
context.Services.Configure<VirtualFileSystemOptions>(options => Configure<VirtualFileSystemOptions>(options =>
{ {
options.FileSets.AddEmbedded<AbpUiModule>(); options.FileSets.AddEmbedded<AbpUiModule>();
}); });
context.Services.Configure<AbpLocalizationOptions>(options => Configure<AbpLocalizationOptions>(options =>
{ {
options.Resources.Add<AbpUiResource>("en").AddVirtualJson("/Localization/Resources/AbpUi"); 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 IsReserved => _parent.IsReserved;
public bool IsDisposed => _parent.IsDisposed;
public bool IsCompleted => _parent.IsCompleted;
public string ReservationName => _parent.ReservationName; public string ReservationName => _parent.ReservationName;
public event EventHandler<UnitOfWorkFailedEventArgs> Failed; 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 IsReserved { get; }
bool IsDisposed { get; }
bool IsCompleted { get; }
string ReservationName { get; } string ReservationName { get; }
void SetOuter([CanBeNull] IUnitOfWork outer); 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 IsReserved { get; set; }
public bool IsDisposed { get; private set; }
public bool IsCompleted { get; private set; }
public string ReservationName { get; set; } public string ReservationName { get; set; }
protected List<Func<Task>> CompletedHandlers { get; } = new List<Func<Task>>(); protected List<Func<Task>> CompletedHandlers { get; } = new List<Func<Task>>();
@ -32,8 +36,7 @@ namespace Volo.Abp.Uow
private readonly UnitOfWorkDefaultOptions _defaultOptions; private readonly UnitOfWorkDefaultOptions _defaultOptions;
private Exception _exception; private Exception _exception;
private bool _isCompleted; private bool _isCompleting;
private bool _isDisposed;
private bool _isRolledback; private bool _isRolledback;
public UnitOfWork(IServiceProvider serviceProvider, IOptions<UnitOfWorkDefaultOptions> options) public UnitOfWork(IServiceProvider serviceProvider, IOptions<UnitOfWorkDefaultOptions> options)
@ -101,8 +104,10 @@ namespace Volo.Abp.Uow
try try
{ {
_isCompleting = true;
SaveChanges(); SaveChanges();
CommitTransactions(); CommitTransactions();
IsCompleted = true;
OnCompleted(); OnCompleted();
} }
catch (Exception ex) catch (Exception ex)
@ -123,8 +128,10 @@ namespace Volo.Abp.Uow
try try
{ {
_isCompleting = true;
await SaveChangesAsync(cancellationToken); await SaveChangesAsync(cancellationToken);
await CommitTransactionsAsync(); await CommitTransactionsAsync();
IsCompleted = true;
await OnCompletedAsync(); await OnCompletedAsync();
} }
catch (Exception ex) catch (Exception ex)
@ -250,16 +257,16 @@ namespace Volo.Abp.Uow
public virtual void Dispose() public virtual void Dispose()
{ {
if (_isDisposed) if (IsDisposed)
{ {
return; return;
} }
_isDisposed = true; IsDisposed = true;
DisposeTransactions(); DisposeTransactions();
if (!_isCompleted || _exception != null) if (!IsCompleted || _exception != null)
{ {
OnFailed(); OnFailed();
} }
@ -283,15 +290,12 @@ namespace Volo.Abp.Uow
private void PreventMultipleComplete() private void PreventMultipleComplete()
{ {
if (_isCompleted) if (IsCompleted || _isCompleting)
{ {
throw new AbpException("Complete is called before!"); throw new AbpException("Complete is called before!");
} }
_isCompleted = true;
} }
protected virtual void RollbackAll() protected virtual void RollbackAll()
{ {
foreach (var databaseApi in _databaseApis.Values) 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)); 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(); var unitOfWork = CreateNewUnitOfWork();
@ -86,7 +87,7 @@ namespace Volo.Abp.Uow
var uow = _ambientUnitOfWork.UnitOfWork; var uow = _ambientUnitOfWork.UnitOfWork;
//Skip reserved unit of work //Skip reserved unit of work
while (uow != null && uow.IsReserved) while (uow != null && (uow.IsReserved || uow.IsDisposed || uow.IsCompleted))
{ {
uow = uow.Outer; uow = uow.Outer;
} }

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

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

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

@ -5,6 +5,6 @@ namespace Volo.Abp.Validation
{ {
public interface IHasValidationErrors 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) public override void ConfigureServices(ServiceConfigurationContext context)
{ {
context.Services.Configure<TenantResolveOptions>(options => Configure<TenantResolveOptions>(options =>
{ {
options.AddDomainTenantResolver("{0}.abp.io"); 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" /> <EmbeddedResource Include="Volo\Abp\AspNetCore\Mvc\Localization\Resource\*.json" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<None Remove="Volo\Abp\AspNetCore\Mvc\Localization\Resource\pt-BR.json" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.1.0" /> <PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.1.0" />
<PackageReference Include="Microsoft.AspNetCore.Authentication" 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 System;
using Localization.Resources.AbpUi;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.AspNetCore.Modularity; using Volo.Abp.AspNetCore.Modularity;
@ -9,9 +10,11 @@ using Volo.Abp.AspNetCore.TestBase;
using Volo.Abp.Authorization.Permissions; using Volo.Abp.Authorization.Permissions;
using Volo.Abp.Autofac; using Volo.Abp.Autofac;
using Volo.Abp.Localization; using Volo.Abp.Localization;
using Volo.Abp.Localization.Resources.AbpValidation;
using Volo.Abp.MemoryDb; using Volo.Abp.MemoryDb;
using Volo.Abp.Modularity; using Volo.Abp.Modularity;
using Volo.Abp.TestApp; using Volo.Abp.TestApp;
using Volo.Abp.UI;
using Volo.Abp.VirtualFileSystem; using Volo.Abp.VirtualFileSystem;
namespace Volo.Abp.AspNetCore.Mvc 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 => 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>(); options.DefinitionProviders.Add<TestPermissionDefinitionProvider>();
}); });
context.Services.Configure<VirtualFileSystemOptions>(options => Configure<VirtualFileSystemOptions>(options =>
{ {
options.FileSets.AddEmbedded<AbpAspNetCoreMvcTestModule>(); options.FileSets.AddEmbedded<AbpAspNetCoreMvcTestModule>();
}); });
context.Services.Configure<AbpLocalizationOptions>(options => Configure<AbpLocalizationOptions>(options =>
{ {
options.Resources options.Resources
.Add<MvcTestResource>("en") .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", "culture": "en",
"texts": { "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", "culture": "tr",
"texts": { "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 System.Threading.Tasks;
using Shouldly; using Shouldly;
using Volo.Abp.Http; using Volo.Abp.Http;
using Volo.Abp.Localization;
using Xunit; using Xunit;
namespace Volo.Abp.AspNetCore.Mvc.Validation namespace Volo.Abp.AspNetCore.Mvc.Validation
@ -22,6 +23,17 @@ namespace Volo.Abp.AspNetCore.Mvc.Validation
result.Error.ValidationErrors.Length.ShouldBeGreaterThan(0); 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] [Fact]
public async Task Should_Not_Validate_Action_Result_Success() 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) public override void ConfigureServices(ServiceConfigurationContext context)
{ {
context.Services.Configure<AbpAspNetCoreMvcOptions>(options => Configure<AbpAspNetCoreMvcOptions>(options =>
{ {
//2.0 Version //2.0 Version
options.ConventionalControllers.Create(typeof(AbpAspNetCoreMvcVersioningTestModule).Assembly, opts => 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.AddHttpClientProxies(typeof(AbpAspNetCoreMvcVersioningTestModule).Assembly);
context.Services.Configure<RemoteServiceOptions>(options => Configure<RemoteServiceOptions>(options =>
{ {
options.RemoteServices.Default = new RemoteServiceConfiguration("/"); 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) public override void ConfigureServices(ServiceConfigurationContext context)
{ {
context.Services.Configure<PermissionOptions>(options => Configure<PermissionOptions>(options =>
{ {
options.DefinitionProviders.TryAdd<AuthorizationTestPermissionDefinitionProvider>(); 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) public override void ConfigureServices(ServiceConfigurationContext context)
{ {
context.Services.Configure<AbpAutoMapperOptions>(options => Configure<AbpAutoMapperOptions>(options =>
{ {
options.UseStaticMapper = false; 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) public override void ConfigureServices(ServiceConfigurationContext context)
{ {
context.Services.Configure<AbpAutoMapperOptions>(options => Configure<AbpAutoMapperOptions>(options =>
{ {
options.UseStaticMapper = false; 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( _backgroundJobExecuter.Execute(
new JobExecutionContext( new JobExecutionContext(
ServiceProvider,
typeof(MyJob), typeof(MyJob),
new MyJobArgs("42") 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"); "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] [Fact]
public void ToEnum_Test() 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) public override void ConfigureServices(ServiceConfigurationContext context)
{ {
context.Services.Configure<DbConnectionOptions>(options => Configure<DbConnectionOptions>(options =>
{ {
options.ConnectionStrings.Default = DefaultConnString; options.ConnectionStrings.Default = DefaultConnString;
options.ConnectionStrings[Database1Name] = Database1ConnString; 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) public override void ConfigureServices(ServiceConfigurationContext context)
{ {
context.Services.Configure<VirtualFileSystemOptions>(options => Configure<VirtualFileSystemOptions>(options =>
{ {
options.FileSets.AddEmbedded<AbpEmailingTestModule>(); options.FileSets.AddEmbedded<AbpEmailingTestModule>();
}); });
context.Services.Configure<EmailTemplateOptions>(options => Configure<EmailTemplateOptions>(options =>
{ {
options.Templates["template1"] = options.Templates["template1"] =
new EmailTemplateDefinition("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(); var sqliteConnection = CreateDatabaseAndGetConnection();
context.Services.Configure<AbpDbContextOptions>(options => Configure<AbpDbContextOptions>(options =>
{ {
options.Configure(abpDbContextConfigurationContext => options.Configure(abpDbContextConfigurationContext =>
{ {

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

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