diff --git a/docs/zh-Hans/Background-Jobs-Hangfire.md b/docs/zh-Hans/Background-Jobs-Hangfire.md new file mode 100644 index 0000000000..5ef9aad32d --- /dev/null +++ b/docs/zh-Hans/Background-Jobs-Hangfire.md @@ -0,0 +1,3 @@ +# Hangfire Background Job Manager + +待添加 \ No newline at end of file diff --git a/docs/zh-Hans/Background-Jobs-RabbitMq.md b/docs/zh-Hans/Background-Jobs-RabbitMq.md new file mode 100644 index 0000000000..979beec872 --- /dev/null +++ b/docs/zh-Hans/Background-Jobs-RabbitMq.md @@ -0,0 +1,3 @@ +# RabbitMQ Background Job Manager + +待添加 \ No newline at end of file diff --git a/docs/zh-Hans/Background-Jobs.md b/docs/zh-Hans/Background-Jobs.md index cfd8cb60b8..c66330f816 100644 --- a/docs/zh-Hans/Background-Jobs.md +++ b/docs/zh-Hans/Background-Jobs.md @@ -1,6 +1,6 @@ -## 后台作业 +# 后台作业 -### 介绍 +## 介绍 后台作业用来在后台里执行应用里的一些任务, 出于几个原因, 你可能需要后台工作, 以下是一些例子: @@ -11,14 +11,167 @@ ABP为后台作业提供了一个**抽象**模块和几个后台作业**实现**. 它具有内置/默认的实现以及与Hangfire和RabbitMQ的集成. -### 抽象模块 +## 抽象模块 -待添加 +ABP为后台作业提供了一个 **abstraction** 模块和 **多个实现**. 它有一个内置/默认实现以及Hangfire与RabbitMQ集成. + +`Volo.Abp.BackgroundJobs.Abstractions` nuget package 提供了创建后台作业和队列作业所需要的服务. 如果你的模块只依赖这个包,那么它可以独立于其实现/集成. + +> `Volo.Abp.BackgroundJobs.Abstractions` package 默认在启动模板中已经安装. ### 创建后台作业 后台作业是一个实现`IBackgroundJob`接口或继承自`BackgroundJob`类的类.`TArgs`是一个简单的C#类, 用于存储作业数据. -在后台发送电子邮件的后台作业例子: +在示例中使用后台作业发送电子邮件,首先定义一个类来存储后台作业的参数 + +````csharp +public class EmailSendingArgs +{ + public string EmailAddress { get; set; } + public string Subject { get; set; } + public string Body { get; set; } +} +```` + +然后创建后台作业类,它使用 `EmailSendingArgs` 对象发送电子邮件: + +````csharp +using Volo.Abp.BackgroundJobs; +using Volo.Abp.Emailing; + +namespace MyProject +{ + public class EmailSendingJob : BackgroundJob + { + private readonly IEmailSender _emailSender; + + public EmailSendingJob(IEmailSender emailSender) + { + _emailSender = emailSender; + } + + public override void Execute(EmailSendingArgs args) + { + _emailSender.Send( + args.EmailAddress, + args.Subject, + args.Body + ); + } + } +} +```` + +这个作业简单的使用了 `IEmailSender` 发送电子邮件 (请参阅 [邮件发送文档](Emailing.md)). + +#### 异常处理 + +后台作业不应该隐藏异常. 如果它抛出一个异常, 在稍后后台作业将会自动重试. 只有在你不想为当前参数重新运行后台作业时才隐藏异常. + +### 队列作业 + +现在, 你可以使用 `IBackgroundJobManager` 服务向队列中添加一个发送电子邮件作业: + +````csharp +public class RegistrationService : ApplicationService +{ + private readonly IBackgroundJobManager _backgroundJobManager; + + public RegistrationService(IBackgroundJobManager backgroundJobManager) + { + _backgroundJobManager = backgroundJobManager; + } + + public async Task RegisterAsync(string userName, string emailAddress, string password) + { + //TODO: 创建一个新用户到数据库中... + + await _backgroundJobManager.EnqueueAsync( + new EmailSendingArgs + { + EmailAddress = emailAddress, + Subject = "You've successfully registered!", + Body = "..." + } + ); + } +} +```` + +刚才我们注入 `IBackgroundJobManager` 服务了并且使用它的 `EnqueueAsync` 方法添加一个新的作业到队列中. + +Enqueue方法接收一些可选参数用于控制后台作业: + +* **priority** 用于控制作业项的优先级. 它接收一个 `BackgroundJobPriority` 类型的枚举,它有 `Low`, `BelowNormal`, `Normal` (默认), `AboveNormal` 和 `Hight` 字段. +* **delay** 用于作业第一次重试之前的等待时间 (`TimeSpan`)类型. + +### 禁用作业执行 + +你可能希望在你的应用程序中禁用后台作业执行. 如果你希望在另一个进程中执行后台作业并在当前进程中禁用它,通常可以使用以下命令. + +使用 `BackgroundJobOptions` 配置作业执行: + +````csharp +[DependsOn(typeof(AbpBackgroundJobsModule))] +public class MyModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + Configure(options => + { + options.IsJobExecutionEnabled = false; //禁用作业执行 + }); + } +} +```` + +> 默认后台管理器(见下文)不支持多进程执行相同的作业队列. 所以, 如果你的应用程序中有多个正在运行的实现,并且使用的是默认的后台管理器, 你应该只在一个应用程序实例进程中启用作业队列. + +## 默认后台作业管理器 + +ABP framework 包含一个简单的 `IBackgroundJobManager` 实现; + +- 在**单线程**中**FIFO(先入先出)**. +- **重试**作业执行直到作业**执行成功**或**超时**. 默认作业超时时间是2天. 记录所有异常 . +- 作业执行成功时从存储中(数据库)**删除**作业. 如果超时, 作业会在数据库中被设置为**abandoned**. +- 作业的**重试等待时间会越来越长**. 作业第一次重试等待1分钟, 第二次重试等待2分钟, 第三次重试等待4分钟,以此类推. +- 以固定的时间间隔轮询存储中的作业. 查询作业, 按优先级排序(asc)然后按尝试次数排序(asc). + +> `Volo.Abp.BackgroundJobs` nuget package 包含默认的后台作业管理器并且在默认在启动模板中已经安装. + +### 配置 + +在你的[模块类](Module-Development-Basics.md)中使用 `BackgroundJobWorkerOptions` 配置默认作业管理器. +示例中更改后台作业的的超时时间: + +````csharp +[DependsOn(typeof(AbpBackgroundJobsModule))] +public class MyModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + Configure(options => + { + options.DefaultTimeout = 864000; //10 days (as seconds) + }); + } +} +```` + +### 数据存储 + +默认的后台作业管理器需要数据存储用来保存和读取作业. 它将 `IBackgroundJobStore` 定义为抽象的. 所以, 如果你想要的话你可以替换它的实现. + +后台作业模块使用各种数据访问提供程序实现 `IBackgroundJobStore`. 参阅 [后台工作模块文档](Modules/Background-Jobs.md). + +> 默认情况下,后台作业模块已经安装到启动模板中,它基于你的ORM/数据访问选项. + +## 集成 + +后台作业系统是可扩展的,你可以使用自己的实现或预先构建的集成更改默认后台作业管理器. + +请参阅预构建的作业管理器备选方案: -待添加 \ No newline at end of file +* [Hangfire 后台作业管理器](Background-Jobs-Hangfire.md) +* [RabbitMQ 后台作业管理器](Background-Jobs-RabbitMq.md) \ No newline at end of file diff --git a/docs/zh-Hans/Best-Practices/Application-Services.md b/docs/zh-Hans/Best-Practices/Application-Services.md index 90f5fd4606..8e9c85d63a 100644 --- a/docs/zh-Hans/Best-Practices/Application-Services.md +++ b/docs/zh-Hans/Best-Practices/Application-Services.md @@ -26,6 +26,7 @@ 示例: ```c# +[Serializable] public class IssueDto : FullAuditedEntityDto { public string Title { get; set; } @@ -34,6 +35,7 @@ public class IssueDto : FullAuditedEntityDto public Collection Labels { get; set; } } +[Serializable] public class IssueLabelDto { public Guid IssueId { get; set; } @@ -54,6 +56,7 @@ public class IssueLabelDto 示例: ````C# +[Serializable] public class IssueWithDetailsDto : FullAuditedEntityDto { public string Title { get; set; } @@ -62,12 +65,14 @@ public class IssueWithDetailsDto : FullAuditedEntityDto public Collection Labels { get; set; } } +[Serializable] public class MilestoneDto : EntityDto { public string Name { get; set; } public bool IsClosed { get; set; } } +[Serializable] public class LabelDto : EntityDto { public string Name { get; set; } @@ -128,6 +133,7 @@ Task CreateAsync(CreateQuestionDto questionDto); 输入**DTO**: ````C# +[Serializable] public class CreateQuestionDto { [Required] @@ -181,11 +187,13 @@ Task VoteAsync(Guid id, VoteType type); * **推荐** 在**应用层**实现应用服务接口. * **推荐** 使用命名约定. 如: 为 `IProductAppService` 接口创建 `ProductAppService` 类. * **推荐** 继承自 `ApplicationService` 基类. +* **推荐** 将所有的公开方法定义为 **virtual**, 以便开发人员继承和覆盖它们. +* **不推荐** 定义 **private** 方法. 应该定义为 **protected virtual**, 这样开发人员可以继承和覆盖它们. #### 使用仓储 * **推荐** 使用专门设计的仓储 (如 `IProductRepository`). -* **不推荐** 使用泛型仓储 (如 `IRepository`). +* **不推荐** 使用泛型仓储 (如 `IRepository`).z` #### 查询数据 diff --git a/docs/zh-Hans/Best-Practices/Data-Transfer-Objects.md b/docs/zh-Hans/Best-Practices/Data-Transfer-Objects.md index 0a523beb71..e0db48397e 100644 --- a/docs/zh-Hans/Best-Practices/Data-Transfer-Objects.md +++ b/docs/zh-Hans/Best-Practices/Data-Transfer-Objects.md @@ -4,4 +4,5 @@ * **推荐** 在可能和必要的情况下从预构建的 **基础DTO类** 继承 (如 `EntityDto`, `CreationAuditedEntityDto`, `AuditedEntityDto`, `FullAuditedEntityDto` 等). * **推荐** 定义 **public getter 和 setter** 的DTO成员 . * **推荐** 使用 **data annotations** **验证** service输入DTO的属性. -* **不推荐** 在DTO中添加任何 **逻辑**, 在必要的时候可以实现 `IValidatableObject` 接口. \ No newline at end of file +* **不推荐** 在DTO中添加任何 **逻辑**, 在必要的时候可以实现 `IValidatableObject` 接口. +* **推荐** 为所有的DTO标记 **[Serializable]** Attribute. 因为它们已经是可序列化的, 开人发员可能会希望进行二进制序列化. \ No newline at end of file diff --git a/docs/zh-Hans/Emailing.md b/docs/zh-Hans/Emailing.md new file mode 100644 index 0000000000..d285e5bde2 --- /dev/null +++ b/docs/zh-Hans/Emailing.md @@ -0,0 +1,3 @@ +# Emailing + +待添加 \ No newline at end of file diff --git a/docs/zh-Hans/Index.md b/docs/zh-Hans/Index.md index 655d0f8e79..e14bd67fa5 100644 --- a/docs/zh-Hans/Index.md +++ b/docs/zh-Hans/Index.md @@ -60,6 +60,8 @@ * [捆绑&压缩](AspNetCore/Bundling-Minification.md) * [Tag Helpers](Tag-Helpers.md) * [主题](AspNetCore/Theming.md) +* 后台服务 + * [后台作业](Background-Jobs.md) * 数据访问 * [Entity Framework Core 集成](Entity-Framework-Core.md) * [MongoDB 集成](MongoDB.md) diff --git a/docs/zh-Hans/Modules/Background-Jobs.md b/docs/zh-Hans/Modules/Background-Jobs.md new file mode 100644 index 0000000000..b183febd80 --- /dev/null +++ b/docs/zh-Hans/Modules/Background-Jobs.md @@ -0,0 +1,3 @@ +# Background Jobs Module + +待添加 \ No newline at end of file diff --git a/docs/zh-Hans/docs-nav.json b/docs/zh-Hans/docs-nav.json index 47f504251e..362e6fbc65 100644 --- a/docs/zh-Hans/docs-nav.json +++ b/docs/zh-Hans/docs-nav.json @@ -224,6 +224,25 @@ } ] }, + { + "text": "后台服务", + "items": [ + { + "text": "后台作业", + "path": "Background-Jobs.md", + "items": [ + { + "text": "Hangfire 集成", + "path": "Background-Jobs-Hangfire.md" + }, + { + "text": "RabbitMQ 集成", + "path": "Background-Jobs-RabbitMq.md" + } + ] + } + ] + }, { "text": "测试" },