Browse Source

Merge branch 'dev' into dev

pull/2441/head
Halil İbrahim Kalkan 7 years ago
committed by GitHub
parent
commit
1a44e4fdde
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 8
      .github/labeler.yml
  2. 2
      .github/workflows/labeler.yml
  3. 2
      common.props
  4. 18
      docs/en/CLI.md
  5. 93
      docs/en/Modules/Docs.md
  6. BIN
      docs/en/images/docs-section-ui.png
  7. 10
      docs/zh-Hans/Tutorials/AspNetCore-Mvc/Part-I.md
  8. 27
      framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/CachedApplicationConfigurationClient.cs
  9. 2
      framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/ICachedApplicationConfigurationClient.cs
  10. 2
      framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/RemoteLocalizationContributor.cs
  11. 1
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.csproj
  12. 1
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo.Abp.AspNetCore.Mvc.UI.Bundling.csproj
  13. 1
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy.csproj
  14. 1
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo.Abp.AspNetCore.Mvc.UI.Packages.csproj
  15. 1
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.csproj
  16. 1
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.csproj
  17. 1
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Widgets/Volo.Abp.AspNetCore.Mvc.UI.Widgets.csproj
  18. 1
      framework/src/Volo.Abp.AspNetCore.Mvc.UI/Volo.Abp.AspNetCore.Mvc.UI.csproj
  19. 3
      framework/src/Volo.Abp.AspNetCore.Mvc/Volo.Abp.AspNetCore.Mvc.csproj
  20. 9
      framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcModule.cs
  21. 2
      framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcOptions.cs
  22. 17
      framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/AbpApplicationConfigurationScriptController.cs
  23. 15
      framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ProxyScripting/AbpServiceProxyScriptController.cs
  24. 4
      framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ProxyScripting/ServiceProxyGenerationModel.cs
  25. 27
      framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/AuditingInterceptor.cs
  26. 15
      framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/AuditingManager.cs
  27. 2
      framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/IAuditLogSaveHandle.cs
  28. 2
      framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/IAuditingStore.cs
  29. 7
      framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/SimpleLogAuditingStore.cs
  30. 7
      framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/AuthorizationInterceptor.cs
  31. 2
      framework/src/Volo.Abp.Autofac/Autofac/Builder/AbpRegistrationBuilderExtensions.cs
  32. 3
      framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/AbpBackgroundJobsAbstractionsModule.cs
  33. 20
      framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/AsyncBackgroundJob.cs
  34. 7
      framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/BackgroundJobArgsHelper.cs
  35. 17
      framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/BackgroundJobExecuter.cs
  36. 16
      framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/IAsyncBackgroundJob.cs
  37. 6
      framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/BackgroundJobWorker.cs
  38. 34
      framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/IBackgroundJobStore.cs
  39. 35
      framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/InMemoryBackgroundJobStore.cs
  40. 1
      framework/src/Volo.Abp.Castle.Core/Volo.Abp.Castle.Core.csproj
  41. 2
      framework/src/Volo.Abp.Castle.Core/Volo/Abp/Castle/AbpCastleCoreModule.cs
  42. 15
      framework/src/Volo.Abp.Castle.Core/Volo/Abp/Castle/DynamicProxy/AbpAsyncDeterminationInterceptor.cs
  43. 89
      framework/src/Volo.Abp.Castle.Core/Volo/Abp/Castle/DynamicProxy/CastleAbpInterceptorAdapter.cs
  44. 67
      framework/src/Volo.Abp.Castle.Core/Volo/Abp/Castle/DynamicProxy/CastleAbpMethodInvocationAdapter.cs
  45. 48
      framework/src/Volo.Abp.Castle.Core/Volo/Abp/Castle/DynamicProxy/CastleAbpMethodInvocationAdapterBase.cs
  46. 27
      framework/src/Volo.Abp.Castle.Core/Volo/Abp/Castle/DynamicProxy/CastleAbpMethodInvocationAdapterWithReturnValue.cs
  47. 36
      framework/src/Volo.Abp.Castle.Core/Volo/Abp/Castle/DynamicProxy/CastleAsyncAbpInterceptorAdapter.cs
  48. 6
      framework/src/Volo.Abp.Cli.Core/Volo.Abp.Cli.Core.csproj
  49. 2
      framework/src/Volo.Abp.Core/Volo.Abp.Core.csproj
  50. 12
      framework/src/Volo.Abp.Core/Volo/Abp/DynamicProxy/AbpInterceptor.cs
  51. 2
      framework/src/Volo.Abp.Core/Volo/Abp/DynamicProxy/IAbpInterceptor.cs
  52. 2
      framework/src/Volo.Abp.Core/Volo/Abp/DynamicProxy/IAbpMethodInvocation.cs
  53. 6
      framework/src/Volo.Abp.Ddd.Application.Contracts/Volo.Abp.Ddd.Application.Contracts.csproj
  54. 22
      framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/AbpDddApplicationContractsModule.cs
  55. 3
      framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/ILimitedResultRequest.cs
  56. 30
      framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/LimitedResultRequestDto.cs
  57. 9
      framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Localization/Resources/AbpDdd/AbpDddResource.cs
  58. 6
      framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Localization/Resources/AbpDdd/en.json
  59. 6
      framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Localization/Resources/AbpDdd/tr.json
  60. 6
      framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Localization/Resources/AbpDdd/zh-Hans.json
  61. 70
      framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/BasicRepositoryBase.cs
  62. 42
      framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/IBasicRepository.cs
  63. 31
      framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/IReadOnlyBasicRepository.cs
  64. 13
      framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/IRepository.cs
  65. 55
      framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/RepositoryBase.cs
  66. 7
      framework/src/Volo.Abp.Emailing/Volo.Abp.Emailing.csproj
  67. 8
      framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/AbpEmailingModule.cs
  68. 66
      framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/EmailSettingProvider.cs
  69. 10
      framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Localization/EmailingResource.cs
  70. 23
      framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Localization/en.json
  71. 23
      framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Localization/zh-Hans.json
  72. 2
      framework/src/Volo.Abp.EntityFrameworkCore.MySQL/Volo.Abp.EntityFrameworkCore.MySQL.csproj
  73. 73
      framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Domain/Repositories/EntityFrameworkCore/EfCoreRepository.cs
  74. 42
      framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContext.cs
  75. 13
      framework/src/Volo.Abp.Features/Volo/Abp/Features/FeatureInterceptor.cs
  76. 2
      framework/src/Volo.Abp.FluentValidation/Volo.Abp.FluentValidation.csproj
  77. 2
      framework/src/Volo.Abp.HangFire/Volo.Abp.HangFire.csproj
  78. 6
      framework/src/Volo.Abp.Http.Client/Microsoft/Extensions/DependencyInjection/ServiceCollectionDynamicHttpClientProxyExtensions.cs
  79. 45
      framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/DynamicHttpProxyInterceptor.cs
  80. 8
      framework/src/Volo.Abp.Http/Volo/Abp/Http/ProxyScripting/ProxyScriptManager.cs
  81. 5
      framework/src/Volo.Abp.Http/Volo/Abp/Http/ProxyScripting/ProxyScriptingModel.cs
  82. 2
      framework/src/Volo.Abp.IdentityModel/Volo.Abp.IdentityModel.csproj
  83. 4
      framework/src/Volo.Abp.Json/Volo.Abp.Json.csproj
  84. 3
      framework/src/Volo.Abp.Localization/Volo.Abp.Localization.csproj
  85. 11
      framework/src/Volo.Abp.Localization/Volo/Abp/Localization/AbpLocalizationModule.cs
  86. 14
      framework/src/Volo.Abp.Localization/Volo/Abp/Localization/LocalizationSettingProvider.cs
  87. 10
      framework/src/Volo.Abp.Localization/Volo/Abp/Localization/Resources/AbpLocalization/AbpLocalizationResource.cs
  88. 7
      framework/src/Volo.Abp.Localization/Volo/Abp/Localization/Resources/AbpLocalization/en.json
  89. 7
      framework/src/Volo.Abp.Localization/Volo/Abp/Localization/Resources/AbpLocalization/zh-Hans.json
  90. 5
      framework/src/Volo.Abp.Localization/Volo/Abp/Localization/Resources/AbpValidation/AbpValidationResource.cs
  91. 79
      framework/src/Volo.Abp.MemoryDb/Volo/Abp/Domain/Repositories/MemoryDb/MemoryDbRepository.cs
  92. 2
      framework/src/Volo.Abp.MongoDB/Volo.Abp.MongoDB.csproj
  93. 120
      framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/MongoDbRepository.cs
  94. 15
      framework/src/Volo.Abp.Uow/Volo/Abp/Uow/ChildUnitOfWork.cs
  95. 6
      framework/src/Volo.Abp.Uow/Volo/Abp/Uow/IUnitOfWork.cs
  96. 58
      framework/src/Volo.Abp.Uow/Volo/Abp/Uow/UnitOfWork.cs
  97. 15
      framework/src/Volo.Abp.Uow/Volo/Abp/Uow/UnitOfWorkInterceptor.cs
  98. 8
      framework/src/Volo.Abp.Validation/Volo.Abp.Validation.csproj
  99. 20
      framework/src/Volo.Abp.Validation/Volo/Abp/Validation/AbpValidationModule.cs
  100. 10
      framework/src/Volo.Abp.Validation/Volo/Abp/Validation/Localization/AbpValidationResource.cs

8
.github/labeler.yml

@ -1,7 +1,15 @@
ui-angular:
- npm/ng-packs/*
- npm/ng-packs/**/*
- npm/ng-packs/**/**/*
- npm/ng-packs/**/**/**/*
- npm/ng-packs/**/**/**/**/*
- npm/ng-packs/**/**/**/**/**/*
- templates/app/angular/*
- templates/app/angular/**/*
- templates/app/angular/**/**/*
- templates/app/angular/**/**/**/*
- templates/module/angular/*
- templates/module/angular/**/*
- templates/module/angular/**/**/*
- templates/module/angular/**/**/**/*

2
.github/workflows/labeler.yml

@ -1,7 +1,7 @@
name: Pull request labeler
on:
schedule:
- cron: '0 0 1 1 *'
- cron: '0 12 */1 * *'
jobs:
labeler:
runs-on: ubuntu-latest

2
common.props

@ -1,7 +1,7 @@
<Project>
<PropertyGroup>
<LangVersion>latest</LangVersion>
<Version>1.1.2</Version>
<Version>2.0.0</Version>
<NoWarn>$(NoWarn);CS1591</NoWarn>
<PackageIconUrl>https://abp.io/assets/abp_nupkg.png</PackageIconUrl>
<PackageProjectUrl>https://abp.io</PackageProjectUrl>

18
docs/en/CLI.md

@ -128,6 +128,24 @@ abp update [options]
* `--npm`: Only updates NPM packages.
* `--nuget`: Only updates NuGet packages.
### login
Some features of the CLI requires to be logged in to abp.io platform. To login with your username write
```bash
abp login <username>
```
Notice that, a new login with an already active session, will kill the previous session and creates a new one.
### logout
Logs you out by removing the session token from your computer.
```
abp logout
```
### help
Writes basic usage information of the CLI.

93
docs/en/Modules/Docs.md

