Browse Source

Merge branch 'dev' into bs5

pull/10355/head
maliming 5 years ago
parent
commit
17db513e95
No known key found for this signature in database GPG Key ID: 96224957E51C89E
  1. 5
      .github/workflows/build-and-test.yml
  2. 5
      Directory.Build.props
  3. 2
      build/test-all.ps1
  4. 3
      codecov.yml
  5. 8
      common.test.props
  6. 99
      docs/en/Background-Workers-Hangfire.md
  7. 11
      docs/en/Background-Workers.md
  8. 53
      docs/en/Distributed-Event-Bus.md
  9. 50
      docs/en/Local-Event-Bus.md
  10. 3
      docs/en/Module-Entity-Extensions.md
  11. 4
      docs/en/Testing.md
  12. 10
      docs/en/UI/Angular/Extensions-Overall.md
  13. 8
      docs/en/docs-nav.json
  14. 100
      docs/zh-Hans/Background-Workers-Hangfire.md
  15. 8
      docs/zh-Hans/Background-Workers.md
  16. 53
      docs/zh-Hans/Distributed-Event-Bus.md
  17. 46
      docs/zh-Hans/Local-Event-Bus.md
  18. 4
      docs/zh-Hans/docs-nav.json
  19. 30
      framework/Volo.Abp.sln
  20. 2
      framework/src/Volo.Abp.BackgroundJobs/Volo.Abp.BackgroundJobs.csproj
  21. 4
      framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/AbpBackgroundJobsModule.cs
  22. 103
      framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/BackgroundJobWorker.cs
  23. 3
      framework/src/Volo.Abp.BackgroundWorkers.Hangfire/FodyWeavers.xml
  24. 2
      framework/src/Volo.Abp.BackgroundWorkers.Hangfire/FodyWeavers.xsd
  25. 7
      framework/src/Volo.Abp.BackgroundWorkers.Hangfire/Volo.Abp.BackgroundWorkers.Hangfire.csproj
  26. 36
      framework/src/Volo.Abp.BackgroundWorkers.Hangfire/Volo/Abp/BackgroundWorkers/Hangfire/AbpBackgroundWorkersHangfireModule.cs
  27. 13
      framework/src/Volo.Abp.BackgroundWorkers.Hangfire/Volo/Abp/BackgroundWorkers/Hangfire/HangfireBackgroundWorkerBase.cs
  28. 91
      framework/src/Volo.Abp.BackgroundWorkers.Hangfire/Volo/Abp/BackgroundWorkers/Hangfire/HangfireBackgroundWorkerManager.cs
  29. 36
      framework/src/Volo.Abp.BackgroundWorkers.Hangfire/Volo/Abp/BackgroundWorkers/Hangfire/HangfirePeriodicBackgroundWorkerAdapter.cs
  30. 15
      framework/src/Volo.Abp.BackgroundWorkers.Hangfire/Volo/Abp/BackgroundWorkers/Hangfire/IHangfireBackgroundWorker.cs
  31. 11
      framework/src/Volo.Abp.BackgroundWorkers/Volo/Abp/BackgroundWorkers/BackgroundWorkerBase.cs
  32. 2
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Auth/LoginInfo.cs
  33. 9
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Bundling/BundlerBase.cs
  34. 2
      framework/src/Volo.Abp.Ddd.Domain/Volo.Abp.Ddd.Domain.csproj
  35. 2
      framework/src/Volo.Abp.Ddd.Domain/Volo.Abp.Ddd.Domain.csproj.DotSettings
  36. 3
      framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/AbpDddDomainModule.cs
  37. 3
      framework/src/Volo.Abp.DistributedLocking.Abstractions/FodyWeavers.xml
  38. 30
      framework/src/Volo.Abp.DistributedLocking.Abstractions/FodyWeavers.xsd
  39. 21
      framework/src/Volo.Abp.DistributedLocking.Abstractions/Volo.Abp.DistributedLocking.Abstractions.csproj
  40. 9
      framework/src/Volo.Abp.DistributedLocking.Abstractions/Volo/Abp/DistributedLocking/AbpDistributedLockingAbstractionsModule.cs
  41. 26
      framework/src/Volo.Abp.DistributedLocking.Abstractions/Volo/Abp/DistributedLocking/IAbpDistributedLock.cs
  42. 9
      framework/src/Volo.Abp.DistributedLocking.Abstractions/Volo/Abp/DistributedLocking/IAbpDistributedLockHandle.cs
  43. 30
      framework/src/Volo.Abp.DistributedLocking.Abstractions/Volo/Abp/DistributedLocking/LocalAbpDistributedLock.cs
  44. 21
      framework/src/Volo.Abp.DistributedLocking.Abstractions/Volo/Abp/DistributedLocking/LocalAbpDistributedLockHandle.cs
  45. 2
      framework/src/Volo.Abp.DistributedLocking/Volo.Abp.DistributedLocking.csproj
  46. 14
      framework/src/Volo.Abp.DistributedLocking/Volo/Abp/DistributedLocking/AbpDistributedLockHandleExtensions.cs
  47. 3
      framework/src/Volo.Abp.DistributedLocking/Volo/Abp/DistributedLocking/AbpDistributedLockingModule.cs
  48. 35
      framework/src/Volo.Abp.DistributedLocking/Volo/Abp/DistributedLocking/MedallionAbpDistributedLock.cs
  49. 20
      framework/src/Volo.Abp.DistributedLocking/Volo/Abp/DistributedLocking/MedallionAbpDistributedLockHandle.cs
  50. 9
      framework/src/Volo.Abp.EntityFrameworkCore.PostgreSql/Volo/Abp/EntityFrameworkCore/PostgreSql/AbpEntityFrameworkCorePostgreSqlModule.cs
  51. 3
      framework/src/Volo.Abp.EventBus.Boxes/FodyWeavers.xml
  52. 20
      framework/src/Volo.Abp.EventBus.Boxes/Volo/Abp/EventBus/Boxes/AbpEventBusBoxesModule.cs
  53. 20
      framework/src/Volo.Abp.EventBus.Boxes/Volo/Abp/EventBus/Boxes/TaskHelper.cs
  54. 2
      framework/src/Volo.Abp.EventBus/Volo.Abp.EventBus.csproj
  55. 13
      framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/AbpEventBusModule.cs
  56. 0
      framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/AbpDistributedEventBusExtensions.cs
  57. 0
      framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/AbpEventBusBoxesOptions.cs
  58. 0
      framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/IInboxProcessor.cs
  59. 0
      framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/IOutboxSender.cs
  60. 0
      framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/InboxProcessManager.cs
  61. 20
      framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/InboxProcessor.cs
  62. 22
      framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/OutboxSender.cs
  63. 0
      framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/OutboxSenderManager.cs
  64. 3
      framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/ClientProxying/ClientProxyBase.cs
  65. 2
      framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Tests/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Tests.csproj
  66. 18
      framework/test/Volo.Abp.DistributedLocking.Abstractions.Tests/Volo.Abp.DistributedLocking.Abstractions.Tests.csproj
  67. 12
      framework/test/Volo.Abp.DistributedLocking.Abstractions.Tests/Volo/Abp/DistributedLocking/AbpDistributedLockingAbstractionsTestBase.cs
  68. 15
      framework/test/Volo.Abp.DistributedLocking.Abstractions.Tests/Volo/Abp/DistributedLocking/AbpDistributedLockingAbstractionsTestModule.cs
  69. 73
      framework/test/Volo.Abp.DistributedLocking.Abstractions.Tests/Volo/Abp/DistributedLocking/LocalDistributedLock_Tests.cs
  70. 1
      framework/test/Volo.Abp.Serialization.Tests/Volo/Abp/Serialization/Objects/CarSerializer.cs
  71. 2
      global.json
  72. 24
      modules/account/src/Volo.Abp.Account.Application.Contracts/Volo/Abp/Account/Localization/Resources/it.json
  73. 7
      modules/account/test/Volo.Abp.Account.Application.Tests/Volo.Abp.Account.Application.Tests.csproj
  74. 7
      modules/audit-logging/test/Volo.Abp.AuditLogging.EntityFrameworkCore.Tests/Volo.Abp.AuditLogging.EntityFrameworkCore.Tests.csproj
  75. 7
      modules/audit-logging/test/Volo.Abp.AuditLogging.MongoDB.Tests/Volo.Abp.AuditLogging.MongoDB.Tests.csproj
  76. 7
      modules/audit-logging/test/Volo.Abp.AuditLogging.TestBase/Volo.Abp.AuditLogging.TestBase.csproj
  77. 7
      modules/audit-logging/test/Volo.Abp.AuditLogging.Tests/Volo.Abp.AuditLogging.Tests.csproj
  78. 4
      modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp/DemoAppModule.cs
  79. 7
      modules/background-jobs/test/Volo.Abp.BackgroundJobs.Domain.Tests/Volo.Abp.BackgroundJobs.Domain.Tests.csproj
  80. 7
      modules/background-jobs/test/Volo.Abp.BackgroundJobs.EntityFrameworkCore.Tests/Volo.Abp.BackgroundJobs.EntityFrameworkCore.Tests.csproj
  81. 7
      modules/background-jobs/test/Volo.Abp.BackgroundJobs.MongoDB.Tests/Volo.Abp.BackgroundJobs.MongoDB.Tests.csproj
  82. 7
      modules/background-jobs/test/Volo.Abp.BackgroundJobs.TestBase/Volo.Abp.BackgroundJobs.TestBase.csproj
  83. 7
      modules/basic-theme/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo.Tests/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo.Tests.csproj
  84. 7
      modules/blob-storing-database/test/Volo.Abp.BlobStoring.Database.Domain.Tests/Volo.Abp.BlobStoring.Database.Domain.Tests.csproj
  85. 7
      modules/blob-storing-database/test/Volo.Abp.BlobStoring.Database.EntityFrameworkCore.Tests/Volo.Abp.BlobStoring.Database.EntityFrameworkCore.Tests.csproj
  86. 7
      modules/blob-storing-database/test/Volo.Abp.BlobStoring.Database.MongoDB.Tests/Volo.Abp.BlobStoring.Database.MongoDB.Tests.csproj
  87. 7
      modules/blob-storing-database/test/Volo.Abp.BlobStoring.Database.TestBase/Volo.Abp.BlobStoring.Database.TestBase.csproj
  88. 7
      modules/blogging/test/Volo.Blogging.Application.Tests/Volo.Blogging.Application.Tests.csproj
  89. 7
      modules/blogging/test/Volo.Blogging.Domain.Tests/Volo.Blogging.Domain.Tests.csproj
  90. 7
      modules/blogging/test/Volo.Blogging.EntityFrameworkCore.Tests/Volo.Blogging.EntityFrameworkCore.Tests.csproj
  91. 7
      modules/blogging/test/Volo.Blogging.MongoDB.Tests/Volo.Blogging.MongoDB.Tests.csproj
  92. 7
      modules/blogging/test/Volo.Blogging.TestBase/Volo.Blogging.TestBase.csproj
  93. 7
      modules/cms-kit/test/Volo.CmsKit.Application.Tests/Volo.CmsKit.Application.Tests.csproj
  94. 7
      modules/cms-kit/test/Volo.CmsKit.Domain.Tests/Volo.CmsKit.Domain.Tests.csproj
  95. 7
      modules/cms-kit/test/Volo.CmsKit.EntityFrameworkCore.Tests/Volo.CmsKit.EntityFrameworkCore.Tests.csproj
  96. 7
      modules/cms-kit/test/Volo.CmsKit.MongoDB.Tests/Volo.CmsKit.MongoDB.Tests.csproj
  97. 7
      modules/cms-kit/test/Volo.CmsKit.TestBase/Volo.CmsKit.TestBase.csproj
  98. 7
      modules/docs/test/Volo.Docs.Admin.Application.Tests/Volo.Docs.Admin.Application.Tests.csproj
  99. 7
      modules/docs/test/Volo.Docs.Application.Tests/Volo.Docs.Application.Tests.csproj
  100. 7
      modules/docs/test/Volo.Docs.Domain.Tests/Volo.Docs.Domain.Tests.csproj

5
.github/workflows/build-and-test.yml

@ -21,7 +21,7 @@ jobs:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- uses: actions/setup-dotnet@master - uses: actions/setup-dotnet@master
with: with:
dotnet-version: 6.0.100-rc.1.21458.32 dotnet-version: 6.0.100-rc.2.21505.57
- name: Build All - name: Build All
run: .\build-all.ps1 run: .\build-all.ps1
@ -32,3 +32,6 @@ jobs:
run: .\test-all.ps1 run: .\test-all.ps1
working-directory: .\build working-directory: .\build
shell: powershell shell: powershell
- name: Codecov
uses: codecov/codecov-action@v2

5
Directory.Build.props

@ -2,7 +2,7 @@
<PropertyGroup> <PropertyGroup>
<!-- All Microsoft packages --> <!-- All Microsoft packages -->
<MicrosoftPackageVersion>6.0.0-rc.*</MicrosoftPackageVersion> <MicrosoftPackageVersion>6.0.0-rc.2.*</MicrosoftPackageVersion>
<!-- Microsoft.NET.Test.Sdk https://www.nuget.org/packages/Microsoft.NET.Test.Sdk --> <!-- Microsoft.NET.Test.Sdk https://www.nuget.org/packages/Microsoft.NET.Test.Sdk -->
<MicrosoftNETTestSdkPackageVersion>16.11.0</MicrosoftNETTestSdkPackageVersion> <MicrosoftNETTestSdkPackageVersion>16.11.0</MicrosoftNETTestSdkPackageVersion>
@ -25,5 +25,8 @@
<!-- Mongo2Go https://www.nuget.org/packages/Mongo2Go --> <!-- Mongo2Go https://www.nuget.org/packages/Mongo2Go -->
<Mongo2GoPackageVersion>3.1.3</Mongo2GoPackageVersion> <Mongo2GoPackageVersion>3.1.3</Mongo2GoPackageVersion>
<!-- coverlet.collector https://www.nuget.org/packages/coverlet.collector -->
<CoverletCollectorPackageVersion>3.1.0</CoverletCollectorPackageVersion>
</PropertyGroup> </PropertyGroup>
</Project> </Project>

2
build/test-all.ps1

