diff --git a/docs/zh-Hans/Microservice-Architecture.md b/docs/zh-Hans/Microservice-Architecture.md index 166591e779..3b96cdc7f6 100644 --- a/docs/zh-Hans/Microservice-Architecture.md +++ b/docs/zh-Hans/Microservice-Architecture.md @@ -23,7 +23,7 @@ ABP框架的主要目标之一就是提供**便捷的基础设施来创建微服 然而开发一个良好的模块化应用程序不是那么简单,因为很难像微服务那样**保持模块之间的隔离** (参阅 [Stefan Tilkov的文章](https://martinfowler.com/articles/dont-start-monolith.html)). 微服务架构会自然的让你开发隔离的服务,但是在模块化的单体应用程序中,模块很容易彼此紧密耦合并设计出**弱模块边界**和API约定. -ABP可以帮助你,它提供了与**与微服务兼容的严格模块架构** 在这个架构中你的模块被分割成多个层/项目,在自己的VS解决方案中进行开发,该解决方案完成独立于其它模块. 这种方式开发的模块是一种天然的微服务,但是它可以很容易的插入到单体应用程序中. 请参阅**微服务优先的模块设计**的[模块开发最佳实践指南](Best-Practices/Index.md). 所有[标准的ABP模块](https://github.com/abpframework/abp/tree/master/modules)都是基于本指南开发的. 因此你可以将这些模块嵌入到单体解决方案中使用它们,也可以单独部署通过远程API调用. 它们可以共享一个数据库,也可以通过简单配置使用自己的数据库. +ABP可以帮助你,它提供了与**与微服务兼容的严格模块架构** 在这个架构中你的模块被分割成多个层/项目,在自己的VS解决方案中进行开发,该解决方案完全独立于其它模块. 这种方式开发的模块是一种天然的微服务,但是它可以很容易的插入到单体应用程序中. 请参阅**微服务优先的模块设计**的[模块开发最佳实践指南](Best-Practices/Index.md). 所有[标准的ABP模块](https://github.com/abpframework/abp/tree/master/modules)都是基于本指南开发的. 因此你可以将这些模块嵌入到单体解决方案中使用它们,也可以单独部署通过远程API调用. 它们可以共享一个数据库,也可以通过简单配置使用自己的数据库. ## 微服务解决方案示例 diff --git a/docs/zh-Hans/Options.md b/docs/zh-Hans/Options.md index a5206bce91..18ccd90bed 100644 --- a/docs/zh-Hans/Options.md +++ b/docs/zh-Hans/Options.md @@ -1,3 +1,121 @@ -# Options +# 选项 -TODO! +微软引入[选项模式](https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/configuration/options),它是用于配置框架服务使用的设置. 选项模式由[Microsoft.Extensions.Options](https://www.nuget.org/packages/Microsoft.Extensions.Options)NuGet包实现,除了ASP.NET Core应用,它还适用于任何类型的应用程序. + +ABP框架遵循选项模式,并定义了用于配置框架和模块的选项类(在相关功能文档中有详细的说明). + +由于[微软的文档](https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/configuration/options)详细解释了选项模式,本文中只会介绍ABP增加的一些功能. + +## 配置选项 + +通常配置选项在 `Startup` 类的 `ConfigureServices` 方法中. 但由于ABP框架提供了模块化基础设施,因此你可以在[模块](Module-Development-Basics.md)的`ConfigureServices` 方法配置选项. +例: + +````csharp +public override void ConfigureServices(ServiceConfigurationContext context) +{ + context.Services.Configure(options => + { + options.IsEnabled = false; + }); +} +```` + +* `AbpAuditingOptions` 是一个简单的类,定义了一些属性,例如这里使用的 `IsEnabled`. +* `AbpModule` 基类定义 `Configure` 方法简化代码. 你可以直接使用 `Configure<...>`,而不是`context.Services.Configure <...>`. + +如果你正在开发一个可重用的模块,你可能需要定义一个允许开发人员配置模块的选项类. 这时定义一个如下所示的普通类: + +````csharp +public class MyOptions +{ + public int Value1 { get; set; } + public bool Value2 { get; set; } +} +```` + +然后开发人员可以像上面 `AbpAuditingOptions` 示例一样配置你的选项: + +````csharp +public override void ConfigureServices(ServiceConfigurationContext context) +{ + Configure(options => + { + options.Value1 = 42; + options.Value2 = true; + }); +} +```` + +* 在本示例中,使用了简化的 `Configure<...>`方法. + +### 获取选项值 + +在你需要获得一个选项值时,将 `IOptions` 服务[注入](Dependency-Injection.md)到你的类中,使用它的 `.Value` 属性得到值. +例: + +````csharp +public class MyService : ITransientDependency +{ + private readonly MyOptions _options; + + public MyService(IOptions options) + { + _options = options.Value; //Notice the options.Value usage! + } + + public void DoIt() + { + var v1 = _options.Value1; + var v2 = _options.Value2; + } +} +```` + +阅读[微软文档](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/options)了解选择模式的所有细节. + +## 预配置 + +选项模式的限制之一是你只能解析(注入) `IOptions ` 并在依赖注入配置完成(即所有模块的`ConfigureServices`方法完成)后获取选项值. + +如果你正在开发一个模块,可能需要让开发者能够设置一些选项,并在依赖注入注册阶段使用这些选项. 你可能需要根据选项值配置其他服务或更改依赖注入的注册代码. + +对于此类情况,ABP为 `IServiceCollection` 引入了 `PreConfigure` 和 `ExecutePreConfiguredActions` 扩展方法. 该模式的工作原理如下所述。 + +1. 你的模块中定义计划选项类. 例: + +````csharp +public class MyPreOptions +{ + public bool MyValue { get; set; } +} +```` + +然后任何依赖于模块的模块类都可以在其 `PreConfigureServices` 方法中使用 `PreConfigure` 方法. +例: + +````csharp +public override void PreConfigureServices(ServiceConfigurationContext context) +{ + PreConfigure(options => + { + options.MyValue = true; + }); +} +```` + +> 多个模块可以预配置选项,并根据它们的依赖顺序覆盖选项值. + +最后在你的模块 `ConfigureServices` 方法中执行 `ExecutePreConfiguredActions` 方法来获得配置的选项值. +例: + +````csharp +public override void ConfigureServices(ServiceConfigurationContext context) +{ + var options = context.Services.ExecutePreConfiguredActions(); + if (options.MyValue) + { + //... + } +} +```` \ No newline at end of file diff --git a/docs/zh-Hans/docs-nav.json b/docs/zh-Hans/docs-nav.json index 3cd3b998da..44856b34ed 100644 --- a/docs/zh-Hans/docs-nav.json +++ b/docs/zh-Hans/docs-nav.json @@ -52,6 +52,10 @@ "text": "配置", "path": "Configuration.md" }, + { + "text": "选项", + "path": "Options.md" + }, { "text": "依赖注入", "path": "Dependency-Injection.md",