@ -408,12 +408,101 @@ public class Person
```
~~~
As an example you can see ABP Framework documentation:
[https://github.com/abpframework/abp/blob/master/docs/en/](https://github.com/abpframework/abp/blob/master/docs/en/)
#### Conditional sections feature (Using Scriban)
Docs module uses [Scriban](<https://github.com/lunet-io/scriban/tree/master/doc> ) for conditionally show or hide some parts of a document. In order to use that feature, you have to create a JSON file as **Parameter document** per every language. It will contain all the key-values, as well as their display names.
For example, [en/docs-params.json](https://github.com/abpio/abp-commercial-docs/blob/master/en/docs-params.json):
```json
{
"parameters": [{
"name": "UI",
"displayName": "UI",
"values": {
"MVC": "MVC / Razor Pages",
"NG": "Angular"
}
},
{
"name": "DB",
"displayName": "Database",
"values": {
"EF": "Entity Framework Core",
"Mongo": "MongoDB"
}
},
{
"name": "Tiered",
"displayName": "Tiered",
"values": {
"No": "Not Tiered",
"Yes": "Tiered"
}
}]
}
```
Since not every single document in your projects may not have sections or may not need all of those parameters, you have to declare which of those parameters will be used for sectioning the document, as a JSON block anywhere on the document.
For example [Getting-Started.md](https://github.com/abpio/abp-commercial-docs/blob/master/en/Getting-Started.md):
```
.....
​````json
//[doc-params]
{
"UI": ["MVC","NG"],
"DB": ["EF", "Mongo"],
"Tiered": ["Yes", "No"]
}
​````
........
```
This section will be automatically deleted during render. And f course, those key values must match with the ones in **Parameter document**.
![Interface](..\images\docs-section-ui.png)
Now you can use **Scriban** syntax to create sections in your document.
For example:
````
{{ if UI == "NG" }}
* `-u` argument specifies the UI framework, `angular` in this case.
{{ end }}
{{ if DB == "Mongo" }}
* `-d` argument specifies the database provider, `mongodb` in this case.
{{ end }}
{{ if Tiered == "Yes" }}
* `--tiered` argument is used to create N-tiered solution where authentication server, UI and API layers are physically separated.
{{ end }}
````
You can also use variables in a text, adding **_Value** postfix to its key:
````
This document assumes that you prefer to use **{{ UI_Value }}** as the UI framework and **{{ DB_Value }}** as the database provider.
````
**IMPORTANT NOTICE**: Scriban uses "{{" and "}}" for syntax. Therefore, you must use escape blocks if you are going to use those in your document (an Angular document, for example). See [Scriban docs](<https://github.com/lunet-io/scriban/blob/master/doc/language.md#13-escape-block> ) for more information.
### 8- Creating the Navigation Document
Navigation document is the main menu of the documents page. It is located on the left side of the page. It is a `JSON` file. Take a look at the below sample navigation document to understand the structure.

BIN
docs/en/images/docs-section-ui.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

10
docs/zh-Hans/Tutorials/AspNetCore-Mvc/Part-I.md

@ -225,7 +225,7 @@ using Volo.Abp.Application.Services;
namespace Acme.BookStore
{
public interface IBookAppService :
IAsyncCrudAppService< //定义了CRUD方法
ICrudAppService< //定义了CRUD方法
BookDto, //用来展示书籍
Guid, //Book实体的主键
PagedAndSortedResultRequestDto, //获取书籍的时候用于分页和排序
@ -238,8 +238,8 @@ namespace Acme.BookStore
````
* 框架定义应用程序服务的接口<u>不是必需的</u>. 但是,它被建议作为最佳实践.
* `IAsyncCrudAppService`定义了常见的**CRUD**方法:`GetAsync`,`GetListAsync`,`CreateAsync`,`UpdateAsync`和`DeleteAsync`. 你可以从空的`IApplicationService`接口继承并手动定义自己的方法.
* `IAsyncCrudAppService`有一些变体, 你可以在每个方法中使用单独的DTO,也可以分别单独指定.
* `ICrudAppService`定义了常见的**CRUD**方法:`GetAsync`,`GetListAsync`,`CreateAsync`,`UpdateAsync`和`DeleteAsync`. 你可以从空的`IApplicationService`接口继承并手动定义自己的方法.
* `ICrudAppService`有一些变体, 你可以在每个方法中使用单独的DTO,也可以分别单独指定.
#### BookAppService
@ -255,7 +255,7 @@ using Volo.Abp.Domain.Repositories;
namespace Acme.BookStore
{
public class BookAppService :
AsyncCrudAppService<Book, BookDto, Guid, PagedAndSortedResultRequestDto,
CrudAppService<Book, BookDto, Guid, PagedAndSortedResultRequestDto,
CreateUpdateBookDto, CreateUpdateBookDto>,
IBookAppService
{
@ -268,7 +268,7 @@ namespace Acme.BookStore
}
````
* `BookAppService`继承了`AsyncCrudAppService<...>`.`AsyncCrudAppService<...>`实现了上面定义的CRUD方法.
* `BookAppService`继承了`CrudAppService<...>`.实现了上面定义的CRUD方法.
* `BookAppService`注入`IRepository <Book,Guid>`,这是`Book`实体的默认仓储. ABP自动为每个聚合根(或实体)创建默认仓储. 请参阅[仓储文档](../../Repositories.md)
* `BookAppService`使用`IObjectMapper`将`Book`对象转换为`BookDto`对象, 将`CreateUpdateBookDto`对象转换为`Book`对象. 启动模板使用[AutoMapper](http://automapper.org/)库作为对象映射提供程序. 你之前定义了映射, 因此它将按预期工作.

27
framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/CachedApplicationConfigurationClient.cs

@ -31,33 +31,6 @@ namespace Volo.Abp.AspNetCore.Mvc.Client
Cache = cache;
}
public ApplicationConfigurationDto Get()
{
var cacheKey = CreateCacheKey();
var httpContext = HttpContextAccessor?.HttpContext;
if (httpContext != null && httpContext.Items[cacheKey] is ApplicationConfigurationDto configuration)
{
return configuration;
}
configuration = Cache.GetOrAdd(
cacheKey,
() => AsyncHelper.RunSync(Proxy.Service.GetAsync),
() => new DistributedCacheEntryOptions
{
AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(120) //TODO: Should be configurable. Default value should be higher (5 mins would be good).
}
);
if (httpContext != null)
{
httpContext.Items[cacheKey] = configuration;
}
return configuration;
}
public async Task<ApplicationConfigurationDto> GetAsync()
{
var cacheKey = CreateCacheKey();

2
framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/ICachedApplicationConfigurationClient.cs

@ -5,8 +5,6 @@ namespace Volo.Abp.AspNetCore.Mvc.Client
{
public interface ICachedApplicationConfigurationClient
{
ApplicationConfigurationDto Get();
Task<ApplicationConfigurationDto> GetAsync();
}
}

2
framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/RemoteLocalizationContributor.cs

@ -55,7 +55,7 @@ namespace Volo.Abp.AspNetCore.Mvc.Client
private Dictionary<string, string> GetResourceOrNull()
{
var applicationConfigurationDto = _applicationConfigurationClient.Get();
var applicationConfigurationDto = AsyncHelper.RunSync(() => _applicationConfigurationClient.GetAsync());
var resource = applicationConfigurationDto
.Localization.Values

1
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.csproj

@ -4,6 +4,7 @@
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<AddRazorSupportForMvc>true</AddRazorSupportForMvc>
<AssemblyName>Volo.Abp.AspNetCore.Mvc.UI.Bootstrap</AssemblyName>
<PackageId>Volo.Abp.AspNetCore.Mvc.UI.Bootstrap</PackageId>
<AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback>

1
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo.Abp.AspNetCore.Mvc.UI.Bundling.csproj

@ -4,6 +4,7 @@
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<AddRazorSupportForMvc>true</AddRazorSupportForMvc>
<AssemblyName>Volo.Abp.AspNetCore.Mvc.UI.Bundling</AssemblyName>
<PackageId>Volo.Abp.AspNetCore.Mvc.UI.Bundling</PackageId>
<IsPackable>true</IsPackable>

1
framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy.csproj

@ -4,6 +4,7 @@
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<AddRazorSupportForMvc>true</AddRazorSupportForMvc>
<AssemblyName>Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy</AssemblyName>
<PackageId>Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy</PackageId>
<AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback>

1
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo.Abp.AspNetCore.Mvc.UI.Packages.csproj

@ -4,6 +4,7 @@
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<AddRazorSupportForMvc>true</AddRazorSupportForMvc>
<AssemblyName>Volo.Abp.AspNetCore.Mvc.UI.Packages</AssemblyName>
<PackageId>Volo.Abp.AspNetCore.Mvc.UI.Packages</PackageId>
<IsPackable>true</IsPackable>

1
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.csproj

@ -4,6 +4,7 @@
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<AddRazorSupportForMvc>true</AddRazorSupportForMvc>
<AssemblyName>Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic</AssemblyName>
<PackageId>Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic</PackageId>
<AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback>

1
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.csproj

@ -4,6 +4,7 @@
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<AddRazorSupportForMvc>true</AddRazorSupportForMvc>
<AssemblyName>Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared</AssemblyName>
<PackageId>Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared</PackageId>
<AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback>

1
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Widgets/Volo.Abp.AspNetCore.Mvc.UI.Widgets.csproj

@ -4,6 +4,7 @@
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<AddRazorSupportForMvc>true</AddRazorSupportForMvc>
<AssemblyName>Volo.Abp.AspNetCore.Mvc.UI.Widgets</AssemblyName>
<PackageId>Volo.Abp.AspNetCore.Mvc.UI.Widgets</PackageId>
<IsPackable>true</IsPackable>

1
framework/src/Volo.Abp.AspNetCore.Mvc.UI/Volo.Abp.AspNetCore.Mvc.UI.csproj

@ -4,6 +4,7 @@
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<AddRazorSupportForMvc>true</AddRazorSupportForMvc>
<AssemblyName>Volo.Abp.AspNetCore.Mvc.UI</AssemblyName>
<PackageId>Volo.Abp.AspNetCore.Mvc.UI</PackageId>
<AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback>

3
framework/src/Volo.Abp.AspNetCore.Mvc/Volo.Abp.AspNetCore.Mvc.csproj

@ -4,6 +4,7 @@
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<AddRazorSupportForMvc>true</AddRazorSupportForMvc>
<AssemblyName>Volo.Abp.AspNetCore.Mvc</AssemblyName>
<PackageId>Volo.Abp.AspNetCore.Mvc</PackageId>
<AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback>
@ -25,7 +26,7 @@
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="3.1.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Versioning" Version="4.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Versioning" Version="4.1.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.1.0" />
</ItemGroup>

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

@ -12,6 +12,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Microsoft.Extensions.Hosting;
using Volo.Abp.ApiVersioning;
using Volo.Abp.AspNetCore.Mvc.Conventions;
using Volo.Abp.AspNetCore.Mvc.DependencyInjection;
@ -64,6 +65,14 @@ namespace Volo.Abp.AspNetCore.Mvc
options.IgnoredInterfaces.AddIfNotContains(typeof(IActionFilter));
});
context.Services.PostConfigure<AbpAspNetCoreMvcOptions>(options =>
{
if (options.MinifyGeneratedScript == null)
{
options.MinifyGeneratedScript = context.Services.GetHostingEnvironment().IsProduction();
}
});
var mvcCoreBuilder = context.Services.AddMvcCore();
context.Services.ExecutePreConfiguredActions(mvcCoreBuilder);

2
framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcOptions.cs

@ -4,6 +4,8 @@ namespace Volo.Abp.AspNetCore.Mvc
{
public class AbpAspNetCoreMvcOptions
{
public bool? MinifyGeneratedScript { get; set; }
public AbpConventionalControllerOptions ConventionalControllers { get; }
public AbpAspNetCoreMvcOptions()

17
framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/AbpApplicationConfigurationScriptController.cs

@ -2,10 +2,12 @@
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using Microsoft.Extensions.Logging;
using Volo.Abp.Auditing;
using Volo.Abp.Http;
using Volo.Abp.Json;
using Volo.Abp.Minify.Scripts;
namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations
{
@ -16,19 +18,30 @@ namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations
{
private readonly IAbpApplicationConfigurationAppService _configurationAppService;
private readonly IJsonSerializer _jsonSerializer;
private readonly AbpAspNetCoreMvcOptions _options;
private readonly IJavascriptMinifier _javascriptMinifier;
public AbpApplicationConfigurationScriptController(
IAbpApplicationConfigurationAppService configurationAppService,
IJsonSerializer jsonSerializer)
IJsonSerializer jsonSerializer,
IOptions<AbpAspNetCoreMvcOptions> options,
IJavascriptMinifier javascriptMinifier)
{
_configurationAppService = configurationAppService;
_jsonSerializer = jsonSerializer;
_options = options.Value;
_javascriptMinifier = javascriptMinifier;
}
[HttpGet]
[Produces(MimeTypes.Application.Javascript, MimeTypes.Text.Plain)]
public async Task<ActionResult> Get()
{
var script = CreateAbpExtendScript(await _configurationAppService.GetAsync());
return Content(_options.MinifyGeneratedScript == true ? _javascriptMinifier.Minify(script) : script,
MimeTypes.Application.Javascript
Logger.LogDebug("Executing AbpApplicationConfigurationScriptController.Get()");
var result = CreateAbpExtendScript(
@ -46,7 +59,7 @@ namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations
script.AppendLine("(function(){");
script.AppendLine();
script.AppendLine($"$.extend(true, abp, {_jsonSerializer.Serialize(config, indented: Debugger.IsAttached)})");
script.AppendLine($"$.extend(true, abp, {_jsonSerializer.Serialize(config, indented: true)})");
script.AppendLine();
script.AppendLine("abp.event.trigger('abp.configurationInitialized');");
script.AppendLine();

15
framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ProxyScripting/AbpServiceProxyScriptController.cs

@ -1,7 +1,9 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using Volo.Abp.Auditing;
using Volo.Abp.Http;
using Volo.Abp.Http.ProxyScripting;
using Volo.Abp.Minify.Scripts;
namespace Volo.Abp.AspNetCore.Mvc.ProxyScripting
{
@ -11,10 +13,16 @@ namespace Volo.Abp.AspNetCore.Mvc.ProxyScripting
public class AbpServiceProxyScriptController : AbpController
{
private readonly IProxyScriptManager _proxyScriptManager;
private readonly AbpAspNetCoreMvcOptions _options;
private readonly IJavascriptMinifier _javascriptMinifier;
public AbpServiceProxyScriptController(IProxyScriptManager proxyScriptManager)
public AbpServiceProxyScriptController(IProxyScriptManager proxyScriptManager,
IOptions<AbpAspNetCoreMvcOptions> options,
IJavascriptMinifier javascriptMinifier)
{
_proxyScriptManager = proxyScriptManager;
_options = options.Value;
_javascriptMinifier = javascriptMinifier;
}
[HttpGet]
@ -22,7 +30,10 @@ namespace Volo.Abp.AspNetCore.Mvc.ProxyScripting
public ActionResult GetAll(ServiceProxyGenerationModel model)
{
model.Normalize();
return Content(_proxyScriptManager.GetScript(model.CreateOptions()), MimeTypes.Application.Javascript);
var script = _proxyScriptManager.GetScript(model.CreateOptions());
return Content(_options.MinifyGeneratedScript == true ? _javascriptMinifier.Minify(script) : script,
MimeTypes.Application.Javascript);
}
}
}

4
framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ProxyScripting/ServiceProxyGenerationModel.cs

@ -11,8 +11,6 @@ namespace Volo.Abp.AspNetCore.Mvc.ProxyScripting
public bool UseCache { get; set; }
public bool Minify { get; set; }
public string Modules { get; set; }
public string Controllers { get; set; }
@ -34,7 +32,7 @@ namespace Volo.Abp.AspNetCore.Mvc.ProxyScripting
public ProxyScriptingModel CreateOptions()
{
var options = new ProxyScriptingModel(Type, UseCache, Minify);
var options = new ProxyScriptingModel(Type, UseCache);
if (!Modules.IsNullOrEmpty())
{

27
framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/AuditingInterceptor.cs

@ -18,33 +18,6 @@ namespace Volo.Abp.Auditing
_auditingManager = auditingManager;
}
public override void Intercept(IAbpMethodInvocation invocation)
{
if (!ShouldIntercept(invocation, out var auditLog, out var auditLogAction))
{
invocation.Proceed();
return;
}
var stopwatch = Stopwatch.StartNew();
try
{
invocation.Proceed();
}
catch (Exception ex)
{
auditLog.Exceptions.Add(ex);
throw;
}
finally
{
stopwatch.Stop();
auditLogAction.ExecutionDuration = Convert.ToInt32(stopwatch.Elapsed.TotalMilliseconds);
auditLog.Actions.Add(auditLogAction);
}
}
public override async Task InterceptAsync(IAbpMethodInvocation invocation)
{
if (!ShouldIntercept(invocation, out var auditLog, out var auditLogAction))

15
framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/AuditingManager.cs

@ -120,16 +120,6 @@ namespace Volo.Abp.Auditing
}
}
protected virtual void Save(DisposableSaveHandle saveHandle)
{
BeforeSave(saveHandle);
if (ShouldSave(saveHandle.AuditLog))
{
_auditingStore.Save(saveHandle.AuditLog);
}
}
protected bool ShouldSave(AuditLogInfo auditLog)
{
if (!auditLog.Actions.Any() && !auditLog.EntityChanges.Any())
@ -165,11 +155,6 @@ namespace Volo.Abp.Auditing
await _auditingManager.SaveAsync(this);
}
public void Save()
{
_auditingManager.Save(this);
}
public void Dispose()
{
_scope.Dispose();

2
framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/IAuditLogSaveHandle.cs

@ -5,8 +5,6 @@ namespace Volo.Abp.Auditing
{
public interface IAuditLogSaveHandle : IDisposable
{
void Save();
Task SaveAsync();
}
}

2
framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/IAuditingStore.cs

@ -4,8 +4,6 @@ namespace Volo.Abp.Auditing
{
public interface IAuditingStore
{
void Save(AuditLogInfo auditInfo);
Task SaveAsync(AuditLogInfo auditInfo);
}
}

7
framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/SimpleLogAuditingStore.cs

@ -15,14 +15,9 @@ namespace Volo.Abp.Auditing
Logger = NullLogger<SimpleLogAuditingStore>.Instance;
}
public void Save(AuditLogInfo auditInfo)
{
Logger.LogInformation(auditInfo.ToString());
}
public Task SaveAsync(AuditLogInfo auditInfo)
{
Save(auditInfo);
Logger.LogInformation(auditInfo.ToString());
return Task.FromResult(0);
}
}

7
framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/AuthorizationInterceptor.cs

@ -1,7 +1,6 @@
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
using Volo.Abp.DynamicProxy;
using Volo.Abp.Threading;
namespace Volo.Abp.Authorization
{
@ -14,12 +13,6 @@ namespace Volo.Abp.Authorization
_methodInvocationAuthorizationService = methodInvocationAuthorizationService;
}
public override void Intercept(IAbpMethodInvocation invocation)
{
AsyncHelper.RunSync(() => AuthorizeAsync(invocation));
invocation.Proceed();
}
public override async Task InterceptAsync(IAbpMethodInvocation invocation)
{
await AuthorizeAsync(invocation);

2
framework/src/Volo.Abp.Autofac/Autofac/Builder/AbpRegistrationBuilderExtensions.cs

@ -89,7 +89,7 @@ namespace Autofac.Builder
foreach (var interceptor in interceptors)
{
registrationBuilder.InterceptedBy(
typeof(CastleAbpInterceptorAdapter<>).MakeGenericType(interceptor)
typeof(AbpAsyncDeterminationInterceptor<>).MakeGenericType(interceptor)
);
}

3
framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/AbpBackgroundJobsAbstractionsModule.cs

@ -23,7 +23,8 @@ namespace Volo.Abp.BackgroundJobs
services.OnRegistred(context =>
{
if (ReflectionHelper.IsAssignableToGenericType(context.ImplementationType, typeof(IBackgroundJob<>)))
if (ReflectionHelper.IsAssignableToGenericType(context.ImplementationType, typeof(IBackgroundJob<>)) ||
ReflectionHelper.IsAssignableToGenericType(context.ImplementationType, typeof(IAsyncBackgroundJob<>)))
{
jobTypes.Add(context.ImplementationType);
}

20
framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/AsyncBackgroundJob.cs

@ -0,0 +1,20 @@
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
namespace Volo.Abp.BackgroundJobs
{
public abstract class AsyncBackgroundJob<TArgs> : IAsyncBackgroundJob<TArgs>
{
//TODO: Add UOW, Localization and other useful properties..?
public ILogger<AsyncBackgroundJob<TArgs>> Logger { get; set; }
protected AsyncBackgroundJob()
{
Logger = NullLogger<AsyncBackgroundJob<TArgs>>.Instance;
}
public abstract Task ExecuteAsync(TArgs args);
}
}

7
framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/BackgroundJobArgsHelper.cs

@ -13,7 +13,8 @@ namespace Volo.Abp.BackgroundJobs
continue;
}
if (@interface.GetGenericTypeDefinition() != typeof(IBackgroundJob<>))
if (@interface.GetGenericTypeDefinition() != typeof(IBackgroundJob<>) &&
@interface.GetGenericTypeDefinition() != typeof(IAsyncBackgroundJob<>))
{
continue;
}
@ -27,7 +28,9 @@ namespace Volo.Abp.BackgroundJobs
return genericArgs[0];
}
throw new AbpException($"Could not find type of the job args. Ensure that given type implements the {typeof(IBackgroundJob<>).AssemblyQualifiedName} interface. Given job type: {jobType.AssemblyQualifiedName}");
throw new AbpException($"Could not find type of the job args. " +
$"Ensure that given type implements the {typeof(IBackgroundJob<>).AssemblyQualifiedName} or {typeof(IAsyncBackgroundJob<>).AssemblyQualifiedName} interface. " +
$"Given job type: {jobType.AssemblyQualifiedName}");
}
}
}

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

@ -2,7 +2,9 @@
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options;
using System;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Threading;
namespace Volo.Abp.BackgroundJobs
{
@ -27,15 +29,24 @@ namespace Volo.Abp.BackgroundJobs
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)) ??
context.JobType.GetMethod(nameof(IAsyncBackgroundJob<object>.ExecuteAsync));
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} or {typeof(IAsyncBackgroundJob<>).Name}. " +
"The job type was: " + context.JobType);
}
try
{
jobExecuteMethod.Invoke(job, new[] { context.JobArgs });
if (jobExecuteMethod.Name == nameof(IAsyncBackgroundJob<object>.ExecuteAsync))
{
AsyncHelper.RunSync(() => (Task) jobExecuteMethod.Invoke(job, new[] {context.JobArgs}));
}
else
{
jobExecuteMethod.Invoke(job, new[] { context.JobArgs });
}
}
catch (Exception ex)
{

16
framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/IAsyncBackgroundJob.cs

@ -0,0 +1,16 @@
using System.Threading.Tasks;
namespace Volo.Abp.BackgroundJobs
{
/// <summary>
/// Defines interface of a background job.
/// </summary>
public interface IAsyncBackgroundJob<in TArgs>
{
/// <summary>
/// Executes the job with the <see cref="args"/>.
/// </summary>
/// <param name="args">Job arguments.</param>
Task ExecuteAsync(TArgs args);
}
}

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

@ -36,7 +36,7 @@ namespace Volo.Abp.BackgroundJobs
{
var store = scope.ServiceProvider.GetRequiredService<IBackgroundJobStore>();
var waitingJobs = store.GetWaitingJobs(WorkerOptions.MaxJobFetchCount);
var waitingJobs = AsyncHelper.RunSync(() => store.GetWaitingJobsAsync(WorkerOptions.MaxJobFetchCount));
if (!waitingJobs.Any())
{
@ -62,7 +62,7 @@ namespace Volo.Abp.BackgroundJobs
{
jobExecuter.Execute(context);
store.Delete(jobInfo.Id);
AsyncHelper.RunSync(() => store.DeleteAsync(jobInfo.Id));
}
catch (BackgroundJobExecutionException)
{
@ -94,7 +94,7 @@ namespace Volo.Abp.BackgroundJobs
{
try
{
store.Update(jobInfo);
AsyncHelper.RunSync(() => store.UpdateAsync(jobInfo));
}
catch (Exception updateEx)
{

34
framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/IBackgroundJobStore.cs

@ -9,13 +9,6 @@ namespace Volo.Abp.BackgroundJobs
/// </summary>
public interface IBackgroundJobStore
{
/// <summary>
/// Gets a BackgroundJobInfo based on the given jobId.
/// </summary>
/// <param name="jobId">The Job Unique Identifier.</param>
/// <returns>The BackgroundJobInfo object.</returns>
BackgroundJobInfo Find(Guid jobId);
/// <summary>
/// Gets a BackgroundJobInfo based on the given jobId.
/// </summary>
@ -23,27 +16,12 @@ namespace Volo.Abp.BackgroundJobs
/// <returns>The BackgroundJobInfo object.</returns>
Task<BackgroundJobInfo> FindAsync(Guid jobId);
/// <summary>
/// Inserts a background job.
/// </summary>
/// <param name="jobInfo">Job information.</param>
void Insert(BackgroundJobInfo jobInfo);
/// <summary>
/// Inserts a background job.
/// </summary>
/// <param name="jobInfo">Job information.</param>
Task InsertAsync(BackgroundJobInfo jobInfo);
/// <summary>
/// Gets waiting jobs. It should get jobs based on these:
/// Conditions: !IsAbandoned And NextTryTime &lt;= Clock.Now.
/// Order by: Priority DESC, TryCount ASC, NextTryTime ASC.
/// Maximum result: <paramref name="maxResultCount"/>.
/// </summary>
/// <param name="maxResultCount">Maximum result count.</param>
List<BackgroundJobInfo> GetWaitingJobs(int maxResultCount);
/// <summary>
/// Gets waiting jobs. It should get jobs based on these:
/// Conditions: !IsAbandoned And NextTryTime &lt;= Clock.Now.
@ -53,24 +31,12 @@ namespace Volo.Abp.BackgroundJobs
/// <param name="maxResultCount">Maximum result count.</param>
Task<List<BackgroundJobInfo>> GetWaitingJobsAsync(int maxResultCount);
/// <summary>
/// Deletes a job.
/// </summary>
/// <param name="jobId">The Job Unique Identifier.</param>
void Delete(Guid jobId);
/// <summary>
/// Deletes a job.
/// </summary>
/// <param name="jobId">The Job Unique Identifier.</param>
Task DeleteAsync(Guid jobId);
/// <summary>
/// Updates a job.
/// </summary>
/// <param name="jobInfo">Job information.</param>
void Update(BackgroundJobInfo jobInfo);
/// <summary>
/// Updates a job.
/// </summary>

35
framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/InMemoryBackgroundJobStore.cs

@ -23,21 +23,11 @@ namespace Volo.Abp.BackgroundJobs
_jobs = new ConcurrentDictionary<Guid, BackgroundJobInfo>();
}
public BackgroundJobInfo Find(Guid jobId)
{
return _jobs.GetOrDefault(jobId);
}
public virtual Task<BackgroundJobInfo> FindAsync(Guid jobId)
{
return Task.FromResult(_jobs.GetOrDefault(jobId));
}
public void Insert(BackgroundJobInfo jobInfo)
{
_jobs[jobInfo.Id] = jobInfo;
}
public virtual Task InsertAsync(BackgroundJobInfo jobInfo)
{
_jobs[jobInfo.Id] = jobInfo;
@ -45,17 +35,6 @@ namespace Volo.Abp.BackgroundJobs
return Task.FromResult(0);
}
public List<BackgroundJobInfo> GetWaitingJobs(int maxResultCount)
{
return _jobs.Values
.Where(t => !t.IsAbandoned && t.NextTryTime <= Clock.Now)
.OrderByDescending(t => t.Priority)
.ThenBy(t => t.TryCount)
.ThenBy(t => t.NextTryTime)
.Take(maxResultCount)
.ToList();
}
public virtual Task<List<BackgroundJobInfo>> GetWaitingJobsAsync(int maxResultCount)
{
var waitingJobs = _jobs.Values
@ -69,10 +48,6 @@ namespace Volo.Abp.BackgroundJobs
return Task.FromResult(waitingJobs);
}
public void Delete(Guid jobId)
{
_jobs.TryRemove(jobId, out _);
}
public virtual Task DeleteAsync(Guid jobId)
{
@ -80,15 +55,7 @@ namespace Volo.Abp.BackgroundJobs
return Task.FromResult(0);
}
public void Update(BackgroundJobInfo jobInfo)
{
if (jobInfo.IsAbandoned)
{
DeleteAsync(jobInfo.Id);
}
}
public virtual Task UpdateAsync(BackgroundJobInfo jobInfo)
{
if (jobInfo.IsAbandoned)

1
framework/src/Volo.Abp.Castle.Core/Volo.Abp.Castle.Core.csproj

@ -15,6 +15,7 @@
<ItemGroup>
<PackageReference Include="Castle.Core" Version="4.4.0" />
<PackageReference Include="Castle.Core.AsyncInterceptor" Version="2.0.21-alpha" />
</ItemGroup>
<ItemGroup>

2
framework/src/Volo.Abp.Castle.Core/Volo/Abp/Castle/AbpCastleCoreModule.cs

@ -8,7 +8,7 @@ namespace Volo.Abp.Castle
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.AddTransient(typeof(CastleAbpInterceptorAdapter<>));
context.Services.AddTransient(typeof(AbpAsyncDeterminationInterceptor<>));
}
}
}

15
framework/src/Volo.Abp.Castle.Core/Volo/Abp/Castle/DynamicProxy/AbpAsyncDeterminationInterceptor.cs

@ -0,0 +1,15 @@
using Castle.DynamicProxy;
using Volo.Abp.DynamicProxy;
namespace Volo.Abp.Castle.DynamicProxy
{
public class AbpAsyncDeterminationInterceptor<TInterceptor> : AsyncDeterminationInterceptor
where TInterceptor : IAbpInterceptor
{
public AbpAsyncDeterminationInterceptor(TInterceptor abpInterceptor)
: base(new CastleAsyncAbpInterceptorAdapter<TInterceptor>(abpInterceptor))
{
}
}
}

89
framework/src/Volo.Abp.Castle.Core/Volo/Abp/Castle/DynamicProxy/CastleAbpInterceptorAdapter.cs

@ -1,89 +0,0 @@
using System.Reflection;
using System.Threading.Tasks;
using Castle.DynamicProxy;
using Volo.Abp.DynamicProxy;
using Volo.Abp.Threading;
namespace Volo.Abp.Castle.DynamicProxy
{
public class CastleAbpInterceptorAdapter<TInterceptor> : IInterceptor
where TInterceptor : IAbpInterceptor
{
private static readonly MethodInfo MethodExecuteWithoutReturnValueAsync =
typeof(CastleAbpInterceptorAdapter<TInterceptor>)
.GetMethod(
nameof(ExecuteWithoutReturnValueAsync),
BindingFlags.NonPublic | BindingFlags.Instance
);
private static readonly MethodInfo MethodExecuteWithReturnValueAsync =
typeof(CastleAbpInterceptorAdapter<TInterceptor>)
.GetMethod(
nameof(ExecuteWithReturnValueAsync),
BindingFlags.NonPublic | BindingFlags.Instance
);
private readonly TInterceptor _abpInterceptor;
public CastleAbpInterceptorAdapter(TInterceptor abpInterceptor)
{
_abpInterceptor = abpInterceptor;
}
public void Intercept(IInvocation invocation)
{
var proceedInfo = invocation.CaptureProceedInfo();
var method = invocation.MethodInvocationTarget ?? invocation.Method;
if (method.IsAsync())
{
InterceptAsyncMethod(invocation, proceedInfo);
}
else
{
InterceptSyncMethod(invocation, proceedInfo);
}
}
private void InterceptSyncMethod(IInvocation invocation, IInvocationProceedInfo proceedInfo)
{
_abpInterceptor.Intercept(new CastleAbpMethodInvocationAdapter(invocation, proceedInfo));
}
private void InterceptAsyncMethod(IInvocation invocation, IInvocationProceedInfo proceedInfo)
{
if (invocation.Method.ReturnType == typeof(Task))
{
invocation.ReturnValue = MethodExecuteWithoutReturnValueAsync
.Invoke(this, new object[] { invocation, proceedInfo });
}
else
{
invocation.ReturnValue = MethodExecuteWithReturnValueAsync
.MakeGenericMethod(invocation.Method.ReturnType.GenericTypeArguments[0])
.Invoke(this, new object[] {invocation, proceedInfo});
}
}
private async Task ExecuteWithoutReturnValueAsync(IInvocation invocation, IInvocationProceedInfo proceedInfo)
{
await Task.Yield();
await _abpInterceptor.InterceptAsync(
new CastleAbpMethodInvocationAdapter(invocation, proceedInfo)
);
}
private async Task<T> ExecuteWithReturnValueAsync<T>(IInvocation invocation, IInvocationProceedInfo proceedInfo)
{
await Task.Yield();
await _abpInterceptor.InterceptAsync(
new CastleAbpMethodInvocationAdapter(invocation, proceedInfo)
);
return await (Task<T>)invocation.ReturnValue;
}
}
}

67
framework/src/Volo.Abp.Castle.Core/Volo/Abp/Castle/DynamicProxy/CastleAbpMethodInvocationAdapter.cs

@ -1,77 +1,26 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Threading.Tasks;
using Castle.DynamicProxy;
using Volo.Abp.DynamicProxy;
using Volo.Abp.Threading;
namespace Volo.Abp.Castle.DynamicProxy
{
public class CastleAbpMethodInvocationAdapter : IAbpMethodInvocation
public class CastleAbpMethodInvocationAdapter : CastleAbpMethodInvocationAdapterBase, IAbpMethodInvocation
{
public object[] Arguments => Invocation.Arguments;
public IReadOnlyDictionary<string, object> ArgumentsDictionary => _lazyArgumentsDictionary.Value;
private readonly Lazy<IReadOnlyDictionary<string, object>> _lazyArgumentsDictionary;
public Type[] GenericArguments => Invocation.GenericArguments;
public object TargetObject => Invocation.InvocationTarget ?? Invocation.MethodInvocationTarget;
public MethodInfo Method => Invocation.MethodInvocationTarget ?? Invocation.Method;
public object ReturnValue
{
get => _actualReturnValue ?? Invocation.ReturnValue;
set => Invocation.ReturnValue = value;
}
private object _actualReturnValue;
protected IInvocation Invocation { get; }
protected IInvocationProceedInfo ProceedInfo { get; }
protected Func<IInvocation, IInvocationProceedInfo, Task> Proceed { get; }
public CastleAbpMethodInvocationAdapter(IInvocation invocation, IInvocationProceedInfo proceedInfo)
public CastleAbpMethodInvocationAdapter(IInvocation invocation, IInvocationProceedInfo proceedInfo,
Func<IInvocation, IInvocationProceedInfo, Task> proceed)
: base(invocation)
{
Invocation = invocation;
ProceedInfo = proceedInfo;
_lazyArgumentsDictionary = new Lazy<IReadOnlyDictionary<string, object>>(GetArgumentsDictionary);
Proceed = proceed;
}
public void Proceed()
public override async Task ProceedAsync()
{
ProceedInfo.Invoke();
if (Invocation.Method.IsAsync())
{
AsyncHelper.RunSync(() => (Task)Invocation.ReturnValue);
}
}
public Task ProceedAsync()
{
ProceedInfo.Invoke();
_actualReturnValue = Invocation.ReturnValue;
return Invocation.Method.IsAsync()
? (Task)_actualReturnValue
: Task.FromResult(_actualReturnValue);
}
private IReadOnlyDictionary<string, object> GetArgumentsDictionary()
{
var dict = new Dictionary<string, object>();
var methodParameters = Method.GetParameters();
for (int i = 0; i < methodParameters.Length; i++)
{
dict[methodParameters[i].Name] = Invocation.Arguments[i];
}
return dict;
await Proceed(Invocation, ProceedInfo);
}
}
}

48
framework/src/Volo.Abp.Castle.Core/Volo/Abp/Castle/DynamicProxy/CastleAbpMethodInvocationAdapterBase.cs

@ -0,0 +1,48 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Threading.Tasks;
using Castle.DynamicProxy;
using Volo.Abp.DynamicProxy;
namespace Volo.Abp.Castle.DynamicProxy
{
public abstract class CastleAbpMethodInvocationAdapterBase : IAbpMethodInvocation
{
public object[] Arguments => Invocation.Arguments;
public IReadOnlyDictionary<string, object> ArgumentsDictionary => _lazyArgumentsDictionary.Value;
private readonly Lazy<IReadOnlyDictionary<string, object>> _lazyArgumentsDictionary;
public Type[] GenericArguments => Invocation.GenericArguments;
public object TargetObject => Invocation.InvocationTarget ?? Invocation.MethodInvocationTarget;
public MethodInfo Method => Invocation.MethodInvocationTarget ?? Invocation.Method;
public object ReturnValue { get; set; }
protected IInvocation Invocation { get; }
protected CastleAbpMethodInvocationAdapterBase(IInvocation invocation)
{
Invocation = invocation;
_lazyArgumentsDictionary = new Lazy<IReadOnlyDictionary<string, object>>(GetArgumentsDictionary);
}
public abstract Task ProceedAsync();
private IReadOnlyDictionary<string, object> GetArgumentsDictionary()
{
var dict = new Dictionary<string, object>();
var methodParameters = Method.GetParameters();
for (int i = 0; i < methodParameters.Length; i++)
{
dict[methodParameters[i].Name] = Invocation.Arguments[i];
}
return dict;
}
}
}

27
framework/src/Volo.Abp.Castle.Core/Volo/Abp/Castle/DynamicProxy/CastleAbpMethodInvocationAdapterWithReturnValue.cs

@ -0,0 +1,27 @@
using System;
using System.Threading.Tasks;
using Castle.DynamicProxy;
using Volo.Abp.DynamicProxy;
namespace Volo.Abp.Castle.DynamicProxy
{
public class CastleAbpMethodInvocationAdapterWithReturnValue<TResult> : CastleAbpMethodInvocationAdapterBase, IAbpMethodInvocation
{
protected IInvocationProceedInfo ProceedInfo { get; }
protected Func<IInvocation, IInvocationProceedInfo, Task<TResult>> Proceed { get; }
public CastleAbpMethodInvocationAdapterWithReturnValue(IInvocation invocation,
IInvocationProceedInfo proceedInfo,
Func<IInvocation, IInvocationProceedInfo, Task<TResult>> proceed)
: base(invocation)
{
ProceedInfo = proceedInfo;
Proceed = proceed;
}
public override async Task ProceedAsync()
{
ReturnValue = await Proceed(Invocation, ProceedInfo);
}
}
}

36
framework/src/Volo.Abp.Castle.Core/Volo/Abp/Castle/DynamicProxy/CastleAsyncAbpInterceptorAdapter.cs

@ -0,0 +1,36 @@
using System;
using System.Threading.Tasks;
using Castle.DynamicProxy;
using Volo.Abp.DynamicProxy;
namespace Volo.Abp.Castle.DynamicProxy
{
public class CastleAsyncAbpInterceptorAdapter<TInterceptor> : AsyncInterceptorBase
where TInterceptor : IAbpInterceptor
{
private readonly TInterceptor _abpInterceptor;
public CastleAsyncAbpInterceptorAdapter(TInterceptor abpInterceptor)
{
_abpInterceptor = abpInterceptor;
}
protected override async Task InterceptAsync(IInvocation invocation, IInvocationProceedInfo proceedInfo, Func<IInvocation, IInvocationProceedInfo, Task> proceed)
{
await _abpInterceptor.InterceptAsync(
new CastleAbpMethodInvocationAdapter(invocation, proceedInfo, proceed)
);
}
protected override async Task<TResult> InterceptAsync<TResult>(IInvocation invocation, IInvocationProceedInfo proceedInfo, Func<IInvocation, IInvocationProceedInfo, Task<TResult>> proceed)
{
var adapter = new CastleAbpMethodInvocationAdapterWithReturnValue<TResult>(invocation, proceedInfo, proceed);
await _abpInterceptor.InterceptAsync(
adapter
);
return (TResult)adapter.ReturnValue;
}
}
}

6
framework/src/Volo.Abp.Cli.Core/Volo.Abp.Cli.Core.csproj

@ -15,10 +15,10 @@
<PackageReference Include="SharpZipLib" Version="1.2.0" />
<PackageReference Include="HtmlAgilityPack.NetCore" Version="1.5.0.1" />
<PackageReference Include="Microsoft.AspNetCore.Hosting.Abstractions" Version="2.2.0" />
<PackageReference Include="NuGet.Versioning" Version="5.3.0" />
<PackageReference Include="NuGet.Versioning" Version="5.4.0" />
<PackageReference Include="System.Text.Encoding.CodePages" Version="4.7.0" />
<PackageReference Include="System.Security.Permissions" Version="4.6.0" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="3.3.1" />
<PackageReference Include="System.Security.Permissions" Version="4.7.0" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="3.4.0" />
<PackageReference Include="Polly" Version="7.2.0" />
<PackageReference Include="Polly.Extensions.Http" Version="3.0.0" />
</ItemGroup>

2
framework/src/Volo.Abp.Core/Volo.Abp.Core.csproj

@ -12,7 +12,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.ComponentModel.Annotations" Version="4.7.0" />
<PackageReference Include="System.Collections.Immutable" Version="1.6.0" />
<PackageReference Include="System.Collections.Immutable" Version="1.7.0" />
<PackageReference Include="Microsoft.Extensions.Localization" Version="3.1.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="3.1.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="3.1.0" />

12
framework/src/Volo.Abp.Core/Volo/Abp/DynamicProxy/AbpInterceptor.cs

@ -3,13 +3,7 @@
namespace Volo.Abp.DynamicProxy
{
public abstract class AbpInterceptor : IAbpInterceptor
{
public abstract void Intercept(IAbpMethodInvocation invocation);
public virtual Task InterceptAsync(IAbpMethodInvocation invocation)
{
Intercept(invocation);
return Task.CompletedTask;
}
}
{
public abstract Task InterceptAsync(IAbpMethodInvocation invocation);
}
}

2
framework/src/Volo.Abp.Core/Volo/Abp/DynamicProxy/IAbpInterceptor.cs

@ -4,8 +4,6 @@ namespace Volo.Abp.DynamicProxy
{
public interface IAbpInterceptor
{
void Intercept(IAbpMethodInvocation invocation);
Task InterceptAsync(IAbpMethodInvocation invocation);
}
}

2
framework/src/Volo.Abp.Core/Volo/Abp/DynamicProxy/IAbpMethodInvocation.cs

@ -19,8 +19,6 @@ namespace Volo.Abp.DynamicProxy
object ReturnValue { get; set; }
void Proceed();
Task ProceedAsync();
}
}

6
framework/src/Volo.Abp.Ddd.Application.Contracts/Volo.Abp.Ddd.Application.Contracts.csproj

@ -13,8 +13,14 @@
<RootNamespace />
</PropertyGroup>
<ItemGroup>
<EmbeddedResource Include="Volo\Abp\Application\Localization\Resources\AbpDdd\*.json" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Volo.Abp.Auditing\Volo.Abp.Auditing.csproj" />
<ProjectReference Include="..\Volo.Abp.Localization\Volo.Abp.Localization.csproj" />
</ItemGroup>
</Project>

22
framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/AbpDddApplicationContractsModule.cs

@ -1,12 +1,30 @@
using Volo.Abp.Auditing;
using Volo.Abp.Application.Localization.Resources.AbpDdd;
using Volo.Abp.Auditing;
using Volo.Abp.Localization;
using Volo.Abp.Modularity;
using Volo.Abp.VirtualFileSystem;
namespace Volo.Abp.Application
{
[DependsOn(
typeof(AbpAuditingModule)
typeof(AbpAuditingModule),
typeof(AbpLocalizationModule)
)]
public class AbpDddApplicationContractsModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpVirtualFileSystemOptions>(options =>
{
options.FileSets.AddEmbedded<AbpDddApplicationContractsModule>();
});
Configure<AbpLocalizationOptions>(options =>
{
options.Resources
.Add<AbpDddResource>("en")
.AddVirtualJson("/Volo/Abp/Application/Localization/Resources/AbpDdd");
});
}
}
}

3
framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/ILimitedResultRequest.cs

@ -6,7 +6,8 @@ namespace Volo.Abp.Application.Dtos
public interface ILimitedResultRequest
{
/// <summary>
/// Max expected result count.
/// Maximum result count should be returned.
/// This is generally used to limit result count on paging.
/// </summary>
int MaxResultCount { get; set; }
}

30
framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/LimitedResultRequestDto.cs

@ -1,5 +1,8 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using Microsoft.Extensions.Localization;
using Volo.Abp.Application.Localization.Resources.AbpDdd;
namespace Volo.Abp.Application.Dtos
{
@ -7,11 +10,36 @@ namespace Volo.Abp.Application.Dtos
/// Simply implements <see cref="ILimitedResultRequest"/>.
/// </summary>
[Serializable]
public class LimitedResultRequestDto : ILimitedResultRequest
public class LimitedResultRequestDto : ILimitedResultRequest, IValidatableObject
{
/// <summary>
/// Default value: 10.
/// </summary>
public static int DefaultMaxResultCount { get; set; } = 10;
/// <summary>
/// Maximum possible value of the <see cref="MaxResultCount"/>.
/// Default value: 1,000.
/// </summary>
public static int MaxMaxResultCount { get; set; } = 1000;
/// <summary>
/// Maximum result count should be returned.
/// This is generally used to limit result count on paging.
/// </summary>
[Range(1, int.MaxValue)]
public virtual int MaxResultCount { get; set; } = DefaultMaxResultCount;
public virtual IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
var l = validationContext.GetService(typeof(IStringLocalizer<AbpDddResource>)) as IStringLocalizer<AbpDddResource>;
if (MaxResultCount > MaxMaxResultCount)
{
yield return new ValidationResult(
errorMessage:l?["MaxResultCountExceededExceptionMessage", nameof(MaxResultCount), MaxMaxResultCount, typeof(LimitedResultRequestDto).FullName, nameof(MaxMaxResultCount)],
new []{nameof(MaxResultCount)});
}
}
}
}

9
framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Localization/Resources/AbpDdd/AbpDddResource.cs

@ -0,0 +1,9 @@
using Volo.Abp.Localization;
namespace Volo.Abp.Application.Localization.Resources.AbpDdd
{
[LocalizationResourceName("AbpDdd")]
public class AbpDddResource
{
}
}

6
framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Localization/Resources/AbpDdd/en.json

@ -0,0 +1,6 @@
{
"culture": "en",
"texts": {
"MaxResultCountExceededExceptionMessage": "{0} can not be more than {1}! Increase {2}.{3} on the server side to allow more results."
}
}

6
framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Localization/Resources/AbpDdd/tr.json

@ -0,0 +1,6 @@
{
"culture": "tr",
"texts": {
"MaxResultCountExceededExceptionMessage": "{0} en fazla {1} olabilir, daha büyük olamaz! Daha fazla sonuca izin vermek için {2}.{3}'ü sunucu tarafında artırın."
}
}

6
framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Localization/Resources/AbpDdd/zh-Hans.json

@ -0,0 +1,6 @@
{
"culture": "zh-Hans",
"texts": {
"MaxResultCountExceededExceptionMessage": "{0}不能超过 {1}! 在服务器端增加{2}.{3}以获得更多结果."
}
}

70
framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/BasicRepositoryBase.cs

@ -25,54 +25,28 @@ namespace Volo.Abp.Domain.Repositories
CancellationTokenProvider = NullCancellationTokenProvider.Instance;
}
public abstract TEntity Insert(TEntity entity, bool autoSave = false);
public abstract Task<TEntity> InsertAsync(TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default);
public virtual Task<TEntity> InsertAsync(TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default)
{
return Task.FromResult(Insert(entity, autoSave));
}
public abstract Task<TEntity> UpdateAsync(TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default);
public abstract TEntity Update(TEntity entity, bool autoSave = false);
public abstract Task DeleteAsync(TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default);
public virtual Task<TEntity> UpdateAsync(TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default)
{
return Task.FromResult(Update(entity));
}
public abstract Task<List<TEntity>> GetListAsync(bool includeDetails = false, CancellationToken cancellationToken = default);
public abstract void Delete(TEntity entity, bool autoSave = false);
public virtual Task DeleteAsync(TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default)
{
Delete(entity);
return Task.CompletedTask;
}
public abstract Task<long> GetCountAsync(CancellationToken cancellationToken = default);
protected virtual CancellationToken GetCancellationToken(CancellationToken prefferedValue = default)
protected virtual CancellationToken GetCancellationToken(CancellationToken preferredValue = default)
{
return CancellationTokenProvider.FallbackToProvider(prefferedValue);
}
public abstract List<TEntity> GetList(bool includeDetails = false);
public virtual Task<List<TEntity>> GetListAsync(bool includeDetails = false, CancellationToken cancellationToken = default)
{
return Task.FromResult(GetList(includeDetails));
}
public abstract long GetCount();
public virtual Task<long> GetCountAsync(CancellationToken cancellationToken = default)
{
return Task.FromResult(GetCount());
return CancellationTokenProvider.FallbackToProvider(preferredValue);
}
}
public abstract class BasicRepositoryBase<TEntity, TKey> : BasicRepositoryBase<TEntity>, IBasicRepository<TEntity, TKey>
where TEntity : class, IEntity<TKey>
{
public virtual TEntity Get(TKey id, bool includeDetails = true)
public virtual async Task<TEntity> GetAsync(TKey id, bool includeDetails = true, CancellationToken cancellationToken = default)
{
var entity = Find(id, includeDetails);
var entity = await FindAsync(id, includeDetails, cancellationToken);
if (entity == null)
{
@ -82,33 +56,17 @@ namespace Volo.Abp.Domain.Repositories
return entity;
}
public virtual Task<TEntity> GetAsync(TKey id, bool includeDetails = true, CancellationToken cancellationToken = default)
{
return Task.FromResult(Get(id, includeDetails));
}
public abstract TEntity Find(TKey id, bool includeDetails = true);
public virtual Task<TEntity> FindAsync(TKey id, bool includeDetails = true, CancellationToken cancellationToken = default)
{
return Task.FromResult(Find(id, includeDetails));
}
public virtual void Delete(TKey id, bool autoSave = false)
public abstract Task<TEntity> FindAsync(TKey id, bool includeDetails = true, CancellationToken cancellationToken = default);
public virtual async Task DeleteAsync(TKey id, bool autoSave = false, CancellationToken cancellationToken = default)
{
var entity = Find(id);
var entity = await FindAsync(id, cancellationToken: cancellationToken);
if (entity == null)
{
return;
}
Delete(entity);
}
public virtual Task DeleteAsync(TKey id, bool autoSave = false, CancellationToken cancellationToken = default)
{
Delete(id);
return Task.CompletedTask;
await DeleteAsync(entity, autoSave, cancellationToken);
}
}
}

42
framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/IBasicRepository.cs

@ -8,17 +8,6 @@ namespace Volo.Abp.Domain.Repositories
public interface IBasicRepository<TEntity> : IReadOnlyBasicRepository<TEntity>
where TEntity : class, IEntity
{
/// <summary>
/// Inserts a new entity.
/// </summary>
/// <param name="entity">Inserted entity</param>
/// <param name="autoSave">
/// Set true to automatically save entity to database.
/// This is useful for ORMs / database APIs those only save changes with an explicit method call, but you need to immediately save changes to the database.
/// </param>
[NotNull]
TEntity Insert([NotNull] TEntity entity, bool autoSave = false);
/// <summary>
/// Inserts a new entity.
/// </summary>
@ -31,17 +20,6 @@ namespace Volo.Abp.Domain.Repositories
[NotNull]
Task<TEntity> InsertAsync([NotNull] TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default);
/// <summary>
/// Updates an existing entity.
/// </summary>
/// <param name="entity">Entity</param>
/// <param name="autoSave">
/// Set true to automatically save changes to database.
/// This is useful for ORMs / database APIs those only save changes with an explicit method call, but you need to immediately save changes to the database.
/// </param>
[NotNull]
TEntity Update([NotNull] TEntity entity, bool autoSave = false);
/// <summary>
/// Updates an existing entity.
/// </summary>
@ -54,16 +32,6 @@ namespace Volo.Abp.Domain.Repositories
[NotNull]
Task<TEntity> UpdateAsync([NotNull] TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default);
/// <summary>
/// Deletes an entity.
/// </summary>
/// <param name="entity">Entity to be deleted</param>
/// <param name="autoSave">
/// Set true to automatically save changes to database.
/// This is useful for ORMs / database APIs those only save changes with an explicit method call, but you need to immediately save changes to the database.
/// </param>
void Delete([NotNull] TEntity entity, bool autoSave = false);
/// <summary>
/// Deletes an entity.
/// </summary>
@ -79,16 +47,6 @@ namespace Volo.Abp.Domain.Repositories
public interface IBasicRepository<TEntity, TKey> : IBasicRepository<TEntity>, IReadOnlyBasicRepository<TEntity, TKey>
where TEntity : class, IEntity<TKey>
{
/// <summary>
/// Deletes an entity by primary key.
/// </summary>
/// <param name="id">Primary key of the entity</param>
/// <param name="autoSave">
/// Set true to automatically save changes to database.
/// This is useful for ORMs / database APIs those only save changes with an explicit method call, but you need to immediately save changes to the database.
/// </param>
void Delete(TKey id, bool autoSave = false); //TODO: Return true if deleted
/// <summary>
/// Deletes an entity by primary key.
/// </summary>

31
framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/IReadOnlyBasicRepository.cs

@ -9,13 +9,6 @@ namespace Volo.Abp.Domain.Repositories
public interface IReadOnlyBasicRepository<TEntity> : IRepository
where TEntity : class, IEntity
{
/// <summary>
/// Gets a list of all the entities.
/// </summary>
/// <param name="includeDetails">Set true to include all children of this entity</param>
/// <returns>Entity</returns>
List<TEntity> GetList(bool includeDetails = false);
/// <summary>
/// Gets a list of all the entities.
/// </summary>
@ -24,11 +17,6 @@ namespace Volo.Abp.Domain.Repositories
/// <returns>Entity</returns>
Task<List<TEntity>> GetListAsync(bool includeDetails = false, CancellationToken cancellationToken = default);
/// <summary>
/// Gets total count of all entities.
/// </summary>
long GetCount();
/// <summary>
/// Gets total count of all entities.
/// </summary>
@ -38,16 +26,6 @@ namespace Volo.Abp.Domain.Repositories
public interface IReadOnlyBasicRepository<TEntity, TKey> : IReadOnlyBasicRepository<TEntity>
where TEntity : class, IEntity<TKey>
{
/// <summary>
/// Gets an entity with given primary key.
/// Throws <see cref="EntityNotFoundException"/> if can not find an entity with given id.
/// </summary>
/// <param name="id">Primary key of the entity to get</param>
/// <param name="includeDetails">Set true to include all children of this entity</param>
/// <returns>Entity</returns>
[NotNull]
TEntity Get(TKey id, bool includeDetails = true);
/// <summary>
/// Gets an entity with given primary key.
/// Throws <see cref="EntityNotFoundException"/> if can not find an entity with given id.
@ -59,15 +37,6 @@ namespace Volo.Abp.Domain.Repositories
[NotNull]
Task<TEntity> GetAsync(TKey id, bool includeDetails = true, CancellationToken cancellationToken = default);
/// <summary>
/// Gets an entity with given primary key or null if not found.
/// </summary>
/// <param name="id">Primary key of the entity to get</param>
/// <param name="includeDetails">Set true to include all children of this entity</param>
/// <returns>Entity or null</returns>
[CanBeNull]
TEntity Find(TKey id, bool includeDetails = true);
/// <summary>
/// Gets an entity with given primary key or null if not found.
/// </summary>

13
framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/IRepository.cs

@ -18,19 +18,6 @@ namespace Volo.Abp.Domain.Repositories
public interface IRepository<TEntity> : IReadOnlyRepository<TEntity>, IBasicRepository<TEntity>
where TEntity : class, IEntity
{
/// <summary>
/// Deletes many entities by function.
/// Notice that: All entities fits to given predicate are retrieved and deleted.
/// This may cause major performance problems if there are too many entities with
/// given predicate.
/// </summary>
/// <param name="predicate">A condition to filter entities</param>
/// <param name="autoSave">
/// Set true to automatically save changes to database.
/// This is useful for ORMs / database APIs those only save changes with an explicit method call, but you need to immediately save changes to the database.
/// </param>
void Delete([NotNull] Expression<Func<TEntity, bool>> predicate, bool autoSave = false);
/// <summary>
/// Deletes many entities by function.
/// Notice that: All entities fits to given predicate are retrieved and deleted.

55
framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/RepositoryBase.cs

@ -46,19 +46,7 @@ namespace Volo.Abp.Domain.Repositories
protected abstract IQueryable<TEntity> GetQueryable();
public virtual void Delete(Expression<Func<TEntity, bool>> predicate, bool autoSave = false)
{
foreach (var entity in GetQueryable().Where(predicate).ToList())
{
Delete(entity, autoSave);
}
}
public virtual Task DeleteAsync(Expression<Func<TEntity, bool>> predicate, bool autoSave = false, CancellationToken cancellationToken = default)
{
Delete(predicate, autoSave);
return Task.CompletedTask;
}
public abstract Task DeleteAsync(Expression<Func<TEntity, bool>> predicate, bool autoSave = false, CancellationToken cancellationToken = default);
protected virtual TQueryable ApplyDataFilters<TQueryable>(TQueryable query)
where TQueryable : IQueryable<TEntity>
@ -81,50 +69,19 @@ namespace Volo.Abp.Domain.Repositories
public abstract class RepositoryBase<TEntity, TKey> : RepositoryBase<TEntity>, IRepository<TEntity, TKey>
where TEntity : class, IEntity<TKey>
{
public virtual TEntity Find(TKey id, bool includeDetails = true)
{
return includeDetails
? WithDetails().FirstOrDefault(EntityHelper.CreateEqualityExpressionForId<TEntity, TKey>(id))
: GetQueryable().FirstOrDefault(EntityHelper.CreateEqualityExpressionForId<TEntity, TKey>(id));
}
public abstract Task<TEntity> GetAsync(TKey id, bool includeDetails = true, CancellationToken cancellationToken = default);
public virtual TEntity Get(TKey id, bool includeDetails = true)
{
var entity = Find(id, includeDetails);
public abstract Task<TEntity> FindAsync(TKey id, bool includeDetails = true, CancellationToken cancellationToken = default);
if (entity == null)
{
throw new EntityNotFoundException(typeof(TEntity), id);
}
return entity;
}
public virtual Task<TEntity> GetAsync(TKey id, bool includeDetails = true, CancellationToken cancellationToken = default)
{
return Task.FromResult(Get(id, includeDetails));
}
public virtual Task<TEntity> FindAsync(TKey id, bool includeDetails = true, CancellationToken cancellationToken = default)
public virtual async Task DeleteAsync(TKey id, bool autoSave = false, CancellationToken cancellationToken = default)
{
return Task.FromResult(Find(id, includeDetails));
}
public virtual void Delete(TKey id, bool autoSave = false)
{
var entity = Find(id, includeDetails: false);
var entity = await FindAsync(id, cancellationToken: cancellationToken);
if (entity == null)
{
return;
}
Delete(entity, autoSave);
}
public virtual Task DeleteAsync(TKey id, bool autoSave = false, CancellationToken cancellationToken = default)
{
Delete(id, autoSave);
return Task.CompletedTask;
await DeleteAsync(entity, autoSave, cancellationToken);
}
}
}

7
framework/src/Volo.Abp.Emailing/Volo.Abp.Emailing.csproj

@ -19,7 +19,12 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Scriban" Version="2.1.0" />
<Content Remove="Volo\Abp\Emailing\Localization\*.json" />
<EmbeddedResource Include="Volo\Abp\Emailing\Localization\*.json" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Scriban" Version="2.1.1" />
</ItemGroup>
<ItemGroup>

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

@ -2,6 +2,7 @@
using System.Collections.Generic;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.BackgroundJobs;
using Volo.Abp.Emailing.Localization;
using Volo.Abp.Emailing.Templates;
using Volo.Abp.Localization;
using Volo.Abp.Modularity;
@ -30,6 +31,13 @@ namespace Volo.Abp.Emailing
options.FileSets.AddEmbedded<AbpEmailingModule>();
});
Configure<AbpLocalizationOptions>(options =>
{
options.Resources
.Add<EmailingResource>("en")
.AddVirtualJson("/Volo/Abp/Emailing/Localization");
});
Configure<AbpBackgroundJobOptions>(options =>
{
options.AddJob<BackgroundEmailSendingJob>();

66
framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/EmailSettingProvider.cs

@ -1,3 +1,5 @@
using Volo.Abp.Emailing.Localization;
using Volo.Abp.Localization;
using Volo.Abp.Settings;
namespace Volo.Abp.Emailing
@ -11,16 +13,62 @@ namespace Volo.Abp.Emailing
public override void Define(ISettingDefinitionContext context)
{
context.Add(
new SettingDefinition(EmailSettingNames.Smtp.Host, "127.0.0.1"),
new SettingDefinition(EmailSettingNames.Smtp.Port, "25"),
new SettingDefinition(EmailSettingNames.Smtp.UserName),
new SettingDefinition(EmailSettingNames.Smtp.Password, isEncrypted: true),
new SettingDefinition(EmailSettingNames.Smtp.Domain),
new SettingDefinition(EmailSettingNames.Smtp.EnableSsl, "false"),
new SettingDefinition(EmailSettingNames.Smtp.UseDefaultCredentials, "true"),
new SettingDefinition(EmailSettingNames.DefaultFromAddress, "noreply@abp.io"),
new SettingDefinition(EmailSettingNames.DefaultFromDisplayName, "ABP application")
new SettingDefinition(
EmailSettingNames.Smtp.Host,
"127.0.0.1",
L("DisplayName:Abp.Mailing.Smtp.Host"),
L("Description:Abp.Mailing.Smtp.Host")),
new SettingDefinition(EmailSettingNames.Smtp.Port,
"25",
L("DisplayName:Abp.Mailing.Smtp.Port"),
L("Description:Abp.Mailing.Smtp.Port")),
new SettingDefinition(
EmailSettingNames.Smtp.UserName,
displayName: L("DisplayName:Abp.Mailing.Smtp.UserName"),
description: L("Description:Abp.Mailing.Smtp.UserName")),
new SettingDefinition(
EmailSettingNames.Smtp.Password,
displayName:
L("DisplayName:Abp.Mailing.Smtp.Password"),
description: L("Description:Abp.Mailing.Smtp.Password"),
isEncrypted: true),
new SettingDefinition(
EmailSettingNames.Smtp.Domain,
displayName: L("DisplayName:Abp.Mailing.Smtp.Domain"),
description: L("Description:Abp.Mailing.Smtp.Domain")),
new SettingDefinition(
EmailSettingNames.Smtp.EnableSsl,
"false",
L("DisplayName:Abp.Mailing.Smtp.EnableSsl"),
L("Description:Abp.Mailing.Smtp.EnableSsl")),
new SettingDefinition(
EmailSettingNames.Smtp.UseDefaultCredentials,
"true",
L("DisplayName:Abp.Mailing.Smtp.UseDefaultCredentials"),
L("Description:Abp.Mailing.Smtp.UseDefaultCredentials")),
new SettingDefinition(
EmailSettingNames.DefaultFromAddress,
"noreply@abp.io",
L("DisplayName:Abp.Mailing.DefaultFromAddress"),
L("Description:Abp.Mailing.DefaultFromAddress")),
new SettingDefinition(EmailSettingNames.DefaultFromDisplayName,
"ABP application",
L("DisplayName:Abp.Mailing.DefaultFromDisplayName"),
L("Description:Abp.Mailing.DefaultFromDisplayName"))
);
}
private static LocalizableString L(string name)
{
return LocalizableString.Create<EmailingResource>(name);
}
}
}

10
framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Localization/EmailingResource.cs

@ -0,0 +1,10 @@
using Volo.Abp.Localization;
namespace Volo.Abp.Emailing.Localization
{
[LocalizationResourceName("AbpEmailing")]
public class EmailingResource
{
}
}

23
framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Localization/en.json

@ -0,0 +1,23 @@
{
"culture": "en",
"texts": {
"DisplayName:Abp.Mailing.DefaultFromAddress": "Default from address",
"DisplayName:Abp.Mailing.DefaultFromDisplayName": "Default from display name",
"DisplayName:Abp.Mailing.Smtp.Host": "Host",
"DisplayName:Abp.Mailing.Smtp.Port": "Port",
"DisplayName:Abp.Mailing.Smtp.UserName": "User name",
"DisplayName:Abp.Mailing.Smtp.Password": "Password",
"DisplayName:Abp.Mailing.Smtp.Domain": "Domain",
"DisplayName:Abp.Mailing.Smtp.EnableSsl": "Enable SSL",
"DisplayName:Abp.Mailing.Smtp.UseDefaultCredentials": "Use default credentials",
"Description:Abp.Mailing.DefaultFromAddress": "The default from address",
"Description:Abp.Mailing.DefaultFromDisplayName": "The default from display name",
"Description:Abp.Mailing.Smtp.Host": "The name or IP address of the host used for SMTP transactions.",
"Description:Abp.Mailing.Smtp.Port": "The port used for SMTP transactions.",
"Description:Abp.Mailing.Smtp.UserName": "User name associated with the credentials.",
"Description:Abp.Mailing.Smtp.Password": "The password for the user name associated with the credentials.",
"Description:Abp.Mailing.Smtp.Domain": "The domain or computer name that verifies the credentials.",
"Description:Abp.Mailing.Smtp.EnableSsl": "Whether the SmtpClient uses Secure Sockets Layer (SSL) to encrypt the connection.",
"Description:Abp.Mailing.Smtp.UseDefaultCredentials": "Whether the DefaultCredentials are sent with requests."
}
}

23
framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Localization/zh-Hans.json

@ -0,0 +1,23 @@
{
"culture": "zh-Hans",
"texts": {
"DisplayName:Abp.Mailing.DefaultFromAddress": "默认发件人地址",
"DisplayName:Abp.Mailing.DefaultFromDisplayName": "默认发件人名字",
"DisplayName:Abp.Mailing.Smtp.Host": "主机",
"DisplayName:Abp.Mailing.Smtp.Port": "端口",
"DisplayName:Abp.Mailing.Smtp.UserName": "用户名",
"DisplayName:Abp.Mailing.Smtp.Password": "密码",
"DisplayName:Abp.Mailing.Smtp.Domain": "域",
"DisplayName:Abp.Mailing.Smtp.EnableSsl": "启用SSL",
"DisplayName:Abp.Mailing.Smtp.UseDefaultCredentials": "使用默认凭据",
"Description:Abp.Mailing.DefaultFromAddress": "默认的发件人地址.",
"Description:Abp.Mailing.DefaultFromDisplayName": "默认的发件人名字.",
"Description:Abp.Mailing.Smtp.Host": "SMTP 事务的主机名或主机 IP 地址.",
"Description:Abp.Mailing.Smtp.Port": "SMTP 事务的端口.",
"Description:Abp.Mailing.Smtp.UserName": "凭据关联的用户名.",
"Description:Abp.Mailing.Smtp.Password": "凭据关联的用户名的密码.",
"Description:Abp.Mailing.Smtp.Domain": "验证凭据的域名或计算机名.",
"Description:Abp.Mailing.Smtp.EnableSsl": "指定 SmtpClient 是否使用安全套接字层 (SSL) 加密连接.",
"Description:Abp.Mailing.Smtp.UseDefaultCredentials": "控制默认凭据是否随请求一起发送."
}
}

2
framework/src/Volo.Abp.EntityFrameworkCore.MySQL/Volo.Abp.EntityFrameworkCore.MySQL.csproj

@ -18,7 +18,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="3.0.0" />
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="3.0.1" />
</ItemGroup>
</Project>

73
framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Domain/Repositories/EntityFrameworkCore/EfCoreRepository.cs

@ -40,18 +40,6 @@ namespace Volo.Abp.Domain.Repositories.EntityFrameworkCore
);
}
public override TEntity Insert(TEntity entity, bool autoSave = false)
{
var savedEntity = DbSet.Add(entity).Entity;
if (autoSave)
{
DbContext.SaveChanges();
}
return savedEntity;
}
public override async Task<TEntity> InsertAsync(TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default)
{
var savedEntity = DbSet.Add(entity).Entity;
@ -64,20 +52,6 @@ namespace Volo.Abp.Domain.Repositories.EntityFrameworkCore
return savedEntity;
}
public override TEntity Update(TEntity entity, bool autoSave = false)
{
DbContext.Attach(entity);
var updatedEntity = DbContext.Update(entity).Entity;
if (autoSave)
{
DbContext.SaveChanges();
}
return updatedEntity;
}
public override async Task<TEntity> UpdateAsync(TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default)
{
DbContext.Attach(entity);
@ -91,17 +65,7 @@ namespace Volo.Abp.Domain.Repositories.EntityFrameworkCore
return updatedEntity;
}
public override void Delete(TEntity entity, bool autoSave = false)
{
DbSet.Remove(entity);
if (autoSave)
{
DbContext.SaveChanges();
}
}
public override async Task DeleteAsync(TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default)
{
DbSet.Remove(entity);
@ -112,13 +76,6 @@ namespace Volo.Abp.Domain.Repositories.EntityFrameworkCore
}
}
public override List<TEntity> GetList(bool includeDetails = false)
{
return includeDetails
? WithDetails().ToList()
: DbSet.ToList();
}
public override async Task<List<TEntity>> GetListAsync(bool includeDetails = false, CancellationToken cancellationToken = default)
{
return includeDetails
@ -126,11 +83,6 @@ namespace Volo.Abp.Domain.Repositories.EntityFrameworkCore
: await DbSet.ToListAsync(GetCancellationToken(cancellationToken));
}
public override long GetCount()
{
return DbSet.LongCount();
}
public override async Task<long> GetCountAsync(CancellationToken cancellationToken = default)
{
return await DbSet.LongCountAsync(GetCancellationToken(cancellationToken));
@ -141,16 +93,6 @@ namespace Volo.Abp.Domain.Repositories.EntityFrameworkCore
return DbSet.AsQueryable();
}
public override void Delete(Expression<Func<TEntity, bool>> predicate, bool autoSave = false)
{
base.Delete(predicate, autoSave);
if (autoSave)
{
DbContext.SaveChanges();
}
}
public override async Task DeleteAsync(Expression<Func<TEntity, bool>> predicate, bool autoSave = false, CancellationToken cancellationToken = default)
{
var entities = await GetQueryable()
@ -269,20 +211,9 @@ namespace Volo.Abp.Domain.Repositories.EntityFrameworkCore
: await DbSet.FindAsync(new object[] { id }, GetCancellationToken(cancellationToken));
}
public virtual void Delete(TKey id, bool autoSave = false)
{
var entity = Find(id, includeDetails: false);
if (entity == null)
{
return;
}
Delete(entity, autoSave);
}
public virtual async Task DeleteAsync(TKey id, bool autoSave = false, CancellationToken cancellationToken = default)
{
var entity = await FindAsync(id, includeDetails: false, cancellationToken: cancellationToken);
var entity = await FindAsync(id, cancellationToken: cancellationToken);
if (entity == null)
{
return;

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

@ -22,7 +22,6 @@ using Volo.Abp.EntityFrameworkCore.ValueConverters;
using Volo.Abp.Guids;
using Volo.Abp.MultiTenancy;
using Volo.Abp.Reflection;
using Volo.Abp.Threading;
using Volo.Abp.Timing;
namespace Volo.Abp.EntityFrameworkCore
@ -92,46 +91,7 @@ namespace Volo.Abp.EntityFrameworkCore
.Invoke(this, new object[] { modelBuilder, entityType });
}
}
public override int SaveChanges(bool acceptAllChangesOnSuccess)
{
//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
try
{
var auditLog = AuditingManager?.Current?.Log;
List<EntityChangeInfo> entityChangeList = null;
if (auditLog != null)
{
entityChangeList = EntityHistoryHelper.CreateChangeList(ChangeTracker.Entries().ToList());
}
var changeReport = ApplyAbpConcepts();
var result = base.SaveChanges(acceptAllChangesOnSuccess);
AsyncHelper.RunSync(() => EntityChangeEventHelper.TriggerEventsAsync(changeReport));
if (auditLog != null)
{
EntityHistoryHelper.UpdateChangeList(entityChangeList);
auditLog.EntityChanges.AddRange(entityChangeList);
}
return result;
}
catch (DbUpdateConcurrencyException ex)
{
throw new AbpDbConcurrencyException(ex.Message, ex);
}
finally
{
ChangeTracker.AutoDetectChangesEnabled = true;
}
}
public override async Task<int> SaveChangesAsync(bool acceptAllChangesOnSuccess, CancellationToken cancellationToken = default)
{
try

13
framework/src/Volo.Abp.Features/Volo/Abp/Features/FeatureInterceptor.cs

@ -2,7 +2,6 @@
using Volo.Abp.Aspects;
using Volo.Abp.DependencyInjection;
using Volo.Abp.DynamicProxy;
using Volo.Abp.Threading;
namespace Volo.Abp.Features
{
@ -16,18 +15,6 @@ namespace Volo.Abp.Features
_methodInvocationFeatureCheckerService = methodInvocationFeatureCheckerService;
}
public override void Intercept(IAbpMethodInvocation invocation)
{
if (AbpCrossCuttingConcerns.IsApplied(invocation.TargetObject, AbpCrossCuttingConcerns.FeatureChecking))
{
invocation.Proceed();
return;
}
AsyncHelper.RunSync(() => CheckFeaturesAsync(invocation));
invocation.Proceed();
}
public override async Task InterceptAsync(IAbpMethodInvocation invocation)
{
if (AbpCrossCuttingConcerns.IsApplied(invocation.TargetObject, AbpCrossCuttingConcerns.FeatureChecking))

2
framework/src/Volo.Abp.FluentValidation/Volo.Abp.FluentValidation.csproj

@ -14,7 +14,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="FluentValidation" Version="8.5.0" />
<PackageReference Include="FluentValidation" Version="8.6.0" />
</ItemGroup>
<ItemGroup>

2
framework/src/Volo.Abp.HangFire/Volo.Abp.HangFire.csproj

@ -14,7 +14,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Hangfire.AspNetCore" Version="1.7.6" />
<PackageReference Include="Hangfire.AspNetCore" Version="1.7.8" />
</ItemGroup>
<ItemGroup>

6
framework/src/Volo.Abp.Http.Client/Microsoft/Extensions/DependencyInjection/ServiceCollectionDynamicHttpClientProxyExtensions.cs

@ -53,7 +53,7 @@ namespace Microsoft.Extensions.DependencyInjection
foreach (var serviceType in serviceTypes)
{
services.AddHttpClientProxy(
serviceType,
serviceType,
remoteServiceConfigurationName,
asDefaultServices
);
@ -153,7 +153,7 @@ namespace Microsoft.Extensions.DependencyInjection
var interceptorType = typeof(DynamicHttpProxyInterceptor<>).MakeGenericType(type);
services.AddTransient(interceptorType);
var interceptorAdapterType = typeof(CastleAbpInterceptorAdapter<>).MakeGenericType(interceptorType);
var interceptorAdapterType = typeof(AbpAsyncDeterminationInterceptor<>).MakeGenericType(interceptorType);
if (asDefaultService)
{
@ -174,7 +174,7 @@ namespace Microsoft.Extensions.DependencyInjection
var service = ProxyGeneratorInstance
.CreateInterfaceProxyWithoutTarget(
type,
(IInterceptor) serviceProvider.GetRequiredService(interceptorAdapterType)
(IInterceptor)serviceProvider.GetRequiredService(interceptorAdapterType)
);
return Activator.CreateInstance(

45
framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/DynamicHttpProxyInterceptor.cs

@ -74,43 +74,33 @@ namespace Volo.Abp.Http.Client.DynamicProxying
Logger = NullLogger<DynamicHttpProxyInterceptor<TService>>.Instance;
}
public override void Intercept(IAbpMethodInvocation invocation)
public override async Task InterceptAsync(IAbpMethodInvocation invocation)
{
if (invocation.Method.ReturnType == typeof(void))
if (invocation.Method.ReturnType.GenericTypeArguments.IsNullOrEmpty())
{
AsyncHelper.RunSync(() => MakeRequestAsync(invocation));
await MakeRequestAsync(invocation);
}
else
{
var responseAsString = AsyncHelper.RunSync(() => MakeRequestAsync(invocation));
var result = (Task)GenericInterceptAsyncMethod
.MakeGenericMethod(invocation.Method.ReturnType.GenericTypeArguments[0])
.Invoke(this, new object[] { invocation });
//TODO: Think on that
if (TypeHelper.IsPrimitiveExtended(invocation.Method.ReturnType, true))
{
invocation.ReturnValue = Convert.ChangeType(responseAsString, invocation.Method.ReturnType);
}
else
{
invocation.ReturnValue = JsonSerializer.Deserialize(
invocation.Method.ReturnType,
responseAsString
);
}
invocation.ReturnValue = await GetResultAsync(
result,
invocation.Method.ReturnType.GetGenericArguments()[0]
);
}
}
public override Task InterceptAsync(IAbpMethodInvocation invocation)
private async Task<object> GetResultAsync(Task task, Type resultType)
{
if (invocation.Method.ReturnType.GenericTypeArguments.IsNullOrEmpty())
{
return MakeRequestAsync(invocation);
}
invocation.ReturnValue = GenericInterceptAsyncMethod
.MakeGenericMethod(invocation.Method.ReturnType.GenericTypeArguments[0])
.Invoke(this, new object[] { invocation });
return Task.CompletedTask;
await task;
return typeof(Task<>)
.MakeGenericType(resultType)
.GetProperty(nameof(Task<object>.Result), BindingFlags.Instance | BindingFlags.Public)
.GetValue(task);
}
private async Task<T> MakeRequestAndGetResultAsync<T>(IAbpMethodInvocation invocation)
@ -163,7 +153,6 @@ namespace Volo.Abp.Http.Client.DynamicProxying
return await response.Content.ReadAsStringAsync();
}
private ApiVersionInfo GetApiVersionInfo(ActionApiDescriptionModel action)
{
var apiVersion = FindBestApiVersion(action);

8
framework/src/Volo.Abp.Http/Volo/Abp/Http/ProxyScripting/ProxyScriptManager.cs

@ -18,21 +18,18 @@ namespace Volo.Abp.Http.ProxyScripting
private readonly IJsonSerializer _jsonSerializer;
private readonly IProxyScriptManagerCache _cache;
private readonly AbpApiProxyScriptingOptions _options;
private readonly IJavascriptMinifier _javascriptMinifier;
public ProxyScriptManager(
IApiDescriptionModelProvider modelProvider,
IServiceProvider serviceProvider,
IJsonSerializer jsonSerializer,
IProxyScriptManagerCache cache,
IOptions<AbpApiProxyScriptingOptions> options,
IJavascriptMinifier javascriptMinifier)
IOptions<AbpApiProxyScriptingOptions> options)
{
_modelProvider = modelProvider;
_serviceProvider = serviceProvider;
_jsonSerializer = jsonSerializer;
_cache = cache;
_javascriptMinifier = javascriptMinifier;
_options = options.Value;
}
@ -67,8 +64,7 @@ namespace Volo.Abp.Http.ProxyScripting
using (var scope = _serviceProvider.CreateScope())
{
var script = scope.ServiceProvider.GetRequiredService(generatorType).As<IProxyScriptGenerator>().CreateScript(apiModel);
return scriptingModel.Minify ? _javascriptMinifier.Minify(script) : script;
return scope.ServiceProvider.GetRequiredService(generatorType).As<IProxyScriptGenerator>().CreateScript(apiModel);
}
}

5
framework/src/Volo.Abp.Http/Volo/Abp/Http/ProxyScripting/ProxyScriptingModel.cs

@ -8,8 +8,6 @@ namespace Volo.Abp.Http.ProxyScripting
public bool UseCache { get; set; }
public bool Minify { get; set; }
public string[] Modules { get; set; }
public string[] Controllers { get; set; }
@ -18,11 +16,10 @@ namespace Volo.Abp.Http.ProxyScripting
public IDictionary<string, string> Properties { get; set; }
public ProxyScriptingModel(string generatorType, bool useCache = true, bool minify = false)
public ProxyScriptingModel(string generatorType, bool useCache = true)
{
GeneratorType = generatorType;
UseCache = useCache;
Minify = minify;
Properties = new Dictionary<string, string>();
}

2
framework/src/Volo.Abp.IdentityModel/Volo.Abp.IdentityModel.csproj

@ -14,7 +14,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="IdentityModel" Version="4.0.0" />
<PackageReference Include="IdentityModel" Version="4.1.1" />
<ProjectReference Include="..\Volo.Abp.Threading\Volo.Abp.Threading.csproj" />
</ItemGroup>

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

@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\common.props" />
@ -14,7 +14,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
</ItemGroup>
<ItemGroup>

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

@ -14,11 +14,12 @@
</PropertyGroup>
<ItemGroup>
<None Remove="Volo\Abp\Localization\Resources\**\*.json" />
<EmbeddedResource Include="Volo\Abp\Localization\Resources\**\*.json" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
</ItemGroup>
<ItemGroup>

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

@ -1,4 +1,5 @@
using Volo.Abp.Localization.Resources.AbpValidation;
using Volo.Abp.Localization.Resources.AbpLocalization;
using Volo.Abp.Localization.Resources.AbpValidation;
using Volo.Abp.Modularity;
using Volo.Abp.Settings;
using Volo.Abp.VirtualFileSystem;
@ -27,10 +28,16 @@ namespace Volo.Abp.Localization
.Resources
.Add<DefaultResource>("en");
//TODO: Obsolete, Remove in the future version
options
.Resources
.Add<AbpValidationResource>("en")
.AddVirtualJson("/Localization/Resources/AbpValidation");
.AddVirtualJson("/Volo/Abp/Validation/Localization");//load from Volo.Abp.Validation
options
.Resources
.Add<AbpLocalizationResource>("en")
.AddVirtualJson("/Localization/Resources/AbpLocalization");
});
}
}

14
framework/src/Volo.Abp.Localization/Volo/Abp/Localization/LocalizationSettingProvider.cs

@ -1,4 +1,5 @@
using Volo.Abp.Settings;
using Volo.Abp.Localization.Resources.AbpValidation;
using Volo.Abp.Settings;
namespace Volo.Abp.Localization
{
@ -7,8 +8,17 @@ namespace Volo.Abp.Localization
public override void Define(ISettingDefinitionContext context)
{
context.Add(
new SettingDefinition(LocalizationSettingNames.DefaultLanguage, "en", isVisibleToClients: true)
new SettingDefinition(LocalizationSettingNames.DefaultLanguage,
"en",
L("DisplayName:Abp.Localization.DefaultLanguage"),
L("Description:Abp.Localization.DefaultLanguage"),
isVisibleToClients: true)
);
}
private static LocalizableString L(string name)
{
return LocalizableString.Create<AbpValidationResource>(name);
}
}
}

10
framework/src/Volo.Abp.Localization/Volo/Abp/Localization/Resources/AbpLocalization/AbpLocalizationResource.cs

@ -0,0 +1,10 @@
using System;
namespace Volo.Abp.Localization.Resources.AbpLocalization
{
[LocalizationResourceName("AbpLocalization")]
public class AbpLocalizationResource
{
}
}

7
framework/src/Volo.Abp.Localization/Volo/Abp/Localization/Resources/AbpLocalization/en.json

@ -0,0 +1,7 @@
{
"culture": "en",
"texts": {
"DisplayName:Abp.Localization.DefaultLanguage": "Default language",
"Description:Abp.Localization.DefaultLanguage": "The default language of the application."
}
}

7
framework/src/Volo.Abp.Localization/Volo/Abp/Localization/Resources/AbpLocalization/zh-Hans.json

@ -0,0 +1,7 @@
{
"culture": "zh-Hans",
"texts": {
"DisplayName:Abp.Localization.DefaultLanguage": "默认语言",
"Description:Abp.Localization.DefaultLanguage": "应用程序的默认语言."
}
}

5
framework/src/Volo.Abp.Localization/Volo/Abp/Localization/Resources/AbpValidation/AbpValidationResource.cs

@ -1,8 +1,11 @@
namespace Volo.Abp.Localization.Resources.AbpValidation
using System;
namespace Volo.Abp.Localization.Resources.AbpValidation
{
//TODO: Move to Volo.Abp.Validation!
[LocalizationResourceName("AbpValidation")]
[Obsolete("This resource is obsolete.Use Volo.Abp.Validation.Localization.AbpValidationResource instead.", false)]
public class AbpValidationResource
{

79
framework/src/Volo.Abp.MemoryDb/Volo/Abp/Domain/Repositories/MemoryDb/MemoryDbRepository.cs

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.Domain.Entities;
@ -25,40 +26,52 @@ namespace Volo.Abp.Domain.Repositories.MemoryDb
DatabaseProvider = databaseProvider;
}
public override TEntity Insert(TEntity entity, bool autoSave = false)
protected override IQueryable<TEntity> GetQueryable()
{
Collection.Add(entity);
return entity;
return ApplyDataFilters(Collection.AsQueryable());
}
public override TEntity Update(TEntity entity, bool autoSave = false)
public override Task DeleteAsync(Expression<Func<TEntity, bool>> predicate, bool autoSave = false, CancellationToken cancellationToken = default)
{
Collection.Update(entity);
return entity;
var entities = Collection.AsQueryable().Where(predicate).ToList();
foreach (var entity in entities)
{
Collection.Remove(entity);
}
return Task.CompletedTask;
}
public override void Delete(TEntity entity, bool autoSave = false)
public override Task<TEntity> InsertAsync(TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default)
{
Collection.Remove(entity);
Collection.Add(entity);
return Task.FromResult(entity);
}
public override Task<TEntity> UpdateAsync(TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default)
{
Collection.Update(entity);
return Task.FromResult(entity);
}
public override List<TEntity> GetList(bool includeDetails = false)
public override Task DeleteAsync(TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default)
{
return Collection.ToList();
Collection.Remove(entity);
return Task.CompletedTask;
}
public override long GetCount()
public override Task<List<TEntity>> GetListAsync(bool includeDetails = false, CancellationToken cancellationToken = default)
{
return Collection.Count();
return Task.FromResult(Collection.ToList());
}
protected override IQueryable<TEntity> GetQueryable()
public override Task<long> GetCountAsync(CancellationToken cancellationToken = default)
{
return ApplyDataFilters(Collection.AsQueryable());
return Task.FromResult(Collection.LongCount());
}
}
public class MemoryDbRepository<TMemoryDbContext, TEntity, TKey> : MemoryDbRepository<TMemoryDbContext, TEntity>, IMemoryDbRepository<TEntity, TKey>
public class MemoryDbRepository<TMemoryDbContext, TEntity, TKey> : MemoryDbRepository<TMemoryDbContext, TEntity>, IMemoryDbRepository<TEntity, TKey>
where TMemoryDbContext : MemoryDbContext
where TEntity : class, IEntity<TKey>
{
@ -67,16 +80,16 @@ namespace Volo.Abp.Domain.Repositories.MemoryDb
{
}
public override TEntity Insert(TEntity entity, bool autoSave = false)
public override Task<TEntity> InsertAsync(TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default)
{
SetIdIfNeeded(entity);
return base.Insert(entity, autoSave);
return base.InsertAsync(entity, autoSave, cancellationToken);
}
protected virtual void SetIdIfNeeded(TEntity entity)
{
if (typeof(TKey) == typeof(int) ||
typeof(TKey) == typeof(long) ||
if (typeof(TKey) == typeof(int) ||
typeof(TKey) == typeof(long) ||
typeof(TKey) == typeof(Guid))
{
if (EntityHelper.HasDefaultId(entity))
@ -86,14 +99,9 @@ namespace Volo.Abp.Domain.Repositories.MemoryDb
}
}
public virtual TEntity Find(TKey id, bool includeDetails = true)
{
return GetQueryable().FirstOrDefault(e => e.Id.Equals(id));
}
public virtual TEntity Get(TKey id, bool includeDetails = true)
public virtual async Task<TEntity> GetAsync(TKey id, bool includeDetails = true, CancellationToken cancellationToken = default)
{
var entity = Find(id, includeDetails);
var entity = await FindAsync(id, includeDetails, cancellationToken);
if (entity == null)
{
@ -103,31 +111,20 @@ namespace Volo.Abp.Domain.Repositories.MemoryDb
return entity;
}
public virtual Task<TEntity> GetAsync(TKey id, bool includeDetails = true, CancellationToken cancellationToken = default)
{
return Task.FromResult(Get(id, includeDetails));
}
public virtual Task<TEntity> FindAsync(TKey id, bool includeDetails = true, CancellationToken cancellationToken = default)
{
return Task.FromResult(Find(id, includeDetails));
return Task.FromResult(GetQueryable().FirstOrDefault(e => e.Id.Equals(id)));
}
public virtual void Delete(TKey id, bool autoSave = false)
public virtual async Task DeleteAsync(TKey id, bool autoSave = false, CancellationToken cancellationToken = default)
{
var entity = Find(id);
var entity = await FindAsync(id, cancellationToken: cancellationToken);
if (entity == null)
{
return;
}
Delete(entity);
}
public virtual Task DeleteAsync(TKey id, bool autoSave = false, CancellationToken cancellationToken = default)
{
Delete(id);
return Task.CompletedTask;
await DeleteAsync(entity, autoSave, cancellationToken);
}
}
}

2
framework/src/Volo.Abp.MongoDB/Volo.Abp.MongoDB.csproj

@ -14,7 +14,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="MongoDB.Driver" Version="2.9.2" />
<PackageReference Include="MongoDB.Driver" Version="2.10.0" />
</ItemGroup>
<ItemGroup>

120
framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/MongoDbRepository.cs

@ -53,20 +53,6 @@ namespace Volo.Abp.Domain.Repositories.MongoDB
EntityChangeEventHelper = NullEntityChangeEventHelper.Instance;
}
public override TEntity Insert(TEntity entity, bool autoSave = false)
{
/* EntityCreatedEvent (OnUowCompleted) is triggered as the first because it should be
* triggered before other events triggered inside an EntityCreating event handler.
* This is also true for other "ed" & "ing" events.
*/
AsyncHelper.RunSync(() => ApplyAbpConceptsForAddedEntityAsync(entity));
Collection.InsertOne(entity);
return entity;
}
public override async Task<TEntity> InsertAsync(
TEntity entity,
bool autoSave = false,
@ -82,37 +68,6 @@ namespace Volo.Abp.Domain.Repositories.MongoDB
return entity;
}
public override TEntity Update(TEntity entity, bool autoSave = false)
{
SetModificationAuditProperties(entity);
if (entity is ISoftDelete softDeleteEntity && softDeleteEntity.IsDeleted)
{
SetDeletionAuditProperties(entity);
AsyncHelper.RunSync(() => TriggerEntityDeleteEventsAsync(entity));
}
else
{
AsyncHelper.RunSync(() => TriggerEntityUpdateEventsAsync(entity));
}
AsyncHelper.RunSync(() => TriggerDomainEventsAsync(entity));
var oldConcurrencyStamp = SetNewConcurrencyStamp(entity);
var result = Collection.ReplaceOne(
CreateEntityFilter(entity, true, oldConcurrencyStamp),
entity
);
if (result.MatchedCount <= 0)
{
ThrowOptimisticConcurrencyException();
}
return entity;
}
public override async Task<TEntity> UpdateAsync(
TEntity entity,
bool autoSave = false,
@ -148,37 +103,6 @@ namespace Volo.Abp.Domain.Repositories.MongoDB
return entity;
}
public override void Delete(TEntity entity, bool autoSave = false)
{
AsyncHelper.RunSync(() => ApplyAbpConceptsForDeletedEntityAsync(entity));
var oldConcurrencyStamp = SetNewConcurrencyStamp(entity);
if (entity is ISoftDelete softDeleteEntity)
{
softDeleteEntity.IsDeleted = true;
var result = Collection.ReplaceOne(
CreateEntityFilter(entity, true, oldConcurrencyStamp),
entity
);
if (result.MatchedCount <= 0)
{
ThrowOptimisticConcurrencyException();
}
}
else
{
var result = Collection.DeleteOne(
CreateEntityFilter(entity, true, oldConcurrencyStamp)
);
if (result.DeletedCount <= 0)
{
ThrowOptimisticConcurrencyException();
}
}
}
public override async Task DeleteAsync(
TEntity entity,
bool autoSave = false,
@ -215,38 +139,16 @@ namespace Volo.Abp.Domain.Repositories.MongoDB
}
}
public override List<TEntity> GetList(bool includeDetails = false)
{
return GetMongoQueryable().ToList();
}
public override async Task<List<TEntity>> GetListAsync(bool includeDetails = false, CancellationToken cancellationToken = default)
{
return await GetMongoQueryable().ToListAsync(GetCancellationToken(cancellationToken));
}
public override long GetCount()
{
return GetMongoQueryable().LongCount();
}
public override async Task<long> GetCountAsync(CancellationToken cancellationToken = default)
{
return await GetMongoQueryable().LongCountAsync(GetCancellationToken(cancellationToken));
}
public override void Delete(Expression<Func<TEntity, bool>> predicate, bool autoSave = false)
{
var entities = GetMongoQueryable()
.Where(predicate)
.ToList();
foreach (var entity in entities)
{
Delete(entity, autoSave);
}
}
public override async Task DeleteAsync(
Expression<Func<TEntity, bool>> predicate,
bool autoSave = false,
@ -417,18 +319,6 @@ namespace Volo.Abp.Domain.Repositories.MongoDB
}
public virtual TEntity Get(TKey id, bool includeDetails = true)
{
var entity = Find(id, includeDetails);
if (entity == null)
{
throw new EntityNotFoundException(typeof(TEntity), id);
}
return entity;
}
public virtual async Task<TEntity> GetAsync(
TKey id,
bool includeDetails = true,
@ -454,16 +344,6 @@ namespace Volo.Abp.Domain.Repositories.MongoDB
.FirstOrDefaultAsync(GetCancellationToken(cancellationToken));
}
public virtual TEntity Find(TKey id, bool includeDetails = true)
{
return Collection.Find(CreateEntityFilter(id, true)).FirstOrDefault();
}
public virtual void Delete(TKey id, bool autoSave = false)
{
Collection.DeleteOne(CreateEntityFilter(id));
}
public virtual Task DeleteAsync(
TKey id,
bool autoSave = false,

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

@ -53,31 +53,16 @@ namespace Volo.Abp.Uow
_parent.Reserve(reservationName);
}
public void SaveChanges()
{
_parent.SaveChanges();
}
public Task SaveChangesAsync(CancellationToken cancellationToken = default)
{
return _parent.SaveChangesAsync(cancellationToken);
}
public void Complete()
{
}
public Task CompleteAsync(CancellationToken cancellationToken = default)
{
return Task.CompletedTask;
}
public void Rollback()
{
_parent.Rollback();
}
public Task RollbackAsync(CancellationToken cancellationToken = default)
{
return _parent.RollbackAsync(cancellationToken);

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

@ -32,16 +32,10 @@ namespace Volo.Abp.Uow
void Reserve([NotNull] string reservationName);
void SaveChanges();
Task SaveChangesAsync(CancellationToken cancellationToken = default);
void Complete();
Task CompleteAsync(CancellationToken cancellationToken = default);
void Rollback();
Task RollbackAsync(CancellationToken cancellationToken = default);
void OnCompleted(Func<Task> handler);

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

@ -5,7 +5,6 @@ using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Options;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Threading;
namespace Volo.Abp.Uow
{
@ -75,14 +74,6 @@ namespace Volo.Abp.Uow
Outer = outer;
}
public virtual void SaveChanges()
{
foreach (var databaseApi in GetAllActiveDatabaseApis())
{
(databaseApi as ISupportsSavingChanges)?.SaveChanges();
}
}
public virtual async Task SaveChangesAsync(CancellationToken cancellationToken = default)
{
foreach (var databaseApi in GetAllActiveDatabaseApis())
@ -104,30 +95,6 @@ namespace Volo.Abp.Uow
return _transactionApis.Values.ToImmutableList();
}
public virtual void Complete()
{
if (_isRolledback)
{
return;
}
PreventMultipleComplete();
try
{
_isCompleting = true;
SaveChanges();
CommitTransactions();
IsCompleted = true;
OnCompleted();
}
catch (Exception ex)
{
_exception = ex;
throw;
}
}
public virtual async Task CompleteAsync(CancellationToken cancellationToken = default)
{
if (_isRolledback)
@ -152,18 +119,6 @@ namespace Volo.Abp.Uow
}
}
public virtual void Rollback()
{
if (_isRolledback)
{
return;
}
_isRolledback = true;
RollbackAll();
}
public virtual async Task RollbackAsync(CancellationToken cancellationToken = default)
{
if (_isRolledback)
@ -235,19 +190,6 @@ namespace Volo.Abp.Uow
CompletedHandlers.Add(handler);
}
public void OnFailed(Func<Task> handler)
{
throw new NotImplementedException();
}
protected virtual void OnCompleted()
{
foreach (var handler in CompletedHandlers)
{
AsyncHelper.RunSync(handler);
}
}
protected virtual async Task OnCompletedAsync()
{
foreach (var handler in CompletedHandlers)

15
framework/src/Volo.Abp.Uow/Volo/Abp/Uow/UnitOfWorkInterceptor.cs

@ -18,21 +18,6 @@ namespace Volo.Abp.Uow
_defaultOptions = options.Value;
}
public override void Intercept(IAbpMethodInvocation invocation)
{
if (!UnitOfWorkHelper.IsUnitOfWorkMethod(invocation.Method, out var unitOfWorkAttribute))
{
invocation.Proceed();
return;
}
using (var uow = _unitOfWorkManager.Begin(CreateOptions(invocation, unitOfWorkAttribute)))
{
invocation.Proceed();
uow.Complete();
}
}
public override async Task InterceptAsync(IAbpMethodInvocation invocation)
{
if (!UnitOfWorkHelper.IsUnitOfWorkMethod(invocation.Method, out var unitOfWorkAttribute))

8
framework/src/Volo.Abp.Validation/Volo.Abp.Validation.csproj

@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\common.props" />
@ -13,8 +13,14 @@
<RootNamespace />
</PropertyGroup>
<ItemGroup>
<None Remove="Volo\Abp\Validation\Localization\*.json" />
<EmbeddedResource Include="Volo\Abp\Validation\Localization\*.json" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Volo.Abp.Core\Volo.Abp.Core.csproj" />
<ProjectReference Include="..\Volo.Abp.Localization\Volo.Abp.Localization.csproj" />
</ItemGroup>
</Project>

20
framework/src/Volo.Abp.Validation/Volo/Abp/Validation/AbpValidationModule.cs

@ -1,10 +1,16 @@
using System;
using System.Collections.Generic;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Localization;
using Volo.Abp.Modularity;
using Volo.Abp.Validation.Localization;
using Volo.Abp.VirtualFileSystem;
namespace Volo.Abp.Validation
{
[DependsOn(
typeof(AbpLocalizationModule)
)]
public class AbpValidationModule : AbpModule
{
public override void PreConfigureServices(ServiceConfigurationContext context)
@ -12,6 +18,20 @@ namespace Volo.Abp.Validation
context.Services.OnRegistred(ValidationInterceptorRegistrar.RegisterIfNeeded);
AutoAddObjectValidationContributors(context.Services);
}
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpVirtualFileSystemOptions>(options =>
{
options.FileSets.AddEmbedded<AbpValidationResource>();
});
Configure<AbpLocalizationOptions>(options =>
{
options.Resources
.Add<AbpValidationResource>("en")
.AddVirtualJson("/Volo/Abp/Validation/Localization");
});
}
private static void AutoAddObjectValidationContributors(IServiceCollection services)
{

10
framework/src/Volo.Abp.Validation/Volo/Abp/Validation/Localization/AbpValidationResource.cs

@ -0,0 +1,10 @@
using Volo.Abp.Localization;
namespace Volo.Abp.Validation.Localization
{
[LocalizationResourceName("AbpValidation")]
public class AbpValidationResource
{
}
}

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

Loading…
Cancel
Save