@ -7,7 +7,7 @@ $full = $args[0]
foreach ($solutionPath in $solutionPaths) { foreach ($solutionPath in $solutionPaths) {
$solutionAbsPath = (Join-Path $rootFolder $solutionPath) $solutionAbsPath = (Join-Path $rootFolder $solutionPath)
Set-Location $solutionAbsPath Set-Location $solutionAbsPath
dotnet test --no-build --no-restore dotnet test --no-build --no-restore --collect:"XPlat Code Coverage"
if (-Not $?) { if (-Not $?) {
Write-Host ("Test failed for the solution: " + $solutionPath) Write-Host ("Test failed for the solution: " + $solutionPath)
Set-Location $rootFolder Set-Location $rootFolder

3
codecov.yml

@ -0,0 +1,3 @@
codecov:
branch: dev
require_ci_to_pass: yes

8
common.test.props

@ -7,4 +7,12 @@
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute> <GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute> <GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
</PropertyGroup> </PropertyGroup>
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="3.1.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project> </Project>

99
docs/en/Background-Workers-Hangfire.md

@ -0,0 +1,99 @@
# Hangfire Background Worker Manager
[Hangfire](https://https://www.hangfire.io/) is an advanced background jobs and worker manager. You can integrate Hangfire with the ABP Framework to use it instead of the [default background worker manager](Background-Workers.md).
The major advantage is that you can use the same server farm to manage your Background Jobs and Workers, as well as leverage the advanced scheduling that is available from Hangfire for [Recurring Jobs](https://docs.hangfire.io/en/latest/background-methods/performing-recurrent-tasks.html?highlight=recurring), aka Background Workers.
## Installation
It is suggested to use the [ABP CLI](CLI.md) to install this package.
### Using the ABP CLI
Open a command line window in the folder of the project (.csproj file) and type the following command:
````bash
abp add-package Volo.Abp.BackgroundWorkers.Hangfire
````
### Manual Installation
If you want to manually install;
1. Add the [Volo.Abp.BackgroundWorkers.Hangfire](https://www.nuget.org/packages/Volo.Abp.BackgroundWorkers.Hangfire) NuGet package to your project:
````
Install-Package Volo.Abp.BackgroundWorkers.Hangfire
````
2. Add the `AbpBackgroundWorkersHangfireModule` to the dependency list of your module:
````csharp
[DependsOn(
//...other dependencies
typeof(AbpBackgroundWorkersHangfireModule) //Add the new module dependency
)]
public class YourModule : AbpModule
{
}
````
> Hangfire background worker integration provides an adapter `HangfirePeriodicBackgroundWorkerAdapter` to automatically load any `PeriodicBackgroundWorkerBase` and `AsyncPeriodicBackgroundWorkerBase` derived classes as `IHangfireBackgroundWorker` instances. This allows you to still to easily switch over to use Hangfire as the background manager even you have existing background workers that are based on the [default background workers implementation](Background-Workers.md).
## Create a Background Worker
`HangfireBackgroundWorkerBase` is an easy way to create a background worker.
```` csharp
public class MyLogWorker : HangfireBackgroundWorkerBase
{
public MyLogWorker()
{
RecurringJobId = nameof(MyLogWorker);
CronExpression = Cron.Daily();
}
public override Task DoWorkAsync()
{
Logger.LogInformation("Executed MyLogWorker..!");
return Task.CompletedTask;
}
}
````
* **RecurringJobId** Is an optional parameter, see [Hangfire document](https://docs.hangfire.io/en/latest/background-methods/performing-recurrent-tasks.html)
* **CronExpression** Is a CRON expression, see [CRON expression](https://en.wikipedia.org/wiki/Cron#CRON_expression)
> You can directly implement the `IHangfireBackgroundWorker`, but `HangfireBackgroundWorkerBase` provides some useful properties like Logger.
## Register BackgroundWorkerManager
After creating a background worker class, you should add it to the `IBackgroundWorkerManager`. The most common place is the `OnApplicationInitialization` method of your module class:
```` csharp
[DependsOn(typeof(AbpBackgroundWorkersModule))]
public class MyModule : AbpModule
{
public override void OnApplicationInitialization(
ApplicationInitializationContext context)
{
context.AddBackgroundWorker<MyLogWorker>();
}
}
````
`context.AddBackgroundWorker(...)` is a shortcut extension method for the expression below:
```` csharp
context.ServiceProvider
.GetRequiredService<IBackgroundWorkerManager>()
.Add(
context
.ServiceProvider
.GetRequiredService<MyLogWorker>()
);
````
So, it resolves the given background worker and adds to the `IBackgroundWorkerManager`.
While we generally add workers in OnApplicationInitialization, there are no restrictions on that. You can inject IBackgroundWorkerManager anywhere and add workers at runtime. Background worker manager will stop and release all the registered workers when your application is being shut down.

11
docs/en/Background-Workers.md

@ -131,10 +131,15 @@ If that's a problem for your workers, you have two options;
* Disable the background worker system using the `AbpBackgroundWorkerOptions` described above, for all the application instances, except one of them. * Disable the background worker system using the `AbpBackgroundWorkerOptions` described above, for all the application instances, except one of them.
* Disable the background worker system for all the application instances and create another special application that runs on a single server and execute the workers. * Disable the background worker system for all the application instances and create another special application that runs on a single server and execute the workers.
## Quartz Integration ## Integrations
ABP Framework's background worker system is good to implement periodic tasks. However, you may want to use an advanced task scheduler like [Quartz](https://www.quartz-scheduler.net/). See the community contributed [quartz integration](Background-Workers-Quartz.md) for the background workers. Background worker system is extensible and you can change the default background worker manager with your own implementation or on of the pre-built integrations.
See pre-built worker manager alternatives:
* [Quartz Background Worker Manager](Background-Workers-Quartz.md)
* [Hangfire Background Worker Manager](Background-Workers-Hangfire.md)
## See Also ## See Also
* [Quartz Integration for the background workers](Background-Workers-Quartz.md)
* [Background Jobs](Background-Jobs.md) * [Background Jobs](Background-Jobs.md)

53
docs/en/Distributed-Event-Bus.md

@ -302,55 +302,4 @@ namespace AbpDemo
} }
```` ````
This example uses the `AutoMap` attribute of the AutoMapper to configure the mapping. You could create a profile class instead. Please refer to the AutoMapper document for more options. This example uses the `AutoMap` attribute of the AutoMapper to configure the mapping. You could create a profile class instead. Please refer to the AutoMapper document for more options.
## Exception Handling
ABP provides exception handling and retries when an exception occurs, it will move to the dead letter queue after the retry fails.
Enable exception handling:
```csharp
public override void PreConfigureServices(ServiceConfigurationContext context)
{
PreConfigure<AbpEventBusOptions>(options =>
{
options.EnabledErrorHandle = true;
options.UseRetryStrategy();
});
}
```
* `EnabledErrorHandle` is used to enable exception handing.
* `UseRetryStrategy` is used to enable retry.
When an exception occurs, it will retry every three seconds up to the maximum number of retries(default is 3) and move to dead letter queue, you can change the number of retries, retry interval and dead letter queue name:
```csharp
PreConfigure<AbpEventBusOptions>(options =>
{
options.DeadLetterName = "dead_queue";
options.UseRetryStrategy(retryStrategyOptions =>
{
retryStrategyOptions.IntervalMillisecond = 0;
retryStrategyOptions.MaxRetryAttempts = 1;
});
});
```
### Error Handle Selector
By default all event types will be exception handling, you can use `ErrorHandleSelector` of `AbpEventBusOptions` to change it:
```csharp
PreConfigure<AbpEventBusOptions>(options =>
{
options.ErrorHandleSelector = type => type == typeof(MyExceptionHandleEventData);
});
```
`options.ErrorHandleSelector` actually a list of type predicate. You can write a lambda expression to define your filter.
### Customize Exception Handling
ABP defines the `IEventErrorHandler` interface and implemented by the provider, you can replace it via [dependency injection](Dependency-Injection.md)

50
docs/en/Local-Event-Bus.md

@ -143,7 +143,7 @@ namespace AbpDemo
{ {
public async Task HandleEventAsync(StockCountChangedEvent eventData) public async Task HandleEventAsync(StockCountChangedEvent eventData)
{ {
//TODO: your code that does somthing on the event //TODO: your code that does something on the event
} }
} }
} }
@ -158,52 +158,6 @@ If you perform **database operations** and use the [repositories](Repositories.m
> The handler class must be registered to the dependency injection (DI). The sample above uses the `ITransientDependency` to accomplish it. See the [DI document](Dependency-Injection.md) for more options. > The handler class must be registered to the dependency injection (DI). The sample above uses the `ITransientDependency` to accomplish it. See the [DI document](Dependency-Injection.md) for more options.
## Exception Handling
ABP provides exception handling and retries when an exception occurs.
Enable exception handling:
```csharp
public override void PreConfigureServices(ServiceConfigurationContext context)
{
PreConfigure<AbpEventBusOptions>(options =>
{
options.UseRetryStrategy();
});
}
```
When an exception occurs, it will retry every three seconds up to the maximum number of retries(default is 3) and throw the original exception, you can change the number of retries and the retry interval:
```csharp
PreConfigure<AbpEventBusOptions>(options =>
{
options.UseRetryStrategy(retryStrategyOptions =>
{
retryStrategyOptions.IntervalMillisecond = 0;
retryStrategyOptions.MaxRetryAttempts = 1;
});
});
```
### Error Handle Selector
By default all event types will be exception handling, you can use `ErrorHandleSelector` of `AbpEventBusOptions` to change it:
```csharp
PreConfigure<AbpEventBusOptions>(options =>
{
options.ErrorHandleSelector = type => type == typeof(MyExceptionHandleEventData);
});
```
`options.ErrorHandleSelector` actually a list of type predicate. You can write a lambda expression to define your filter.
### Customize Exception Handling
ABP defines the `IEventErrorHandler` interface and implemented by `LocalEventErrorHandler`, you can replace it via [dependency injection](Dependency-Injection.md)
### Transaction & Exception Behavior ### Transaction & Exception Behavior
When an event published, subscribed event handlers are immediately executed. So; When an event published, subscribed event handlers are immediately executed. So;
@ -272,4 +226,4 @@ The event types are;
Pre-build events are published when you save changes to the database; Pre-build events are published when you save changes to the database;
* For EF Core, they are published on `DbContext.SaveChanges`. * For EF Core, they are published on `DbContext.SaveChanges`.
* For MongoDB, they are published when you call repository's `InsertAsync`, `UpdateAsync` or `DeleteAsync` methods (since MongoDB has not a change tracking system). * For MongoDB, they are published when you call repository's `InsertAsync`, `UpdateAsync` or `DeleteAsync` methods (since MongoDB has not a change tracking system).

3
docs/en/Module-Entity-Extensions.md

@ -491,3 +491,6 @@ Here, a few things you can do:
* You can override a domain or application service to perform custom logics with your new property. * You can override a domain or application service to perform custom logics with your new property.
* You can low level control how to add/render a field in the data table on the UI. * You can low level control how to add/render a field in the data table on the UI.
## See Also
* [Angular UI Extensions](UI/Angular/Extensions-Overall.md)

4
docs/en/Testing.md

@ -647,7 +647,7 @@ namespace MyProject.Issues
} }
```` ````
It's that simple. This test method tests everything, including the application service, EF Core mapping, object to object mapping and the repository implementation. In this way, you can fully test the Application Later and the Domain Layer of your solution. It's that simple. This test method tests everything, including the application service, EF Core mapping, object to object mapping and the repository implementation. In this way, you can fully test the Application Layer and the Domain Layer of your solution.
## UI Tests ## UI Tests
@ -670,4 +670,4 @@ See the following documents to learn Non Visual UI Testing;
Visual Tests are used to interact with the application UI just like a real user does. It fully tests the application, including the visual appearance of the pages and components. Visual Tests are used to interact with the application UI just like a real user does. It fully tests the application, including the visual appearance of the pages and components.
Visual UI Testing is out of the scope for the ABP Framework. There are a lot of tooling in the industry (like [Selenium](https://www.selenium.dev/)) that you can use to test your application's UI. Visual UI Testing is out of the scope for the ABP Framework. There are a lot of tooling in the industry (like [Selenium](https://www.selenium.dev/)) that you can use to test your application's UI.

10
docs/en/UI/Angular/Extensions-Overall.md

@ -0,0 +1,10 @@
## Angular UI Extensions
Angular UI extensions system allows you to add a new action to the actions menu, a new column to the data table, a new action to the toolbar of a page, and add a new field to the create and/or edit forms.
See the documents below for the details:
* [Entity Action Extensions](Entity-Action-Extensions.md)
* [Data Table Column (or Entity Prop) Extensions](Data-Table-Column-Extensions.md)
* [Page Toolbar Extension](Page-Toolbar-Extensions.md)
* [Dynamic Form (or Form Prop) Extensions](Dynamic-Form-Extensions.md)

8
docs/en/docs-nav.json

@ -235,6 +235,10 @@
{ {
"text": "Quartz Integration", "text": "Quartz Integration",
"path": "Background-Workers-Quartz.md" "path": "Background-Workers-Quartz.md"
},
{
"text": "Hangfire Integration",
"path": "Background-Workers-Hangfire.md"
} }
] ]
}, },
@ -1057,6 +1061,10 @@
{ {
"text": "Extensions", "text": "Extensions",
"items": [ "items": [
{
"text": "Overall",
"path": "UI/Angular/Extensions-Overall.md"
},
{ {
"text": "Entity Action Extensions", "text": "Entity Action Extensions",
"path": "UI/Angular/Entity-Action-Extensions.md" "path": "UI/Angular/Entity-Action-Extensions.md"

100
docs/zh-Hans/Background-Workers-Hangfire.md

@ -0,0 +1,100 @@
# Hangfire Background Worker Manager
[Hangfire](https://https://www.hangfire.io/)是一个高级的后台工作者管理. 你可以用ABP框架Hangfire集成代替[默认后台工作者管理](Background-Workers.md).
主要优点是你可以使用相同的服务器群来管理你的后台作业和工作线程以及利用 Hangfire 提供的[Recurring Jobs](https://docs.hangfire.io/en/latest/background-methods/performing-recurrent-tasks.html?highlight=recurring)高级调度功能.
## 安装
建议使用[ABP CLI](CLI.md)安装包.
### 使用ABP CLI
在项目的文件夹(.csproj文件)中打开命令行窗口输入以下命令:
````bash
abp add-package Volo.Abp.BackgroundWorkers.Hangfire
````
### 手动安装
如果你想手动安装;
1. 添加 [Volo.Abp.BackgroundWorkers.Hangfire](https://www.nuget.org/packages/Volo.Abp.BackgroundWorkers.Hangfire) NuGet包添加到你的项目:
````
Install-Package Volo.Abp.BackgroundWorkers.Hangfire
````
2. 添加 `AbpBackgroundWorkersHangfireModule` 到你的模块的依赖列表:
````csharp
[DependsOn(
//...other dependencies
typeof(AbpBackgroundWorkersHangfireModule) //Add the new module dependency
)]
public class YourModule : AbpModule
{
}
````
> Hangfire后台工作者集成提供了 `HangfirePeriodicBackgroundWorkerAdapter` 来适配 `PeriodicBackgroundWorkerBase` 和 `AsyncPeriodicBackgroundWorkerBase` 派生类. 所以你依然可以按照[后台工作者文档](Background-Workers.md)来定义后台作业.
## 创建后台工作者
`HangfireBackgroundWorkerBase` 是创建一个后台工作者简单的方法.
```` csharp
public class MyLogWorker : HangfireBackgroundWorkerBase
{
public MyLogWorker()
{
RecurringJobId = nameof(MyLogWorker);
CronExpression = Cron.Daily();
}
public override Task DoWorkAsync()
{
Logger.LogInformation("Executed MyLogWorker..!");
return Task.CompletedTask;
}
}
````
* **RecurringJobId** 是一个可选参数, 参阅 [Hangfire文档](https://docs.hangfire.io/en/latest/background-methods/performing-recurrent-tasks.html)
* **CronExpression** 是CRON表达式, 参阅 [CRON 表达式](https://en.wikipedia.org/wiki/Cron#CRON_expression)
> 你可以直接实现 `IHangfireBackgroundWorker`, 但是 `HangfireBackgroundWorkerBase` 提供了一些有用的属性,例如 `Logger`.
## 注册到后台工作者管理器
创建一个后台工作者后, 你应该添加到 `IBackgroundWorkerManager`, 最常用的地方是在你模块类的 `OnApplicationInitialization` 方法中:
```` csharp
[DependsOn(typeof(AbpBackgroundWorkersModule))]
public class MyModule : AbpModule
{
public override void OnApplicationInitialization(
ApplicationInitializationContext context)
{
context.AddBackgroundWorker<MyLogWorker>();
}
}
````
`context.AddBackgroundWorker(...)` 是一个是以下代码快捷的扩展方法:
```` csharp
context.ServiceProvider
.GetRequiredService<IBackgroundWorkerManager>()
.Add(
context
.ServiceProvider
.GetRequiredService<MyLogWorker>()
);
````
它解析给定的后台工作者并添加到 `IBackgroundWorkerManager`.
虽然我们通常在 `OnApplicationInitialization` 中添加后台工作者, 但对此没有限制. 你可以在任何地方注入 `IBackgroundWorkerManager` 并在运行时添加后台工作者.

8
docs/zh-Hans/Background-Workers.md

@ -128,11 +128,13 @@ context.ServiceProvider
* 使用上面提到的 `AbpBackgroundWorkerOptions` 禁用其他的后台工作者系统,只保留一个实例. * 使用上面提到的 `AbpBackgroundWorkerOptions` 禁用其他的后台工作者系统,只保留一个实例.
* 所有的应用程序都禁用后台工作者系统,创建一个特殊的应用程序在一个服务上运行执行工作者. * 所有的应用程序都禁用后台工作者系统,创建一个特殊的应用程序在一个服务上运行执行工作者.
## Quartz 集成 ## 集成
ABP框架的后台工作者系统可以很好的执行周期任务. 但是你可能需要使用更高级的任务调度,像[Quartz](https://www.quartz-scheduler.net/). 参阅社区贡献的[Quartz集成](Background-Workers-Quartz.md) 后台工作者系统是可扩展的,你可以更改默认的后台工作者管理器为你自己的实现,或者使用以下预构建的集成:
* [Quartz 后台工作者管理器](Background-Workers-Quartz.md)
* [Hangfire 后台工作者管理器](Background-Workers-Hangfire.md)
## 另请参阅 ## 另请参阅
* [后台工作者的Quartz集成](Background-Workers-Quartz.md)
* [后台作业](Background-Jobs.md) * [后台作业](Background-Jobs.md)

53
docs/zh-Hans/Distributed-Event-Bus.md

@ -299,55 +299,4 @@ namespace AbpDemo
} }
```` ````
此示例使用AutoMapper的 `AutoMap` 属性配置的映射. 你可以创建一个配置文件类代替. 请参阅AutoMapper文档了解更多选项. 此示例使用AutoMapper的 `AutoMap` 属性配置的映射. 你可以创建一个配置文件类代替. 请参阅AutoMapper文档了解更多选项.
## 异常处理
ABP提供了异常处理, 它会进行重试并且重试失败后移动到死信队列.
启用异常处理:
```csharp
public override void PreConfigureServices(ServiceConfigurationContext context)
{
PreConfigure<AbpEventBusOptions>(options =>
{
options.EnabledErrorHandle = true;
options.UseRetryStrategy();
});
}
```
* `EnabledErrorHandle` 用于启用异常处理.
* `UseRetryStrategy` 用于启用重试.
当一个异常抛出,它会每3秒重试一次直到最大重试次数(默认是3)并且移动到错误队列, 你可以更改重试次数,重试间隔和死信队列名称:
```csharp
PreConfigure<AbpEventBusOptions>(options =>
{
options.DeadLetterName = "dead_queue";
options.UseRetryStrategy(retryStrategyOptions =>
{
retryStrategyOptions.IntervalMillisecond = 0;
retryStrategyOptions.MaxRetryAttempts = 1;
});
});
```
### 错误处理选择器
默认所有的事件类型都会被处理, 你可以使用 `AbpEventBusOptions` 的 `ErrorHandleSelector` 来更改它:
```csharp
PreConfigure<AbpEventBusOptions>(options =>
{
options.ErrorHandleSelector = type => type == typeof(MyExceptionHandleEventData);
});
```
`options.ErrorHandleSelector` 实际上是一个类型类型谓词列表. 你可以编写lambda来定义你的过滤.
### 自定义异常处理
ABP定义了 `IEventErrorHandler` 接口并且由提供程序实现, 你可以通过[依赖注入](Dependency-Injection.md)替换它.

46
docs/zh-Hans/Local-Event-Bus.md

@ -158,52 +158,6 @@ namespace AbpDemo
如果您执行**数据库操作**并在事件处理程序中使用[仓储](Repositories.md),那么您可能需要创建一个[工作单元](Unit-Of-Work.md),因为一些存储库方法需要在**活动的工作单元**中工作. 确保处理方法设置为 `virtual`,并为该方法添加一个 `[UnitOfWork]` attribute. 或者手动使用 `IUnitOfWorkManager` 创建一个工作单元范围. 如果您执行**数据库操作**并在事件处理程序中使用[仓储](Repositories.md),那么您可能需要创建一个[工作单元](Unit-Of-Work.md),因为一些存储库方法需要在**活动的工作单元**中工作. 确保处理方法设置为 `virtual`,并为该方法添加一个 `[UnitOfWork]` attribute. 或者手动使用 `IUnitOfWorkManager` 创建一个工作单元范围.
## 异常处理
ABP提供了异常处理, 当异常发现时它会进行重试.
启用异常处理:
```csharp
public override void PreConfigureServices(ServiceConfigurationContext context)
{
PreConfigure<AbpEventBusOptions>(options =>
{
options.UseRetryStrategy();
});
}
```
当一个异常抛出,它会每3秒重试一次直到最大重试次数(默认是3)并且移动抛出原始异常, 你可以更改重试次数和重试间隔和:
```csharp
PreConfigure<AbpEventBusOptions>(options =>
{
options.UseRetryStrategy(retryStrategyOptions =>
{
retryStrategyOptions.IntervalMillisecond = 0;
retryStrategyOptions.MaxRetryAttempts = 1;
});
});
```
### 错误处理选择器
默认所有的事件类型都会被处理, 你可以使用 `AbpEventBusOptions` 的 `ErrorHandleSelector` 来更改它:
```csharp
PreConfigure<AbpEventBusOptions>(options =>
{
options.ErrorHandleSelector = type => type == typeof(MyExceptionHandleEventData);
});
```
`options.ErrorHandleSelector` 实际上是一个类型类型谓词列表. 你可以编写lambda来定义你的过滤.
### 自定义异常处理
ABP定义了 `IEventErrorHandler` 接口并且由 `LocalEventErrorHandler` 实现, 你可以通过[依赖注入](Dependency-Injection.md)替换它.
### 事务和异常行为 ### 事务和异常行为
当一个事件发布,订阅的事件处理程序将立即执行.所以; 当一个事件发布,订阅的事件处理程序将立即执行.所以;

4
docs/zh-Hans/docs-nav.json

@ -176,6 +176,10 @@
{ {
"text": "Quartz 集成", "text": "Quartz 集成",
"path": "Background-Workers-Quartz.md" "path": "Background-Workers-Quartz.md"
},
{
"text": "Hangfire 集成",
"path": "Background-Workers-Hangfire.md"
} }
] ]
} }

30
framework/Volo.Abp.sln

@ -372,6 +372,7 @@ EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.AzureServiceBus", "src\Volo.Abp.AzureServiceBus\Volo.Abp.AzureServiceBus.csproj", "{808EC18E-C8CC-4F5C-82B6-984EADBBF85D}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.AzureServiceBus", "src\Volo.Abp.AzureServiceBus\Volo.Abp.AzureServiceBus.csproj", "{808EC18E-C8CC-4F5C-82B6-984EADBBF85D}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.EventBus.Azure", "src\Volo.Abp.EventBus.Azure\Volo.Abp.EventBus.Azure.csproj", "{FB27F78E-F10E-4810-9B8E-BCD67DCFC8A2}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.EventBus.Azure", "src\Volo.Abp.EventBus.Azure\Volo.Abp.EventBus.Azure.csproj", "{FB27F78E-F10E-4810-9B8E-BCD67DCFC8A2}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Authorization.Abstractions", "src\Volo.Abp.Authorization.Abstractions\Volo.Abp.Authorization.Abstractions.csproj", "{87B0C2A8-FE95-4779-8B9C-2181AA52B3FA}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Authorization.Abstractions", "src\Volo.Abp.Authorization.Abstractions\Volo.Abp.Authorization.Abstractions.csproj", "{87B0C2A8-FE95-4779-8B9C-2181AA52B3FA}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.TextTemplating.Core", "src\Volo.Abp.TextTemplating.Core\Volo.Abp.TextTemplating.Core.csproj", "{184E859A-282D-44D7-B8E9-FEA874644013}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.TextTemplating.Core", "src\Volo.Abp.TextTemplating.Core\Volo.Abp.TextTemplating.Core.csproj", "{184E859A-282D-44D7-B8E9-FEA874644013}"
@ -390,13 +391,18 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.IdentityModel.Test
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Threading.Tests", "test\Volo.Abp.Threading.Tests\Volo.Abp.Threading.Tests.csproj", "{7B2FCAD6-86E6-49C8-ADBE-A61B4F4B101B}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Threading.Tests", "test\Volo.Abp.Threading.Tests\Volo.Abp.Threading.Tests.csproj", "{7B2FCAD6-86E6-49C8-ADBE-A61B4F4B101B}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.EventBus.Boxes", "src\Volo.Abp.EventBus.Boxes\Volo.Abp.EventBus.Boxes.csproj", "{6E289F31-7924-418B-9DAC-62A7CFADF916}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.DistributedLocking", "src\Volo.Abp.DistributedLocking\Volo.Abp.DistributedLocking.csproj", "{9A7EEA08-15BE-476D-8168-53039867038E}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.DistributedLocking", "src\Volo.Abp.DistributedLocking\Volo.Abp.DistributedLocking.csproj", "{9A7EEA08-15BE-476D-8168-53039867038E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Auditing.Contracts", "src\Volo.Abp.Auditing.Contracts\Volo.Abp.Auditing.Contracts.csproj", "{508B6355-AD28-4E60-8549-266D21DBF2CF}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Auditing.Contracts", "src\Volo.Abp.Auditing.Contracts\Volo.Abp.Auditing.Contracts.csproj", "{508B6355-AD28-4E60-8549-266D21DBF2CF}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Http.Client.Web", "src\Volo.Abp.Http.Client.Web\Volo.Abp.Http.Client.Web.csproj", "{F7407459-8AFA-45E4-83E9-9BB01412CC08}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Http.Client.Web", "src\Volo.Abp.Http.Client.Web\Volo.Abp.Http.Client.Web.csproj", "{F7407459-8AFA-45E4-83E9-9BB01412CC08}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.DistributedLocking.Abstractions", "src\Volo.Abp.DistributedLocking.Abstractions\Volo.Abp.DistributedLocking.Abstractions.csproj", "{CA805B77-D50C-431F-B3CB-1111C9C6E807}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.DistributedLocking.Abstractions.Tests", "test\Volo.Abp.DistributedLocking.Abstractions.Tests\Volo.Abp.DistributedLocking.Abstractions.Tests.csproj", "{C4F54FB5-C828-414D-BA03-E8E7A10C784D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.BackgroundWorkers.Hangfire", "src\Volo.Abp.BackgroundWorkers.Hangfire\Volo.Abp.BackgroundWorkers.Hangfire.csproj", "{E5FCE710-C5A3-4F94-B9C9-BD1E99252BFB}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
@ -1171,10 +1177,6 @@ Global
{7B2FCAD6-86E6-49C8-ADBE-A61B4F4B101B}.Debug|Any CPU.Build.0 = Debug|Any CPU {7B2FCAD6-86E6-49C8-ADBE-A61B4F4B101B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7B2FCAD6-86E6-49C8-ADBE-A61B4F4B101B}.Release|Any CPU.ActiveCfg = Release|Any CPU {7B2FCAD6-86E6-49C8-ADBE-A61B4F4B101B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7B2FCAD6-86E6-49C8-ADBE-A61B4F4B101B}.Release|Any CPU.Build.0 = Release|Any CPU {7B2FCAD6-86E6-49C8-ADBE-A61B4F4B101B}.Release|Any CPU.Build.0 = Release|Any CPU
{6E289F31-7924-418B-9DAC-62A7CFADF916}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6E289F31-7924-418B-9DAC-62A7CFADF916}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6E289F31-7924-418B-9DAC-62A7CFADF916}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6E289F31-7924-418B-9DAC-62A7CFADF916}.Release|Any CPU.Build.0 = Release|Any CPU
{9A7EEA08-15BE-476D-8168-53039867038E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {9A7EEA08-15BE-476D-8168-53039867038E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9A7EEA08-15BE-476D-8168-53039867038E}.Debug|Any CPU.Build.0 = Debug|Any CPU {9A7EEA08-15BE-476D-8168-53039867038E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9A7EEA08-15BE-476D-8168-53039867038E}.Release|Any CPU.ActiveCfg = Release|Any CPU {9A7EEA08-15BE-476D-8168-53039867038E}.Release|Any CPU.ActiveCfg = Release|Any CPU
@ -1187,6 +1189,18 @@ Global
{F7407459-8AFA-45E4-83E9-9BB01412CC08}.Debug|Any CPU.Build.0 = Debug|Any CPU {F7407459-8AFA-45E4-83E9-9BB01412CC08}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F7407459-8AFA-45E4-83E9-9BB01412CC08}.Release|Any CPU.ActiveCfg = Release|Any CPU {F7407459-8AFA-45E4-83E9-9BB01412CC08}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F7407459-8AFA-45E4-83E9-9BB01412CC08}.Release|Any CPU.Build.0 = Release|Any CPU {F7407459-8AFA-45E4-83E9-9BB01412CC08}.Release|Any CPU.Build.0 = Release|Any CPU
{CA805B77-D50C-431F-B3CB-1111C9C6E807}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CA805B77-D50C-431F-B3CB-1111C9C6E807}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CA805B77-D50C-431F-B3CB-1111C9C6E807}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CA805B77-D50C-431F-B3CB-1111C9C6E807}.Release|Any CPU.Build.0 = Release|Any CPU
{C4F54FB5-C828-414D-BA03-E8E7A10C784D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C4F54FB5-C828-414D-BA03-E8E7A10C784D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C4F54FB5-C828-414D-BA03-E8E7A10C784D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C4F54FB5-C828-414D-BA03-E8E7A10C784D}.Release|Any CPU.Build.0 = Release|Any CPU
{E5FCE710-C5A3-4F94-B9C9-BD1E99252BFB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E5FCE710-C5A3-4F94-B9C9-BD1E99252BFB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E5FCE710-C5A3-4F94-B9C9-BD1E99252BFB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E5FCE710-C5A3-4F94-B9C9-BD1E99252BFB}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
@ -1384,10 +1398,12 @@ Global
{90B1866A-EF99-40B9-970E-B898E5AA523F} = {447C8A77-E5F0-4538-8687-7383196D04EA} {90B1866A-EF99-40B9-970E-B898E5AA523F} = {447C8A77-E5F0-4538-8687-7383196D04EA}
{40C6740E-BFCA-4D37-8344-3D84E2044BB2} = {447C8A77-E5F0-4538-8687-7383196D04EA} {40C6740E-BFCA-4D37-8344-3D84E2044BB2} = {447C8A77-E5F0-4538-8687-7383196D04EA}
{7B2FCAD6-86E6-49C8-ADBE-A61B4F4B101B} = {447C8A77-E5F0-4538-8687-7383196D04EA} {7B2FCAD6-86E6-49C8-ADBE-A61B4F4B101B} = {447C8A77-E5F0-4538-8687-7383196D04EA}
{6E289F31-7924-418B-9DAC-62A7CFADF916} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
{9A7EEA08-15BE-476D-8168-53039867038E} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6} {9A7EEA08-15BE-476D-8168-53039867038E} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
{508B6355-AD28-4E60-8549-266D21DBF2CF} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6} {508B6355-AD28-4E60-8549-266D21DBF2CF} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
{F7407459-8AFA-45E4-83E9-9BB01412CC08} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6} {F7407459-8AFA-45E4-83E9-9BB01412CC08} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
{CA805B77-D50C-431F-B3CB-1111C9C6E807} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
{C4F54FB5-C828-414D-BA03-E8E7A10C784D} = {447C8A77-E5F0-4538-8687-7383196D04EA}
{E5FCE710-C5A3-4F94-B9C9-BD1E99252BFB} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
EndGlobalSection EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {BB97ECF4-9A84-433F-A80B-2A3285BDD1D5} SolutionGuid = {BB97ECF4-9A84-433F-A80B-2A3285BDD1D5}

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

@ -17,7 +17,7 @@
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Volo.Abp.BackgroundJobs.Abstractions\Volo.Abp.BackgroundJobs.Abstractions.csproj" /> <ProjectReference Include="..\Volo.Abp.BackgroundJobs.Abstractions\Volo.Abp.BackgroundJobs.Abstractions.csproj" />
<ProjectReference Include="..\Volo.Abp.BackgroundWorkers\Volo.Abp.BackgroundWorkers.csproj" /> <ProjectReference Include="..\Volo.Abp.BackgroundWorkers\Volo.Abp.BackgroundWorkers.csproj" />
<ProjectReference Include="..\Volo.Abp.Core\Volo.Abp.Core.csproj" /> <ProjectReference Include="..\Volo.Abp.DistributedLocking.Abstractions\Volo.Abp.DistributedLocking.Abstractions.csproj" />
<ProjectReference Include="..\Volo.Abp.Guids\Volo.Abp.Guids.csproj" /> <ProjectReference Include="..\Volo.Abp.Guids\Volo.Abp.Guids.csproj" />
<ProjectReference Include="..\Volo.Abp.Timing\Volo.Abp.Timing.csproj" /> <ProjectReference Include="..\Volo.Abp.Timing\Volo.Abp.Timing.csproj" />
</ItemGroup> </ItemGroup>

4
framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/AbpBackgroundJobsModule.cs

@ -1,6 +1,7 @@
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Volo.Abp.BackgroundWorkers; using Volo.Abp.BackgroundWorkers;
using Volo.Abp.DistributedLocking;
using Volo.Abp.Guids; using Volo.Abp.Guids;
using Volo.Abp.Modularity; using Volo.Abp.Modularity;
using Volo.Abp.Timing; using Volo.Abp.Timing;
@ -11,7 +12,8 @@ namespace Volo.Abp.BackgroundJobs
typeof(AbpBackgroundJobsAbstractionsModule), typeof(AbpBackgroundJobsAbstractionsModule),
typeof(AbpBackgroundWorkersModule), typeof(AbpBackgroundWorkersModule),
typeof(AbpTimingModule), typeof(AbpTimingModule),
typeof(AbpGuidsModule) typeof(AbpGuidsModule),
typeof(AbpDistributedLockingAbstractionsModule)
)] )]
public class AbpBackgroundJobsModule : AbpModule public class AbpBackgroundJobsModule : AbpModule
{ {

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

@ -5,6 +5,7 @@ using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Volo.Abp.BackgroundWorkers; using Volo.Abp.BackgroundWorkers;
using Volo.Abp.DistributedLocking;
using Volo.Abp.Threading; using Volo.Abp.Threading;
using Volo.Abp.Timing; using Volo.Abp.Timing;
@ -12,19 +13,25 @@ namespace Volo.Abp.BackgroundJobs
{ {
public class BackgroundJobWorker : AsyncPeriodicBackgroundWorkerBase, IBackgroundJobWorker public class BackgroundJobWorker : AsyncPeriodicBackgroundWorkerBase, IBackgroundJobWorker
{ {
protected const string DistributedLockName = "AbpBackgroundJobWorker";
protected AbpBackgroundJobOptions JobOptions { get; } protected AbpBackgroundJobOptions JobOptions { get; }
protected AbpBackgroundJobWorkerOptions WorkerOptions { get; } protected AbpBackgroundJobWorkerOptions WorkerOptions { get; }
protected IAbpDistributedLock DistributedLock { get; }
public BackgroundJobWorker( public BackgroundJobWorker(
AbpAsyncTimer timer, AbpAsyncTimer timer,
IOptions<AbpBackgroundJobOptions> jobOptions, IOptions<AbpBackgroundJobOptions> jobOptions,
IOptions<AbpBackgroundJobWorkerOptions> workerOptions, IOptions<AbpBackgroundJobWorkerOptions> workerOptions,
IServiceScopeFactory serviceScopeFactory) IServiceScopeFactory serviceScopeFactory,
IAbpDistributedLock distributedLock)
: base( : base(
timer, timer,
serviceScopeFactory) serviceScopeFactory)
{ {
DistributedLock = distributedLock;
WorkerOptions = workerOptions.Value; WorkerOptions = workerOptions.Value;
JobOptions = jobOptions.Value; JobOptions = jobOptions.Value;
Timer.Period = WorkerOptions.JobPollPeriod; Timer.Period = WorkerOptions.JobPollPeriod;
@ -32,57 +39,74 @@ namespace Volo.Abp.BackgroundJobs
protected override async Task DoWorkAsync(PeriodicBackgroundWorkerContext workerContext) protected override async Task DoWorkAsync(PeriodicBackgroundWorkerContext workerContext)
{ {
var store = workerContext.ServiceProvider.GetRequiredService<IBackgroundJobStore>(); await using (var handler = await DistributedLock.TryAcquireAsync(DistributedLockName, cancellationToken: StoppingToken))
var waitingJobs = await store.GetWaitingJobsAsync(WorkerOptions.MaxJobFetchCount);
if (!waitingJobs.Any())
{ {
return; if (handler != null)
}
var jobExecuter = workerContext.ServiceProvider.GetRequiredService<IBackgroundJobExecuter>();
var clock = workerContext.ServiceProvider.GetRequiredService<IClock>();
var serializer = workerContext.ServiceProvider.GetRequiredService<IBackgroundJobSerializer>();
foreach (var jobInfo in waitingJobs)
{
jobInfo.TryCount++;
jobInfo.LastTryTime = clock.Now;
try
{ {
var jobConfiguration = JobOptions.GetJob(jobInfo.JobName); var store = workerContext.ServiceProvider.GetRequiredService<IBackgroundJobStore>();
var jobArgs = serializer.Deserialize(jobInfo.JobArgs, jobConfiguration.ArgsType);
var context = new JobExecutionContext(workerContext.ServiceProvider, jobConfiguration.JobType, jobArgs);
try var waitingJobs = await store.GetWaitingJobsAsync(WorkerOptions.MaxJobFetchCount);
{
await jobExecuter.ExecuteAsync(context);
await store.DeleteAsync(jobInfo.Id); if (!waitingJobs.Any())
{
return;
} }
catch (BackgroundJobExecutionException)
var jobExecuter = workerContext.ServiceProvider.GetRequiredService<IBackgroundJobExecuter>();
var clock = workerContext.ServiceProvider.GetRequiredService<IClock>();
var serializer = workerContext.ServiceProvider.GetRequiredService<IBackgroundJobSerializer>();
foreach (var jobInfo in waitingJobs)
{ {
var nextTryTime = CalculateNextTryTime(jobInfo, clock); jobInfo.TryCount++;
jobInfo.LastTryTime = clock.Now;
if (nextTryTime.HasValue) try
{ {
jobInfo.NextTryTime = nextTryTime.Value; var jobConfiguration = JobOptions.GetJob(jobInfo.JobName);
var jobArgs = serializer.Deserialize(jobInfo.JobArgs, jobConfiguration.ArgsType);
var context = new JobExecutionContext(
workerContext.ServiceProvider,
jobConfiguration.JobType,
jobArgs);
try
{
await jobExecuter.ExecuteAsync(context);
await store.DeleteAsync(jobInfo.Id);
}
catch (BackgroundJobExecutionException)
{
var nextTryTime = CalculateNextTryTime(jobInfo, clock);
if (nextTryTime.HasValue)
{
jobInfo.NextTryTime = nextTryTime.Value;
}
else
{
jobInfo.IsAbandoned = true;
}
await TryUpdateAsync(store, jobInfo);
}
} }
else catch (Exception ex)
{ {
Logger.LogException(ex);
jobInfo.IsAbandoned = true; jobInfo.IsAbandoned = true;
await TryUpdateAsync(store, jobInfo);
} }
await TryUpdateAsync(store, jobInfo);
} }
} }
catch (Exception ex) else
{ {
Logger.LogException(ex); try
jobInfo.IsAbandoned = true; {
await TryUpdateAsync(store, jobInfo); await Task.Delay(WorkerOptions.JobPollPeriod * 12, StoppingToken);
}
catch (TaskCanceledException) { }
} }
} }
} }
@ -101,7 +125,8 @@ namespace Volo.Abp.BackgroundJobs
protected virtual DateTime? CalculateNextTryTime(BackgroundJobInfo jobInfo, IClock clock) protected virtual DateTime? CalculateNextTryTime(BackgroundJobInfo jobInfo, IClock clock)
{ {
var nextWaitDuration = WorkerOptions.DefaultFirstWaitDuration * (Math.Pow(WorkerOptions.DefaultWaitFactor, jobInfo.TryCount - 1)); var nextWaitDuration = WorkerOptions.DefaultFirstWaitDuration *
(Math.Pow(WorkerOptions.DefaultWaitFactor, jobInfo.TryCount - 1));
var nextTryDate = jobInfo.LastTryTime?.AddSeconds(nextWaitDuration) ?? var nextTryDate = jobInfo.LastTryTime?.AddSeconds(nextWaitDuration) ??
clock.Now.AddSeconds(nextWaitDuration); clock.Now.AddSeconds(nextWaitDuration);
@ -113,4 +138,4 @@ namespace Volo.Abp.BackgroundJobs
return nextTryDate; return nextTryDate;
} }
} }
} }

3
framework/src/Volo.Abp.BackgroundWorkers.Hangfire/FodyWeavers.xml

@ -0,0 +1,3 @@
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<ConfigureAwait ContinueOnCapturedContext="false" />
</Weavers>

2
framework/src/Volo.Abp.EventBus.Boxes/FodyWeavers.xsd → framework/src/Volo.Abp.BackgroundWorkers.Hangfire/FodyWeavers.xsd

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. --> <!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. -->
<xs:element name="Weavers"> <xs:element name="Weavers">

7
framework/src/Volo.Abp.EventBus.Boxes/Volo.Abp.EventBus.Boxes.csproj → framework/src/Volo.Abp.BackgroundWorkers.Hangfire/Volo.Abp.BackgroundWorkers.Hangfire.csproj

@ -5,8 +5,8 @@
<PropertyGroup> <PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework> <TargetFramework>netstandard2.0</TargetFramework>
<AssemblyName>Volo.Abp.EventBus.Boxes</AssemblyName> <AssemblyName>Volo.Abp.BackgroundWorkers.Hangfire</AssemblyName>
<PackageId>Volo.Abp.EventBus.Boxes</PackageId> <PackageId>Volo.Abp.BackgroundWorkers.Hangfire</PackageId>
<AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback> <AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback>
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute> <GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute> <GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
@ -16,8 +16,7 @@
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Volo.Abp.BackgroundWorkers\Volo.Abp.BackgroundWorkers.csproj" /> <ProjectReference Include="..\Volo.Abp.BackgroundWorkers\Volo.Abp.BackgroundWorkers.csproj" />
<ProjectReference Include="..\Volo.Abp.DistributedLocking\Volo.Abp.DistributedLocking.csproj" /> <ProjectReference Include="..\Volo.Abp.Hangfire\Volo.Abp.Hangfire.csproj" />
<ProjectReference Include="..\Volo.Abp.EventBus\Volo.Abp.EventBus.csproj" />
</ItemGroup> </ItemGroup>
</Project> </Project>

36
framework/src/Volo.Abp.BackgroundWorkers.Hangfire/Volo/Abp/BackgroundWorkers/Hangfire/AbpBackgroundWorkersHangfireModule.cs

@ -0,0 +1,36 @@
using System;
using Hangfire;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Volo.Abp.Hangfire;
using Volo.Abp.Modularity;
namespace Volo.Abp.BackgroundWorkers.Hangfire
{
[DependsOn(
typeof(AbpBackgroundWorkersModule),
typeof(AbpHangfireModule))]
public class AbpBackgroundWorkerHangfireModule : AbpModule
{
public override void OnPreApplicationInitialization(ApplicationInitializationContext context)
{
var options = context.ServiceProvider.GetRequiredService<IOptions<AbpBackgroundWorkerOptions>>().Value;
if (!options.IsEnabled)
{
var hangfireOptions = context.ServiceProvider.GetRequiredService<IOptions<AbpHangfireOptions>>().Value;
hangfireOptions.BackgroundJobServerFactory = CreateOnlyEnqueueJobServer;
}
}
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.AddSingleton(typeof(HangfirePeriodicBackgroundWorkerAdapter<>));
}
private BackgroundJobServer CreateOnlyEnqueueJobServer(IServiceProvider serviceProvider)
{
serviceProvider.GetRequiredService<JobStorage>();
return null;
}
}
}

13
framework/src/Volo.Abp.BackgroundWorkers.Hangfire/Volo/Abp/BackgroundWorkers/Hangfire/HangfireBackgroundWorkerBase.cs

@ -0,0 +1,13 @@
using System.Threading.Tasks;
namespace Volo.Abp.BackgroundWorkers.Hangfire
{
public abstract class HangfireBackgroundWorkerBase : BackgroundWorkerBase, IHangfireBackgroundWorker
{
public string RecurringJobId { get; set; }
public string CronExpression { get; set; }
public abstract Task DoWorkAsync();
}
}

91
framework/src/Volo.Abp.BackgroundWorkers.Hangfire/Volo/Abp/BackgroundWorkers/Hangfire/HangfireBackgroundWorkerManager.cs

@ -0,0 +1,91 @@
using System;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using Hangfire;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Threading;
namespace Volo.Abp.BackgroundWorkers.Hangfire
{
[Dependency(ReplaceServices = true)]
public class HangfireBackgroundWorkerManager : IBackgroundWorkerManager, ISingletonDependency
{
public Task StartAsync(CancellationToken cancellationToken = default)
{
return Task.CompletedTask;
}
public Task StopAsync(CancellationToken cancellationToken = default)
{
return Task.CompletedTask;
}
public void Add(IBackgroundWorker worker)
{
if (worker is IHangfireBackgroundWorker hangfireBackgroundWorker)
{
if (hangfireBackgroundWorker.RecurringJobId.IsNullOrWhiteSpace())
{
RecurringJob.AddOrUpdate(() => hangfireBackgroundWorker.DoWorkAsync(),
hangfireBackgroundWorker.CronExpression);
}
else
{
RecurringJob.AddOrUpdate(hangfireBackgroundWorker.RecurringJobId,() => hangfireBackgroundWorker.DoWorkAsync(),
hangfireBackgroundWorker.CronExpression);
}
}
else
{
int? period;
if (worker is AsyncPeriodicBackgroundWorkerBase or PeriodicBackgroundWorkerBase)
{
var timer = (AbpTimer) worker.GetType()
.GetProperty("Timer", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(worker);
period = timer?.Period;
}
else
{
return;
}
if (period == null)
{
return;
}
var adapterType = typeof(HangfirePeriodicBackgroundWorkerAdapter<>).MakeGenericType(worker.GetType());
var workerAdapter = Activator.CreateInstance(adapterType) as IHangfireBackgroundWorker;
RecurringJob.AddOrUpdate(() => workerAdapter.DoWorkAsync(), GetCron(period.Value));
}
}
protected virtual string GetCron(int period)
{
var time = TimeSpan.FromMilliseconds(period);
string cron;
if (time.TotalSeconds <= 59)
{
cron = $"*/{time.TotalSeconds} * * * * *";
}
else if (time.TotalMinutes <= 59)
{
cron = $"*/{time.TotalMinutes} * * * *";
}
else if (time.TotalHours <= 23)
{
cron = $"0 */{time.TotalHours} * * *";
}
else
{
cron = $"0 0 */{time.TotalDays} * *";
}
return cron;
}
}
}

36
framework/src/Volo.Abp.BackgroundWorkers.Hangfire/Volo/Abp/BackgroundWorkers/Hangfire/HangfirePeriodicBackgroundWorkerAdapter.cs

@ -0,0 +1,36 @@
using System.Reflection;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
namespace Volo.Abp.BackgroundWorkers.Hangfire
{
public class HangfirePeriodicBackgroundWorkerAdapter<TWorker> : HangfireBackgroundWorkerBase
where TWorker : IBackgroundWorker
{
private readonly MethodInfo _doWorkAsyncMethod;
private readonly MethodInfo _doWorkMethod;
public HangfirePeriodicBackgroundWorkerAdapter()
{
_doWorkAsyncMethod =
typeof(TWorker).GetMethod("DoWorkAsync", BindingFlags.Instance | BindingFlags.NonPublic);
_doWorkMethod = typeof(TWorker).GetMethod("DoWork", BindingFlags.Instance | BindingFlags.NonPublic);
}
public override async Task DoWorkAsync()
{
var workerContext = new PeriodicBackgroundWorkerContext(ServiceProvider);
var worker = ServiceProvider.GetRequiredService<TWorker>();
switch (worker)
{
case AsyncPeriodicBackgroundWorkerBase asyncPeriodicBackgroundWorker:
await (Task) _doWorkAsyncMethod.Invoke(asyncPeriodicBackgroundWorker, new object[] {workerContext});
break;
case PeriodicBackgroundWorkerBase periodicBackgroundWorker:
_doWorkMethod.Invoke(periodicBackgroundWorker, new object[] {workerContext});
break;
}
}
}
}

15
framework/src/Volo.Abp.BackgroundWorkers.Hangfire/Volo/Abp/BackgroundWorkers/Hangfire/IHangfireBackgroundWorker.cs

@ -0,0 +1,15 @@
using System.Threading.Tasks;
namespace Volo.Abp.BackgroundWorkers.Hangfire
{
public interface IHangfireBackgroundWorker : IBackgroundWorker
{
string RecurringJobId { get; set; }
string CronExpression { get; set; }
Task DoWorkAsync();
}
}

11
framework/src/Volo.Abp.BackgroundWorkers/Volo/Abp/BackgroundWorkers/BackgroundWorkerBase.cs

@ -21,6 +21,15 @@ namespace Volo.Abp.BackgroundWorkers
protected ILoggerFactory LoggerFactory => LazyServiceProvider.LazyGetRequiredService<ILoggerFactory>(); protected ILoggerFactory LoggerFactory => LazyServiceProvider.LazyGetRequiredService<ILoggerFactory>();
protected ILogger Logger => LazyServiceProvider.LazyGetService<ILogger>(provider => LoggerFactory?.CreateLogger(GetType().FullName) ?? NullLogger.Instance); protected ILogger Logger => LazyServiceProvider.LazyGetService<ILogger>(provider => LoggerFactory?.CreateLogger(GetType().FullName) ?? NullLogger.Instance);
protected CancellationTokenSource StoppingTokenSource { get; }
protected CancellationToken StoppingToken { get; }
public BackgroundWorkerBase()
{
StoppingTokenSource = new CancellationTokenSource();
StoppingToken = StoppingTokenSource.Token;
}
public virtual Task StartAsync(CancellationToken cancellationToken = default) public virtual Task StartAsync(CancellationToken cancellationToken = default)
{ {
@ -31,6 +40,8 @@ namespace Volo.Abp.BackgroundWorkers
public virtual Task StopAsync(CancellationToken cancellationToken = default) public virtual Task StopAsync(CancellationToken cancellationToken = default)
{ {
Logger.LogDebug("Stopped background worker: " + ToString()); Logger.LogDebug("Stopped background worker: " + ToString());
StoppingTokenSource.Cancel();
StoppingTokenSource.Dispose();
return Task.CompletedTask; return Task.CompletedTask;
} }

2
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Auth/LoginInfo.cs

@ -12,5 +12,7 @@ namespace Volo.Abp.Cli.Auth
public string EmailAddress { get; set; } public string EmailAddress { get; set; }
public string Organization { get; set; } public string Organization { get; set; }
public bool HasSourceCodeAccess { get; set; }
} }
} }

9
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Bundling/BundlerBase.cs

@ -41,7 +41,7 @@ namespace Volo.Abp.Cli.Bundling
return GenerateDefinition(bundleFilePath,fileDefinitionsExcludingFromBundle); return GenerateDefinition(bundleFilePath,fileDefinitionsExcludingFromBundle);
} }
private bool IsMinFile(string fileName) private bool IsMinFile(string fileName, string content)
{ {
foreach (var suffix in _minFileSuffixes) foreach (var suffix in _minFileSuffixes)
{ {
@ -51,6 +51,11 @@ namespace Volo.Abp.Cli.Bundling
} }
} }
if (content.SplitToLines().Length < 10)
{
return true;
}
return false; return false;
} }
@ -117,7 +122,7 @@ namespace Volo.Abp.Cli.Bundling
private string GetFileContent(string filePath, bool minify) private string GetFileContent(string filePath, bool minify)
{ {
var content = File.ReadAllText(filePath); var content = File.ReadAllText(filePath);
if (minify && !IsMinFile(filePath)) if (minify && !IsMinFile(filePath, content))
{ {
try try
{ {

2
framework/src/Volo.Abp.Ddd.Domain/Volo.Abp.Ddd.Domain.csproj

@ -17,7 +17,7 @@
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Volo.Abp.Auditing\Volo.Abp.Auditing.csproj" /> <ProjectReference Include="..\Volo.Abp.Auditing\Volo.Abp.Auditing.csproj" />
<ProjectReference Include="..\Volo.Abp.Data\Volo.Abp.Data.csproj" /> <ProjectReference Include="..\Volo.Abp.Data\Volo.Abp.Data.csproj" />
<ProjectReference Include="..\Volo.Abp.EventBus.Boxes\Volo.Abp.EventBus.Boxes.csproj" /> <ProjectReference Include="..\Volo.Abp.EventBus\Volo.Abp.EventBus.csproj" />
<ProjectReference Include="..\Volo.Abp.ExceptionHandling\Volo.Abp.ExceptionHandling.csproj" /> <ProjectReference Include="..\Volo.Abp.ExceptionHandling\Volo.Abp.ExceptionHandling.csproj" />
<ProjectReference Include="..\Volo.Abp.Guids\Volo.Abp.Guids.csproj" /> <ProjectReference Include="..\Volo.Abp.Guids\Volo.Abp.Guids.csproj" />
<ProjectReference Include="..\Volo.Abp.MultiTenancy\Volo.Abp.MultiTenancy.csproj" /> <ProjectReference Include="..\Volo.Abp.MultiTenancy\Volo.Abp.MultiTenancy.csproj" />

2
framework/src/Volo.Abp.Ddd.Domain/Volo.Abp.Ddd.Domain.csproj.DotSettings

@ -1,2 +0,0 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/CodeInspection/CSharpLanguageProject/LanguageLevel/@EntryValue">CSharp71</s:String></wpf:ResourceDictionary>

3
framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/AbpDddDomainModule.cs

@ -3,7 +3,6 @@ using Volo.Abp.Auditing;
using Volo.Abp.Data; using Volo.Abp.Data;
using Volo.Abp.Domain.Repositories; using Volo.Abp.Domain.Repositories;
using Volo.Abp.EventBus; using Volo.Abp.EventBus;
using Volo.Abp.EventBus.Boxes;
using Volo.Abp.ExceptionHandling; using Volo.Abp.ExceptionHandling;
using Volo.Abp.Guids; using Volo.Abp.Guids;
using Volo.Abp.Modularity; using Volo.Abp.Modularity;
@ -19,7 +18,7 @@ namespace Volo.Abp.Domain
[DependsOn( [DependsOn(
typeof(AbpAuditingModule), typeof(AbpAuditingModule),
typeof(AbpDataModule), typeof(AbpDataModule),
typeof(AbpEventBusBoxesModule), typeof(AbpEventBusModule),
typeof(AbpGuidsModule), typeof(AbpGuidsModule),
typeof(AbpMultiTenancyModule), typeof(AbpMultiTenancyModule),
typeof(AbpThreadingModule), typeof(AbpThreadingModule),

3
framework/src/Volo.Abp.DistributedLocking.Abstractions/FodyWeavers.xml

@ -0,0 +1,3 @@
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<ConfigureAwait ContinueOnCapturedContext="false" />
</Weavers>

30
framework/src/Volo.Abp.DistributedLocking.Abstractions/FodyWeavers.xsd

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. -->
<xs:element name="Weavers">
<xs:complexType>
<xs:all>
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" />
</xs:complexType>
</xs:element>
</xs:all>
<xs:attribute name="VerifyAssembly" type="xs:boolean">
<xs:annotation>
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="VerifyIgnoreCodes" type="xs:string">
<xs:annotation>
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="GenerateXsd" type="xs:boolean">
<xs:annotation>
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
</xs:element>
</xs:schema>

21
framework/src/Volo.Abp.DistributedLocking.Abstractions/Volo.Abp.DistributedLocking.Abstractions.csproj

@ -0,0 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\configureawait.props" />
<Import Project="..\..\..\common.props" />
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<AssemblyName>Volo.Abp.DistributedLocking.Abstractions</AssemblyName>
<PackageId>Volo.Abp.DistributedLocking.Abstractions</PackageId>
<AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback>
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
<RootNamespace />
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Volo.Abp.Core\Volo.Abp.Core.csproj" />
</ItemGroup>
</Project>

9
framework/src/Volo.Abp.DistributedLocking.Abstractions/Volo/Abp/DistributedLocking/AbpDistributedLockingAbstractionsModule.cs

@ -0,0 +1,9 @@
using Volo.Abp.Modularity;
namespace Volo.Abp.DistributedLocking
{
public class AbpDistributedLockingAbstractionsModule : AbpModule
{
}
}

26
framework/src/Volo.Abp.DistributedLocking.Abstractions/Volo/Abp/DistributedLocking/IAbpDistributedLock.cs

@ -0,0 +1,26 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using JetBrains.Annotations;
namespace Volo.Abp.DistributedLocking
{
public interface IAbpDistributedLock
{
/// <summary>
/// Tries to acquire a named lock.
/// Returns a disposable object to release the lock.
/// It is suggested to use this method within a using block.
/// Returns null if the lock could not be handled.
/// </summary>
/// <param name="name">The name of the lock</param>
/// <param name="timeout">Timeout value</param>
/// <param name="cancellationToken">Cancellation token</param>
[ItemCanBeNull]
Task<IAbpDistributedLockHandle> TryAcquireAsync(
[NotNull] string name,
TimeSpan timeout = default,
CancellationToken cancellationToken = default
);
}
}

9
framework/src/Volo.Abp.DistributedLocking.Abstractions/Volo/Abp/DistributedLocking/IAbpDistributedLockHandle.cs

@ -0,0 +1,9 @@
using System;
namespace Volo.Abp.DistributedLocking
{
public interface IAbpDistributedLockHandle : IAsyncDisposable
{
}
}

30
framework/src/Volo.Abp.DistributedLocking.Abstractions/Volo/Abp/DistributedLocking/LocalAbpDistributedLock.cs

@ -0,0 +1,30 @@
using System;
using System.Collections.Concurrent;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.DistributedLocking
{
public class LocalAbpDistributedLock : IAbpDistributedLock, ISingletonDependency
{
private readonly ConcurrentDictionary<string, SemaphoreSlim> _localSyncObjects = new();
public async Task<IAbpDistributedLockHandle> TryAcquireAsync(
string name,
TimeSpan timeout = default,
CancellationToken cancellationToken = default)
{
Check.NotNullOrWhiteSpace(name, nameof(name));
var semaphore = _localSyncObjects.GetOrAdd(name, _ => new SemaphoreSlim(1, 1));
if (!await semaphore.WaitAsync(timeout, cancellationToken))
{
return null;
}
return new LocalAbpDistributedLockHandle(semaphore);
}
}
}

21
framework/src/Volo.Abp.DistributedLocking.Abstractions/Volo/Abp/DistributedLocking/LocalAbpDistributedLockHandle.cs

@ -0,0 +1,21 @@
using System.Threading;
using System.Threading.Tasks;
namespace Volo.Abp.DistributedLocking
{
public class LocalAbpDistributedLockHandle : IAbpDistributedLockHandle
{
private readonly SemaphoreSlim _semaphore;
public LocalAbpDistributedLockHandle(SemaphoreSlim semaphore)
{
_semaphore = semaphore;
}
public ValueTask DisposeAsync()
{
_semaphore.Release();
return default;
}
}
}

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

@ -15,7 +15,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Volo.Abp.Core\Volo.Abp.Core.csproj" /> <ProjectReference Include="..\Volo.Abp.DistributedLocking.Abstractions\Volo.Abp.DistributedLocking.Abstractions.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

14
framework/src/Volo.Abp.DistributedLocking/Volo/Abp/DistributedLocking/AbpDistributedLockHandleExtensions.cs

@ -0,0 +1,14 @@
using System;
using Medallion.Threading;
namespace Volo.Abp.DistributedLocking
{
public static class AbpDistributedLockHandleExtensions
{
public static IDistributedSynchronizationHandle ToDistributedSynchronizationHandle(
this IAbpDistributedLockHandle handle)
{
return handle.As<MedallionAbpDistributedLockHandle>().Handle;
}
}
}

3
framework/src/Volo.Abp.DistributedLocking/Volo/Abp/DistributedLocking/AbpDistributedLockingModule.cs

@ -2,6 +2,9 @@
namespace Volo.Abp.DistributedLocking namespace Volo.Abp.DistributedLocking
{ {
[DependsOn(
typeof(AbpDistributedLockingAbstractionsModule)
)]
public class AbpDistributedLockingModule : AbpModule public class AbpDistributedLockingModule : AbpModule
{ {

35
framework/src/Volo.Abp.DistributedLocking/Volo/Abp/DistributedLocking/MedallionAbpDistributedLock.cs

@ -0,0 +1,35 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using Medallion.Threading;
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.DistributedLocking
{
[Dependency(ReplaceServices = true)]
public class MedallionAbpDistributedLock : IAbpDistributedLock, ITransientDependency
{
protected IDistributedLockProvider DistributedLockProvider { get; }
public MedallionAbpDistributedLock(IDistributedLockProvider distributedLockProvider)
{
DistributedLockProvider = distributedLockProvider;
}
public async Task<IAbpDistributedLockHandle> TryAcquireAsync(
string name,
TimeSpan timeout = default,
CancellationToken cancellationToken = default)
{
Check.NotNullOrWhiteSpace(name, nameof(name));
var handle = await DistributedLockProvider.TryAcquireLockAsync(name, timeout, cancellationToken);
if (handle == null)
{
return null;
}
return new MedallionAbpDistributedLockHandle(handle);
}
}
}

20
framework/src/Volo.Abp.DistributedLocking/Volo/Abp/DistributedLocking/MedallionAbpDistributedLockHandle.cs

@ -0,0 +1,20 @@
using System.Threading.Tasks;
using Medallion.Threading;
namespace Volo.Abp.DistributedLocking
{
public class MedallionAbpDistributedLockHandle : IAbpDistributedLockHandle
{
public IDistributedSynchronizationHandle Handle { get; }
public MedallionAbpDistributedLockHandle(IDistributedSynchronizationHandle handle)
{
Handle = handle;
}
public ValueTask DisposeAsync()
{
return Handle.DisposeAsync();
}
}
}

9
framework/src/Volo.Abp.EntityFrameworkCore.PostgreSql/Volo/Abp/EntityFrameworkCore/PostgreSql/AbpEntityFrameworkCorePostgreSqlModule.cs

@ -1,4 +1,5 @@
using Microsoft.Extensions.DependencyInjection; using System;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.EntityFrameworkCore.DistributedEvents; using Volo.Abp.EntityFrameworkCore.DistributedEvents;
using Volo.Abp.Guids; using Volo.Abp.Guids;
using Volo.Abp.Modularity; using Volo.Abp.Modularity;
@ -10,6 +11,12 @@ namespace Volo.Abp.EntityFrameworkCore.PostgreSql
)] )]
public class AbpEntityFrameworkCorePostgreSqlModule : AbpModule public class AbpEntityFrameworkCorePostgreSqlModule : AbpModule
{ {
public override void PreConfigureServices(ServiceConfigurationContext context)
{
// https://www.npgsql.org/efcore/release-notes/6.0.html#opting-out-of-the-new-timestamp-mapping-logic
AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true);
}
public override void ConfigureServices(ServiceConfigurationContext context) public override void ConfigureServices(ServiceConfigurationContext context)
{ {
Configure<AbpSequentialGuidGeneratorOptions>(options => Configure<AbpSequentialGuidGeneratorOptions>(options =>

3
framework/src/Volo.Abp.EventBus.Boxes/FodyWeavers.xml

@ -1,3 +0,0 @@
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<ConfigureAwait ContinueOnCapturedContext="false" />
</Weavers>

20
framework/src/Volo.Abp.EventBus.Boxes/Volo/Abp/EventBus/Boxes/AbpEventBusBoxesModule.cs

@ -1,20 +0,0 @@
using Volo.Abp.BackgroundWorkers;
using Volo.Abp.DistributedLocking;
using Volo.Abp.Modularity;
namespace Volo.Abp.EventBus.Boxes
{
[DependsOn(
typeof(AbpEventBusModule),
typeof(AbpBackgroundWorkersModule),
typeof(AbpDistributedLockingModule)
)]
public class AbpEventBusBoxesModule : AbpModule
{
public override void OnApplicationInitialization(ApplicationInitializationContext context)
{
context.AddBackgroundWorker<OutboxSenderManager>();
context.AddBackgroundWorker<InboxProcessManager>();
}
}
}

20
framework/src/Volo.Abp.EventBus.Boxes/Volo/Abp/EventBus/Boxes/TaskHelper.cs

@ -1,20 +0,0 @@
using System.Threading;
using System.Threading.Tasks;
namespace Volo.Abp.EventBus.Boxes
{
internal static class TaskDelayHelper
{
public static async Task DelayAsync(int milliseconds, CancellationToken cancellationToken = default)
{
try
{
await Task.Delay(milliseconds, cancellationToken);
}
catch (TaskCanceledException)
{
return;
}
}
}
}

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

@ -15,6 +15,8 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Volo.Abp.BackgroundWorkers\Volo.Abp.BackgroundWorkers.csproj" />
<ProjectReference Include="..\Volo.Abp.DistributedLocking.Abstractions\Volo.Abp.DistributedLocking.Abstractions.csproj" />
<ProjectReference Include="..\Volo.Abp.EventBus.Abstractions\Volo.Abp.EventBus.Abstractions.csproj" /> <ProjectReference Include="..\Volo.Abp.EventBus.Abstractions\Volo.Abp.EventBus.Abstractions.csproj" />
<ProjectReference Include="..\Volo.Abp.Guids\Volo.Abp.Guids.csproj" /> <ProjectReference Include="..\Volo.Abp.Guids\Volo.Abp.Guids.csproj" />
<ProjectReference Include="..\Volo.Abp.Json\Volo.Abp.Json.csproj" /> <ProjectReference Include="..\Volo.Abp.Json\Volo.Abp.Json.csproj" />

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

@ -1,7 +1,10 @@
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Volo.Abp.BackgroundWorkers;
using Volo.Abp.DistributedLocking;
using Volo.Abp.EventBus.Abstractions; using Volo.Abp.EventBus.Abstractions;
using Volo.Abp.EventBus.Boxes;
using Volo.Abp.EventBus.Distributed; using Volo.Abp.EventBus.Distributed;
using Volo.Abp.EventBus.Local; using Volo.Abp.EventBus.Local;
using Volo.Abp.Guids; using Volo.Abp.Guids;
@ -16,7 +19,9 @@ namespace Volo.Abp.EventBus
typeof(AbpEventBusAbstractionsModule), typeof(AbpEventBusAbstractionsModule),
typeof(AbpMultiTenancyModule), typeof(AbpMultiTenancyModule),
typeof(AbpJsonModule), typeof(AbpJsonModule),
typeof(AbpGuidsModule) typeof(AbpGuidsModule),
typeof(AbpBackgroundWorkersModule),
typeof(AbpDistributedLockingAbstractionsModule)
)] )]
public class AbpEventBusModule : AbpModule public class AbpEventBusModule : AbpModule
{ {
@ -24,6 +29,12 @@ namespace Volo.Abp.EventBus
{ {
AddEventHandlers(context.Services); AddEventHandlers(context.Services);
} }
public override void OnApplicationInitialization(ApplicationInitializationContext context)
{
context.AddBackgroundWorker<OutboxSenderManager>();
context.AddBackgroundWorker<InboxProcessManager>();
}
private static void AddEventHandlers(IServiceCollection services) private static void AddEventHandlers(IServiceCollection services)
{ {

0
framework/src/Volo.Abp.EventBus.Boxes/Volo/Abp/EventBus/Boxes/AbpDistributedEventBusExtensions.cs → framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/AbpDistributedEventBusExtensions.cs

0
framework/src/Volo.Abp.EventBus.Boxes/Volo/Abp/EventBus/Boxes/AbpEventBusBoxesOptions.cs → framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/AbpEventBusBoxesOptions.cs

0
framework/src/Volo.Abp.EventBus.Boxes/Volo/Abp/EventBus/Boxes/IInboxProcessor.cs → framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/IInboxProcessor.cs

0
framework/src/Volo.Abp.EventBus.Boxes/Volo/Abp/EventBus/Boxes/IOutboxSender.cs → framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/IOutboxSender.cs

0
framework/src/Volo.Abp.EventBus.Boxes/Volo/Abp/EventBus/Boxes/InboxProcessManager.cs → framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/InboxProcessManager.cs

20
framework/src/Volo.Abp.EventBus.Boxes/Volo/Abp/EventBus/Boxes/InboxProcessor.cs → framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/InboxProcessor.cs

@ -1,12 +1,12 @@
using System; using System;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Medallion.Threading;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
using Volo.Abp.DistributedLocking;
using Volo.Abp.EventBus.Distributed; using Volo.Abp.EventBus.Distributed;
using Volo.Abp.Threading; using Volo.Abp.Threading;
using Volo.Abp.Timing; using Volo.Abp.Timing;
@ -19,7 +19,7 @@ namespace Volo.Abp.EventBus.Boxes
protected IServiceProvider ServiceProvider { get; } protected IServiceProvider ServiceProvider { get; }
protected AbpAsyncTimer Timer { get; } protected AbpAsyncTimer Timer { get; }
protected IDistributedEventBus DistributedEventBus { get; } protected IDistributedEventBus DistributedEventBus { get; }
protected IDistributedLockProvider DistributedLockProvider { get; } protected IAbpDistributedLock DistributedLock { get; }
protected IUnitOfWorkManager UnitOfWorkManager { get; } protected IUnitOfWorkManager UnitOfWorkManager { get; }
protected IClock Clock { get; } protected IClock Clock { get; }
protected IEventInbox Inbox { get; private set; } protected IEventInbox Inbox { get; private set; }
@ -28,7 +28,7 @@ namespace Volo.Abp.EventBus.Boxes
protected DateTime? LastCleanTime { get; set; } protected DateTime? LastCleanTime { get; set; }
protected string DistributedLockName => "Inbox_" + InboxConfig.Name; protected string DistributedLockName => "AbpInbox_" + InboxConfig.Name;
public ILogger<InboxProcessor> Logger { get; set; } public ILogger<InboxProcessor> Logger { get; set; }
protected CancellationTokenSource StoppingTokenSource { get; } protected CancellationTokenSource StoppingTokenSource { get; }
protected CancellationToken StoppingToken { get; } protected CancellationToken StoppingToken { get; }
@ -37,7 +37,7 @@ namespace Volo.Abp.EventBus.Boxes
IServiceProvider serviceProvider, IServiceProvider serviceProvider,
AbpAsyncTimer timer, AbpAsyncTimer timer,
IDistributedEventBus distributedEventBus, IDistributedEventBus distributedEventBus,
IDistributedLockProvider distributedLockProvider, IAbpDistributedLock distributedLock,
IUnitOfWorkManager unitOfWorkManager, IUnitOfWorkManager unitOfWorkManager,
IClock clock, IClock clock,
IOptions<AbpEventBusBoxesOptions> eventBusBoxesOptions) IOptions<AbpEventBusBoxesOptions> eventBusBoxesOptions)
@ -45,11 +45,11 @@ namespace Volo.Abp.EventBus.Boxes
ServiceProvider = serviceProvider; ServiceProvider = serviceProvider;
Timer = timer; Timer = timer;
DistributedEventBus = distributedEventBus; DistributedEventBus = distributedEventBus;
DistributedLockProvider = distributedLockProvider; DistributedLock = distributedLock;
UnitOfWorkManager = unitOfWorkManager; UnitOfWorkManager = unitOfWorkManager;
Clock = clock; Clock = clock;
EventBusBoxesOptions = eventBusBoxesOptions.Value; EventBusBoxesOptions = eventBusBoxesOptions.Value;
Timer.Period = EventBusBoxesOptions.PeriodTimeSpan.Milliseconds; Timer.Period = Convert.ToInt32(EventBusBoxesOptions.PeriodTimeSpan.TotalMilliseconds);
Timer.Elapsed += TimerOnElapsed; Timer.Elapsed += TimerOnElapsed;
Logger = NullLogger<InboxProcessor>.Instance; Logger = NullLogger<InboxProcessor>.Instance;
StoppingTokenSource = new CancellationTokenSource(); StoppingTokenSource = new CancellationTokenSource();
@ -84,7 +84,7 @@ namespace Volo.Abp.EventBus.Boxes
return; return;
} }
await using (var handle = await DistributedLockProvider.TryAcquireLockAsync(DistributedLockName, cancellationToken: StoppingToken)) await using (var handle = await DistributedLock.TryAcquireAsync(DistributedLockName, cancellationToken: StoppingToken))
{ {
if (handle != null) if (handle != null)
{ {
@ -120,7 +120,11 @@ namespace Volo.Abp.EventBus.Boxes
else else
{ {
Logger.LogDebug("Could not obtain the distributed lock: " + DistributedLockName); Logger.LogDebug("Could not obtain the distributed lock: " + DistributedLockName);
await TaskDelayHelper.DelayAsync(EventBusBoxesOptions.DistributedLockWaitDuration.Milliseconds, StoppingToken); try
{
await Task.Delay(EventBusBoxesOptions.DistributedLockWaitDuration, StoppingToken);
}
catch (TaskCanceledException) { }
} }
} }
} }

22
framework/src/Volo.Abp.EventBus.Boxes/Volo/Abp/EventBus/Boxes/OutboxSender.cs → framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/OutboxSender.cs

@ -1,12 +1,12 @@
using System; using System;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Medallion.Threading;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
using Volo.Abp.DistributedLocking;
using Volo.Abp.EventBus.Distributed; using Volo.Abp.EventBus.Distributed;
using Volo.Abp.Threading; using Volo.Abp.Threading;
@ -17,11 +17,11 @@ namespace Volo.Abp.EventBus.Boxes
protected IServiceProvider ServiceProvider { get; } protected IServiceProvider ServiceProvider { get; }
protected AbpAsyncTimer Timer { get; } protected AbpAsyncTimer Timer { get; }
protected IDistributedEventBus DistributedEventBus { get; } protected IDistributedEventBus DistributedEventBus { get; }
protected IDistributedLockProvider DistributedLockProvider { get; } protected IAbpDistributedLock DistributedLock { get; }
protected IEventOutbox Outbox { get; private set; } protected IEventOutbox Outbox { get; private set; }
protected OutboxConfig OutboxConfig { get; private set; } protected OutboxConfig OutboxConfig { get; private set; }
protected AbpEventBusBoxesOptions EventBusBoxesOptions { get; } protected AbpEventBusBoxesOptions EventBusBoxesOptions { get; }
protected string DistributedLockName => "Outbox_" + OutboxConfig.Name; protected string DistributedLockName => "AbpOutbox_" + OutboxConfig.Name;
public ILogger<OutboxSender> Logger { get; set; } public ILogger<OutboxSender> Logger { get; set; }
protected CancellationTokenSource StoppingTokenSource { get; } protected CancellationTokenSource StoppingTokenSource { get; }
@ -31,15 +31,15 @@ namespace Volo.Abp.EventBus.Boxes
IServiceProvider serviceProvider, IServiceProvider serviceProvider,
AbpAsyncTimer timer, AbpAsyncTimer timer,
IDistributedEventBus distributedEventBus, IDistributedEventBus distributedEventBus,
IDistributedLockProvider distributedLockProvider, IAbpDistributedLock distributedLock,
IOptions<AbpEventBusBoxesOptions> eventBusBoxesOptions) IOptions<AbpEventBusBoxesOptions> eventBusBoxesOptions)
{ {
ServiceProvider = serviceProvider; ServiceProvider = serviceProvider;
Timer = timer;
DistributedEventBus = distributedEventBus; DistributedEventBus = distributedEventBus;
DistributedLockProvider = distributedLockProvider; DistributedLock = distributedLock;
EventBusBoxesOptions = eventBusBoxesOptions.Value; EventBusBoxesOptions = eventBusBoxesOptions.Value;
Timer.Period = EventBusBoxesOptions.PeriodTimeSpan.Milliseconds; Timer = timer;
Timer.Period = Convert.ToInt32(EventBusBoxesOptions.PeriodTimeSpan.TotalMilliseconds);
Timer.Elapsed += TimerOnElapsed; Timer.Elapsed += TimerOnElapsed;
Logger = NullLogger<OutboxSender>.Instance; Logger = NullLogger<OutboxSender>.Instance;
StoppingTokenSource = new CancellationTokenSource(); StoppingTokenSource = new CancellationTokenSource();
@ -69,7 +69,7 @@ namespace Volo.Abp.EventBus.Boxes
protected virtual async Task RunAsync() protected virtual async Task RunAsync()
{ {
await using (var handle = await DistributedLockProvider.TryAcquireLockAsync(DistributedLockName, cancellationToken: StoppingToken)) await using (var handle = await DistributedLock.TryAcquireAsync(DistributedLockName, cancellationToken: StoppingToken))
{ {
if (handle != null) if (handle != null)
{ {
@ -100,7 +100,11 @@ namespace Volo.Abp.EventBus.Boxes
else else
{ {
Logger.LogDebug("Could not obtain the distributed lock: " + DistributedLockName); Logger.LogDebug("Could not obtain the distributed lock: " + DistributedLockName);
await TaskDelayHelper.DelayAsync(EventBusBoxesOptions.DistributedLockWaitDuration.Milliseconds, StoppingToken); try
{
await Task.Delay(EventBusBoxesOptions.DistributedLockWaitDuration, StoppingToken);
}
catch (TaskCanceledException) { }
} }
} }
} }

0
framework/src/Volo.Abp.EventBus.Boxes/Volo/Abp/EventBus/Boxes/OutboxSenderManager.cs → framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/OutboxSenderManager.cs

3
framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/ClientProxying/ClientProxyBase.cs

@ -16,6 +16,7 @@ using Volo.Abp.Http.Modeling;
using Volo.Abp.Http.ProxyScripting.Generators; using Volo.Abp.Http.ProxyScripting.Generators;
using Volo.Abp.Json; using Volo.Abp.Json;
using Volo.Abp.MultiTenancy; using Volo.Abp.MultiTenancy;
using Volo.Abp.Reflection;
using Volo.Abp.Threading; using Volo.Abp.Threading;
using Volo.Abp.Tracing; using Volo.Abp.Tracing;
@ -55,7 +56,7 @@ namespace Volo.Abp.Http.Client.ClientProxying
arguments = new ClientProxyRequestTypeValue(); arguments = new ClientProxyRequestTypeValue();
} }
var methodUniqueName = $"{typeof(TService).FullName}.{methodName}.{string.Join("-", arguments.Values.Select(x => x.Key.FullName))}"; var methodUniqueName = $"{typeof(TService).FullName}.{methodName}.{string.Join("-", arguments.Values.Select(x => TypeHelper.GetFullNameHandlingNullableAndGenerics(x.Key)))}";
var action = ClientProxyApiDescriptionFinder.FindAction(methodUniqueName); var action = ClientProxyApiDescriptionFinder.FindAction(methodUniqueName);
if (action == null) if (action == null)
{ {

2
framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Tests/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Tests.csproj

@ -1,5 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.Web"> <Project Sdk="Microsoft.NET.Sdk.Web">
<Import Project="..\..\..\common.test.props" />
<PropertyGroup> <PropertyGroup>
<TargetFramework>net6.0</TargetFramework> <TargetFramework>net6.0</TargetFramework>
</PropertyGroup> </PropertyGroup>

18
framework/test/Volo.Abp.DistributedLocking.Abstractions.Tests/Volo.Abp.DistributedLocking.Abstractions.Tests.csproj

@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\common.test.props" />
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
<RootNamespace />
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Volo.Abp.DistributedLocking.Abstractions\Volo.Abp.DistributedLocking.Abstractions.csproj" />
<ProjectReference Include="..\AbpTestBase\AbpTestBase.csproj" />
<ProjectReference Include="..\..\src\Volo.Abp.Autofac\Volo.Abp.Autofac.csproj" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="$(MicrosoftNETTestSdkPackageVersion)" />
</ItemGroup>
</Project>

12
framework/test/Volo.Abp.DistributedLocking.Abstractions.Tests/Volo/Abp/DistributedLocking/AbpDistributedLockingAbstractionsTestBase.cs

@ -0,0 +1,12 @@
using Volo.Abp.Testing;
namespace Volo.Abp.DistributedLocking
{
public class AbpDistributedLockingAbstractionsTestBase : AbpIntegratedTest<AbpDistributedLockingAbstractionsTestModule>
{
protected override void SetAbpApplicationCreationOptions(AbpApplicationCreationOptions options)
{
options.UseAutofac();
}
}
}

15
framework/test/Volo.Abp.DistributedLocking.Abstractions.Tests/Volo/Abp/DistributedLocking/AbpDistributedLockingAbstractionsTestModule.cs

@ -0,0 +1,15 @@
using Volo.Abp.Autofac;
using Volo.Abp.Modularity;
namespace Volo.Abp.DistributedLocking
{
[DependsOn(
typeof(AbpTestBaseModule),
typeof(AbpDistributedLockingAbstractionsModule),
typeof(AbpAutofacModule)
)]
public class AbpDistributedLockingAbstractionsTestModule : AbpModule
{
}
}

73
framework/test/Volo.Abp.DistributedLocking.Abstractions.Tests/Volo/Abp/DistributedLocking/LocalDistributedLock_Tests.cs

@ -0,0 +1,73 @@
using System.Threading.Tasks;
using Shouldly;
using Xunit;
namespace Volo.Abp.DistributedLocking
{
public class LocalDistributedLock_Tests : AbpDistributedLockingAbstractionsTestBase
{
private readonly IAbpDistributedLock _distributedLock;
public LocalDistributedLock_Tests()
{
_distributedLock = GetRequiredService<IAbpDistributedLock>();
}
[Fact]
public void Should_Be_Instance_Of_LocalAbpDistributedLock()
{
_distributedLock.ShouldBeOfType<LocalAbpDistributedLock>();
}
[Fact]
public async Task Should_Lock_With_TryAcquire()
{
await using (var handle = await _distributedLock.TryAcquireAsync("lock1"))
{
handle.ShouldNotBeNull();
}
}
[Fact]
public async Task Should_Not_Acquire_If_Already_Locked()
{
await using (var handle = await _distributedLock.TryAcquireAsync("lock1"))
{
handle.ShouldNotBeNull();
await Task.Run(async () =>
{
await using (var handle2 = await _distributedLock.TryAcquireAsync("lock1"))
{
handle2.ShouldBeNull();
}
});
}
await Task.Run(async () =>
{
await using (var handle = await _distributedLock.TryAcquireAsync("lock1"))
{
handle.ShouldNotBeNull();
}
});
}
[Fact]
public async Task Should_Obtain_Multiple_Locks()
{
await using (var handle = await _distributedLock.TryAcquireAsync("lock1"))
{
handle.ShouldNotBeNull();
await Task.Run(async () =>
{
await using (var handle2 = await _distributedLock.TryAcquireAsync("lock2"))
{
handle2.ShouldNotBeNull();
}
});
}
}
}
}

1
framework/test/Volo.Abp.Serialization.Tests/Volo/Abp/Serialization/Objects/CarSerializer.cs

@ -1,7 +1,6 @@
using System.Text.Json; using System.Text.Json;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
namespace Volo.Abp.Serialization.Objects namespace Volo.Abp.Serialization.Objects
{ {
public class CarSerializer : IObjectSerializer<Car>, ITransientDependency public class CarSerializer : IObjectSerializer<Car>, ITransientDependency

2
global.json

@ -1,6 +1,6 @@
{ {
"sdk": { "sdk": {
"version": "6.0.100-rc.1.21458.32", "version": "6.0.100-rc.2.21505.57",
"rollForward": "latestFeature" "rollForward": "latestFeature"
} }
} }

24
modules/account/src/Volo.Abp.Account.Application.Contracts/Volo/Abp/Account/Localization/Resources/it.json

@ -3,14 +3,14 @@
"texts": { "texts": {
"UserName": "Nome utente", "UserName": "Nome utente",
"EmailAddress": "Indirizzo e-mail", "EmailAddress": "Indirizzo e-mail",
"UserNameOrEmailAddress": "Username o Indirizzo Email", "UserNameOrEmailAddress": "Username o Indirizzo e-mail",
"Password": "Password", "Password": "Password",
"RememberMe": "Ricordati di me", "RememberMe": "Ricordati di me",
"UseAnotherServiceToLogin": "Usa un altro servizio per accedere", "UseAnotherServiceToLogin": "Usa un altro servizio per accedere",
"UserLockedOutMessage": "L'account utente è stato bloccato a causa di tentativi di accesso non validi. Attendi qualche istante e riprova.", "UserLockedOutMessage": "L'account utente è stato bloccato a causa di troppi tentativi di accesso non validi. Attendi qualche istante e riprova.",
"InvalidUserNameOrPassword": "Username o password non validi!", "InvalidUserNameOrPassword": "Username o password non validi!",
"LoginIsNotAllowed": "Non sei autorizzato ad accedere! Il tuo account non è attivo o deve confermare la tua email/numero di telefono.", "LoginIsNotAllowed": "Non sei autorizzato ad accedere! Il tuo account non è attivo o devi confermare la tua e-mail/numero di telefono.",
"SelfRegistrationDisabledMessage": "L'auto-registrazione è disabilitata per questa applicazione. Contatta l'amministratore dell'applicazione per registrare un nuovo utente.", "SelfRegistrationDisabledMessage": "L'auto-registrazione è disabilitata per questa applicazione. Contatta l'amministratore dell'applicazione per richiedere la registrazione.",
"LocalLoginDisabledMessage": "L'accesso locale è disabilitato per questa applicazione.", "LocalLoginDisabledMessage": "L'accesso locale è disabilitato per questa applicazione.",
"Login": "Login", "Login": "Login",
"Cancel": "Annulla", "Cancel": "Annulla",
@ -36,18 +36,18 @@
"PasswordChanged": "Password cambiata", "PasswordChanged": "Password cambiata",
"NewPasswordConfirmFailed": "Conferma la nuova password.", "NewPasswordConfirmFailed": "Conferma la nuova password.",
"Manage": "Gestire", "Manage": "Gestire",
"MyAccount": "Il mio conto", "MyAccount": "Il mio account",
"DisplayName:Abp.Account.IsSelfRegistrationEnabled": "L'auto-registrazione è abilitata", "DisplayName:Abp.Account.IsSelfRegistrationEnabled": "L'auto-registrazione è abilitata",
"Description:Abp.Account.IsSelfRegistrationEnabled": "Se un utente può registrare l'account da solo.", "Description:Abp.Account.IsSelfRegistrationEnabled": "Indica se un utente può registrare l'account da solo.",
"DisplayName:Abp.Account.EnableLocalLogin": "Autentica con un account locale", "DisplayName:Abp.Account.EnableLocalLogin": "Autenticazione con un account locale",
"Description:Abp.Account.EnableLocalLogin": "Indica se il server consentirà agli utenti di autenticarsi con un account locale.", "Description:Abp.Account.EnableLocalLogin": "Indica se il server consentirà agli utenti di autenticarsi con un account locale.",
"LoggedOutTitle": "Disconnesso", "LoggedOutTitle": "Disconnesso",
"LoggedOutText": "Sei stato disconnesso e verrai reindirizzato presto.", "LoggedOutText": "Sei stato disconnesso e verrai reindirizzato presto.",
"ReturnToText": "Fai clic qui per reindirizzare a {0}", "ReturnToText": "Fai clic qui per reindirizzare a {0}",
"OrLoginWith": "Oppure accedi con:", "OrLoginWith": "Oppure accedi con:",
"ForgotPassword": "Ha dimenticato la password?", "ForgotPassword": "Ha dimenticato la password?",
"SendPasswordResetLink_Information": "Un link per reimpostare la password verrà inviato alla tua e-mail per reimpostare la password. Se non ricevi un'email entro pochi minuti, riprova.", "SendPasswordResetLink_Information": "Un link per reimpostare la password verrà inviato alla tua e-mail. Se non ricevi l'e-mail entro pochi minuti, riprova.",
"PasswordResetMailSentMessage": "E-mail di recupero dell'account inviata al tuo indirizzo e-mail. Se non vedi questa email nella tua posta in arrivo entro 15 minuti, cercala nella cartella della posta indesiderata. Se lo trovi lì, contrassegnalo come -Non Junk-.", "PasswordResetMailSentMessage": "E-mail di recupero dell'account inviata al tuo indirizzo e-mail. Se non vedi questa e-mail nella tua posta in arrivo entro 15 minuti, cercala nella cartella della posta indesiderata. Se lo trovi lì, contrassegnalo come -Non Junk-.",
"ResetPassword": "Resetta la password", "ResetPassword": "Resetta la password",
"ConfirmPassword": "Conferma (ripeti) la password", "ConfirmPassword": "Conferma (ripeti) la password",
"ResetPassword_Information": "Per favore inserisci la tua nuova password.", "ResetPassword_Information": "Per favore inserisci la tua nuova password.",
@ -57,11 +57,11 @@
"ProfileTab:Password": "Cambia la password", "ProfileTab:Password": "Cambia la password",
"ProfileTab:PersonalInfo": "Informazioni personali", "ProfileTab:PersonalInfo": "Informazioni personali",
"ReturnToApplication": "Torna all'applicazione", "ReturnToApplication": "Torna all'applicazione",
"Volo.Account:InvalidEmailAddress": "Impossibile trovare l'indirizzo email fornito: {0}", "Volo.Account:InvalidEmailAddress": "Impossibile trovare l'indirizzo e-mail fornito: {0}",
"PasswordReset": "Reimpostazione della password", "PasswordReset": "Reimpostazione della password",
"PasswordResetInfoInEmail": "Abbiamo ricevuto una richiesta di recupero dell'account! Se hai avviato questa richiesta, fai clic sul seguente collegamento per reimpostare la password.", "PasswordResetInfoInEmail": "Abbiamo ricevuto una richiesta di recupero dell'account! Se hai fatto tu questa richiesta fai clic sul seguente collegamento per reimpostare la password.",
"ResetMyPassword": "Reimposta la mia password", "ResetMyPassword": "Reimposta la mia password",
"AccessDenied": "Accesso negato!", "AccessDenied": "Accesso negato!",
"AccessDeniedMessage": "Non hai accesso a questa risorsa." "AccessDeniedMessage": "Non hai accesso a questa risorsa."
} }
} }

7
modules/account/test/Volo.Abp.Account.Application.Tests/Volo.Abp.Account.Application.Tests.csproj

@ -26,4 +26,11 @@
<ProjectReference Include="..\..\..\permission-management\src\Volo.Abp.PermissionManagement.EntityFrameworkCore\Volo.Abp.PermissionManagement.EntityFrameworkCore.csproj" /> <ProjectReference Include="..\..\..\permission-management\src\Volo.Abp.PermissionManagement.EntityFrameworkCore\Volo.Abp.PermissionManagement.EntityFrameworkCore.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="$(CoverletCollectorPackageVersion)">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project> </Project>

7
modules/audit-logging/test/Volo.Abp.AuditLogging.EntityFrameworkCore.Tests/Volo.Abp.AuditLogging.EntityFrameworkCore.Tests.csproj

@ -18,4 +18,11 @@
<PackageReference Include="Microsoft.Data.Sqlite" Version="$(MicrosoftPackageVersion)" /> <PackageReference Include="Microsoft.Data.Sqlite" Version="$(MicrosoftPackageVersion)" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="$(CoverletCollectorPackageVersion)">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project> </Project>

7
modules/audit-logging/test/Volo.Abp.AuditLogging.MongoDB.Tests/Volo.Abp.AuditLogging.MongoDB.Tests.csproj

@ -17,4 +17,11 @@
<PackageReference Include="Mongo2Go" Version="$(Mongo2GoPackageVersion)" /> <PackageReference Include="Mongo2Go" Version="$(Mongo2GoPackageVersion)" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="$(CoverletCollectorPackageVersion)">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project> </Project>

7
modules/audit-logging/test/Volo.Abp.AuditLogging.TestBase/Volo.Abp.AuditLogging.TestBase.csproj

@ -22,4 +22,11 @@
<PackageReference Include="xunit.runner.visualstudio" Version="$(xUnitRunnerVisualstudioPackageVersion)" /> <PackageReference Include="xunit.runner.visualstudio" Version="$(xUnitRunnerVisualstudioPackageVersion)" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="$(CoverletCollectorPackageVersion)">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project> </Project>

7
modules/audit-logging/test/Volo.Abp.AuditLogging.Tests/Volo.Abp.AuditLogging.Tests.csproj

@ -15,4 +15,11 @@
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="$(MicrosoftNETTestSdkPackageVersion)" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="$(MicrosoftNETTestSdkPackageVersion)" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="$(CoverletCollectorPackageVersion)">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project> </Project>

4
modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp/DemoAppModule.cs

@ -1,6 +1,4 @@
using Microsoft.Extensions.DependencyInjection; using Volo.Abp.Autofac;
using Microsoft.Extensions.Logging;
using Volo.Abp.Autofac;
using Volo.Abp.BackgroundJobs.DemoApp.Shared; using Volo.Abp.BackgroundJobs.DemoApp.Shared;
using Volo.Abp.BackgroundJobs.EntityFrameworkCore; using Volo.Abp.BackgroundJobs.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore; using Volo.Abp.EntityFrameworkCore;

7
modules/background-jobs/test/Volo.Abp.BackgroundJobs.Domain.Tests/Volo.Abp.BackgroundJobs.Domain.Tests.csproj

@ -15,4 +15,11 @@
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="$(MicrosoftNETTestSdkPackageVersion)" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="$(MicrosoftNETTestSdkPackageVersion)" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="$(CoverletCollectorPackageVersion)">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project> </Project>

7
modules/background-jobs/test/Volo.Abp.BackgroundJobs.EntityFrameworkCore.Tests/Volo.Abp.BackgroundJobs.EntityFrameworkCore.Tests.csproj

@ -18,4 +18,11 @@
<PackageReference Include="Microsoft.EntityFrameworkCore.Proxies" Version="$(MicrosoftPackageVersion)" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Proxies" Version="$(MicrosoftPackageVersion)" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="$(CoverletCollectorPackageVersion)">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project> </Project>

7
modules/background-jobs/test/Volo.Abp.BackgroundJobs.MongoDB.Tests/Volo.Abp.BackgroundJobs.MongoDB.Tests.csproj

@ -17,4 +17,11 @@
<PackageReference Include="Mongo2Go" Version="$(Mongo2GoPackageVersion)" /> <PackageReference Include="Mongo2Go" Version="$(Mongo2GoPackageVersion)" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="$(CoverletCollectorPackageVersion)">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project> </Project>

7
modules/background-jobs/test/Volo.Abp.BackgroundJobs.TestBase/Volo.Abp.BackgroundJobs.TestBase.csproj

@ -22,4 +22,11 @@
<PackageReference Include="xunit.runner.visualstudio" Version="$(xUnitRunnerVisualstudioPackageVersion)" /> <PackageReference Include="xunit.runner.visualstudio" Version="$(xUnitRunnerVisualstudioPackageVersion)" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="$(CoverletCollectorPackageVersion)">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project> </Project>

7
modules/basic-theme/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo.Tests/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo.Tests.csproj

@ -29,6 +29,13 @@
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3" /> <PackageReference Include="xunit.runner.visualstudio" Version="2.4.3" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="$(CoverletCollectorPackageVersion)">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
</ItemGroup>
<!-- Below ItemGroup and Target tags are added according to https://github.com/aspnet/Hosting/issues/959#issuecomment-286351703 --> <!-- Below ItemGroup and Target tags are added according to https://github.com/aspnet/Hosting/issues/959#issuecomment-286351703 -->
<!-- Solves Problem#2 (404 when executing service calls hosted in other assemblies) --> <!-- Solves Problem#2 (404 when executing service calls hosted in other assemblies) -->

7
modules/blob-storing-database/test/Volo.Abp.BlobStoring.Database.Domain.Tests/Volo.Abp.BlobStoring.Database.Domain.Tests.csproj

@ -10,4 +10,11 @@
<ProjectReference Include="..\Volo.Abp.BlobStoring.Database.EntityFrameworkCore.Tests\Volo.Abp.BlobStoring.Database.EntityFrameworkCore.Tests.csproj" /> <ProjectReference Include="..\Volo.Abp.BlobStoring.Database.EntityFrameworkCore.Tests\Volo.Abp.BlobStoring.Database.EntityFrameworkCore.Tests.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="$(CoverletCollectorPackageVersion)">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project> </Project>

7
modules/blob-storing-database/test/Volo.Abp.BlobStoring.Database.EntityFrameworkCore.Tests/Volo.Abp.BlobStoring.Database.EntityFrameworkCore.Tests.csproj

@ -14,4 +14,11 @@
<ProjectReference Include="..\Volo.Abp.BlobStoring.Database.TestBase\Volo.Abp.BlobStoring.Database.TestBase.csproj" /> <ProjectReference Include="..\Volo.Abp.BlobStoring.Database.TestBase\Volo.Abp.BlobStoring.Database.TestBase.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="$(CoverletCollectorPackageVersion)">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project> </Project>

7
modules/blob-storing-database/test/Volo.Abp.BlobStoring.Database.MongoDB.Tests/Volo.Abp.BlobStoring.Database.MongoDB.Tests.csproj

@ -12,4 +12,11 @@
<ProjectReference Include="..\Volo.Abp.BlobStoring.Database.TestBase\Volo.Abp.BlobStoring.Database.TestBase.csproj" /> <ProjectReference Include="..\Volo.Abp.BlobStoring.Database.TestBase\Volo.Abp.BlobStoring.Database.TestBase.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="$(CoverletCollectorPackageVersion)">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project> </Project>

7
modules/blob-storing-database/test/Volo.Abp.BlobStoring.Database.TestBase/Volo.Abp.BlobStoring.Database.TestBase.csproj

@ -19,4 +19,11 @@
<ProjectReference Include="..\..\src\Volo.Abp.BlobStoring.Database.Domain\Volo.Abp.BlobStoring.Database.Domain.csproj" /> <ProjectReference Include="..\..\src\Volo.Abp.BlobStoring.Database.Domain\Volo.Abp.BlobStoring.Database.Domain.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="$(CoverletCollectorPackageVersion)">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project> </Project>

7
modules/blogging/test/Volo.Blogging.Application.Tests/Volo.Blogging.Application.Tests.csproj

@ -16,4 +16,11 @@
<ProjectReference Include="..\Volo.Blogging.Domain.Tests\Volo.Blogging.Domain.Tests.csproj" /> <ProjectReference Include="..\Volo.Blogging.Domain.Tests\Volo.Blogging.Domain.Tests.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="$(CoverletCollectorPackageVersion)">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project> </Project>

7
modules/blogging/test/Volo.Blogging.Domain.Tests/Volo.Blogging.Domain.Tests.csproj

@ -14,4 +14,11 @@
<ProjectReference Include="..\Volo.Blogging.TestBase\Volo.Blogging.TestBase.csproj" /> <ProjectReference Include="..\Volo.Blogging.TestBase\Volo.Blogging.TestBase.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="$(CoverletCollectorPackageVersion)">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project> </Project>

7
modules/blogging/test/Volo.Blogging.EntityFrameworkCore.Tests/Volo.Blogging.EntityFrameworkCore.Tests.csproj

@ -15,4 +15,11 @@
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="$(MicrosoftNETTestSdkPackageVersion)" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="$(MicrosoftNETTestSdkPackageVersion)" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="$(CoverletCollectorPackageVersion)">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project> </Project>

7
modules/blogging/test/Volo.Blogging.MongoDB.Tests/Volo.Blogging.MongoDB.Tests.csproj

@ -12,4 +12,11 @@
<ProjectReference Include="..\Volo.Blogging.TestBase\Volo.Blogging.TestBase.csproj" /> <ProjectReference Include="..\Volo.Blogging.TestBase\Volo.Blogging.TestBase.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="$(CoverletCollectorPackageVersion)">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project> </Project>

7
modules/blogging/test/Volo.Blogging.TestBase/Volo.Blogging.TestBase.csproj

@ -20,4 +20,11 @@
<PackageReference Include="xunit.runner.visualstudio" Version="$(xUnitRunnerVisualstudioPackageVersion)" /> <PackageReference Include="xunit.runner.visualstudio" Version="$(xUnitRunnerVisualstudioPackageVersion)" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="$(CoverletCollectorPackageVersion)">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project> </Project>

7
modules/cms-kit/test/Volo.CmsKit.Application.Tests/Volo.CmsKit.Application.Tests.csproj

@ -15,4 +15,11 @@
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="$(MicrosoftNETTestSdkPackageVersion)" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="$(MicrosoftNETTestSdkPackageVersion)" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="$(CoverletCollectorPackageVersion)">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project> </Project>

7
modules/cms-kit/test/Volo.CmsKit.Domain.Tests/Volo.CmsKit.Domain.Tests.csproj

@ -10,4 +10,11 @@
<ProjectReference Include="..\Volo.CmsKit.EntityFrameworkCore.Tests\Volo.CmsKit.EntityFrameworkCore.Tests.csproj" /> <ProjectReference Include="..\Volo.CmsKit.EntityFrameworkCore.Tests\Volo.CmsKit.EntityFrameworkCore.Tests.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="$(CoverletCollectorPackageVersion)">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project> </Project>

7
modules/cms-kit/test/Volo.CmsKit.EntityFrameworkCore.Tests/Volo.CmsKit.EntityFrameworkCore.Tests.csproj

@ -13,4 +13,11 @@
<ProjectReference Include="..\..\..\..\framework\src\Volo.Abp.EntityFrameworkCore.Sqlite\Volo.Abp.EntityFrameworkCore.Sqlite.csproj" /> <ProjectReference Include="..\..\..\..\framework\src\Volo.Abp.EntityFrameworkCore.Sqlite\Volo.Abp.EntityFrameworkCore.Sqlite.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="$(CoverletCollectorPackageVersion)">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project> </Project>

7
modules/cms-kit/test/Volo.CmsKit.MongoDB.Tests/Volo.CmsKit.MongoDB.Tests.csproj

@ -12,4 +12,11 @@
<ProjectReference Include="..\Volo.CmsKit.TestBase\Volo.CmsKit.TestBase.csproj" /> <ProjectReference Include="..\Volo.CmsKit.TestBase\Volo.CmsKit.TestBase.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="$(CoverletCollectorPackageVersion)">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project> </Project>

7
modules/cms-kit/test/Volo.CmsKit.TestBase/Volo.CmsKit.TestBase.csproj

@ -19,4 +19,11 @@
<ProjectReference Include="..\..\src\Volo.CmsKit.Domain\Volo.CmsKit.Domain.csproj" /> <ProjectReference Include="..\..\src\Volo.CmsKit.Domain\Volo.CmsKit.Domain.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="$(CoverletCollectorPackageVersion)">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project> </Project>

7
modules/docs/test/Volo.Docs.Admin.Application.Tests/Volo.Docs.Admin.Application.Tests.csproj

@ -14,4 +14,11 @@
<ProjectReference Include="..\Volo.Docs.Domain.Tests\Volo.Docs.Domain.Tests.csproj" /> <ProjectReference Include="..\Volo.Docs.Domain.Tests\Volo.Docs.Domain.Tests.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="$(CoverletCollectorPackageVersion)">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project> </Project>

7
modules/docs/test/Volo.Docs.Application.Tests/Volo.Docs.Application.Tests.csproj

@ -14,4 +14,11 @@
<ProjectReference Include="..\Volo.Docs.Domain.Tests\Volo.Docs.Domain.Tests.csproj" /> <ProjectReference Include="..\Volo.Docs.Domain.Tests\Volo.Docs.Domain.Tests.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="$(CoverletCollectorPackageVersion)">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project> </Project>

7
modules/docs/test/Volo.Docs.Domain.Tests/Volo.Docs.Domain.Tests.csproj

@ -14,4 +14,11 @@
<ProjectReference Include="..\Volo.Docs.TestBase\Volo.Docs.TestBase.csproj" /> <ProjectReference Include="..\Volo.Docs.TestBase\Volo.Docs.TestBase.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="$(CoverletCollectorPackageVersion)">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project> </Project>

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

Loading…
Cancel
Save