diff --git a/docs/zh-Hans/Best-Practices/Data-Transfer-Objects.md b/docs/zh-Hans/Best-Practices/Data-Transfer-Objects.md index 2d25ce7f41..f38dc07084 100644 --- a/docs/zh-Hans/Best-Practices/Data-Transfer-Objects.md +++ b/docs/zh-Hans/Best-Practices/Data-Transfer-Objects.md @@ -1,7 +1,7 @@ -## Data Transfer Objects Best Practices & Conventions +## 数据传输对象最佳实践&约定 -* **Do** define DTOs in the **application contracts** package. -* **Do** inherit from the pre-built **base DTO classes** where possible and necessary (like `EntityDto`, `CreationAuditedEntityDto`, `AuditedEntityDto`, `FullAuditedEntityDto` and so on). -* **Do** define DTO members with **public getter and setter**. -* **Do** use **data annotations** for **validation** on the properties of DTOs those are inputs of the service. -* **Do** not add any **logic** into DTOs except implementing `IValidatableObject` when necessary. \ No newline at end of file +* **推荐** 在 **application.contracts** 层中定义DTO. +* **推荐** 在可能和必要的情况下从预构建的 **基础DTO类** 继承 (如 `EntityDto`, `CreationAuditedEntityDto`, `AuditedEntityDto`, `FullAuditedEntityDto` 等). +* **推荐** 定义 **public getter 和 setter** 的DTO成员 . +* **推荐** 使用 **data annotations** **验证** service输入DTO的属性. +* **不推荐** 在DTO中添加任何 **逻辑**, 在必要的时候可以实现 `IValidatableObject` 接口. \ No newline at end of file diff --git a/docs/zh-Hans/Best-Practices/Entity-Framework-Core-Integration.md b/docs/zh-Hans/Best-Practices/Entity-Framework-Core-Integration.md index f150bd6f66..4e74c7bb46 100644 --- a/docs/zh-Hans/Best-Practices/Entity-Framework-Core-Integration.md +++ b/docs/zh-Hans/Best-Practices/Entity-Framework-Core-Integration.md @@ -1,16 +1,16 @@ -## Entity Framework Core Integration Best Practices +## Entity Framework Core 集成最佳实践 -> See [Entity Framework Core Integration document](../Entity-Framework-Core.md) for the basics of the EF Core integration. +> 有关EF Core 集成的基础知识,请参阅[Entity Framework Core 集成文档](../Entity-Framework-Core.md). -- **Do** define a separated `DbContext` interface and class for each module. -- **Do not** rely on lazy loading on the application development. -- **Do not** enable lazy loading for the `DbContext`. +- **推荐** 为每个模块定义单独的 `DbContext` 接口和类. +- **不推荐** 在应用程序开发中使用延迟加载. +- **不推荐** 为 `DbContext` 启用延迟加载. ### DbContext Interface -- **Do** define an **interface** for the `DbContext` that inherits from `IEfCoreDbContext`. -- **Do** add a `ConnectionStringName` **attribute** to the `DbContext` interface. -- **Do** add `DbSet` **properties** to the `DbContext` interface for only aggregate roots. Example: +- **推荐** 继承自`IEfCoreDbContext` 的 `DbContext` 定义一个相应的 **interface**. +- **推荐** 添加 `ConnectionStringName` **attribute** 到 `DbContext` 接口. +- **推荐** 将 `DbSet` **properties** 添加到 `DbContext` 接口中,注意: 仅适用于聚合根. 例如: ````C# [ConnectionStringName("AbpIdentity")] @@ -23,9 +23,9 @@ public interface IIdentityDbContext : IEfCoreDbContext ### DbContext class -* **Do** inherit the `DbContext` from the `AbpDbContext` class. -* **Do** add a `ConnectionStringName` attribute to the `DbContext` class. -* **Do** implement the corresponding `interface` for the `DbContext` class. Example: +* **推荐** `DbContext` 继承自 `AbpDbContext` 类. +* **推荐** 添加 `ConnectionStringName` **attribute** 到 `DbContext` 类. +* **推荐** 实现 `DbContext` 类实现其相应的接口. 例如: ````C# [ConnectionStringName("AbpIdentity")] @@ -44,21 +44,21 @@ public class IdentityDbContext : AbpDbContext, IIdentityDbCon } ```` -### Table Prefix and Schema +### 表前缀与架构 -- **Do** add static `TablePrefix` and `Schema` **properties** to the `DbContext` class. Set default value from a constant. Example: +- **推荐** 添加静态 **properties** `TablePrefix` 与 `Schema` 到 `DbContext` 类. 使用常量为其设置一个默认值. 例如: ````C# public static string TablePrefix { get; set; } = AbpIdentityConsts.DefaultDbTablePrefix; public static string Schema { get; set; } = AbpIdentityConsts.DefaultDbSchema; ```` - - **Do** always use a short `TablePrefix` value for a module to create **unique table names** in a shared database. `Abp` table prefix is reserved for ABP core modules. - - **Do** set `Schema` to `null` as default. + - **推荐** 总是使用简短的 `TablePrefix` 值为模块在共享数据库中创建 **unique table names**. `Abp` 前缀是为ABP Core模块保留的. + - **推荐** `Schema` 默认赋值为 `null`. ### Model Mapping -- **Do** explicitly **configure all entities** by overriding the `OnModelCreating` method of the `DbContext`. Example: +- **Do** 重写 `DbContext` 的 `OnModelCreating` 方法显式 **配置所有实体**. 例如: ````C# protected override void OnModelCreating(ModelBuilder builder) @@ -73,7 +73,7 @@ protected override void OnModelCreating(ModelBuilder builder) } ```` -- **Do not** configure model directly in the `OnModelCreating` method. Instead, create an **extension method** for `ModelBuilder`. Use Configure*ModuleName* as the method name. Example: +- **不推荐** 直接在 `OnModelCreating` 方法中配置model,而是为 `ModelBuilder` 定义一个 **扩展方法**. 使用Configure*ModuleName*作为方法名称. 例如: ````C# public static class IdentityDbContextModelBuilderExtensions @@ -89,7 +89,7 @@ public static class IdentityDbContextModelBuilderExtensions builder.Entity(b => { - b.ToTable(options.TablePrefix + "Users", options.Schema); + b.ToTable(options.TablePrefix + "Users", options.Schema); //code omitted for brevity }); @@ -97,14 +97,13 @@ public static class IdentityDbContextModelBuilderExtensions { b.ToTable(options.TablePrefix + "UserClaims", options.Schema); //code omitted for brevity - }); - + }); //code omitted for brevity } } ```` -* **Do** create a **configuration options** class by inheriting from the `ModelBuilderConfigurationOptions`. Example: +* **推荐** 通过继承 `ModelBuilderConfigurationOptions` 来创建 **configuration Options** 类. 例如: ````C# public class IdentityModelBuilderConfigurationOptions : ModelBuilderConfigurationOptions @@ -116,9 +115,9 @@ public class IdentityModelBuilderConfigurationOptions : ModelBuilderConfiguratio } ```` -### Repository Implementation +### 仓储实现 -- **Do** **inherit** the repository from the `EfCoreRepository` class and implement the corresponding repository interface. Example: +- **推荐** 从 `EfCoreRepository` 类 **继承** 仓储并实现相应的仓储接口. 例如: ````C# public class EfCoreIdentityUserRepository @@ -132,12 +131,12 @@ public class EfCoreIdentityUserRepository } ```` -* **Do** use the `DbContext` interface as the generic parameter, not the class. -* **Do** pass the `cancellationToken` to EF Core using the `GetCancellationToken` helper method. Example: +* **推荐** 使用 `DbContext` 接口而不是类来作为泛型参数. +* **推荐** 使用 `GetCancellationToken` 帮助方法将 `cancellationToken` 传递给EF Core. 例如: ````C# public virtual async Task FindByNormalizedUserNameAsync( - string normalizedUserName, + string normalizedUserName, bool includeDetails = true, CancellationToken cancellationToken = default) { @@ -150,9 +149,9 @@ public virtual async Task FindByNormalizedUserNameAsync( } ```` -`GetCancellationToken` fallbacks to the `ICancellationTokenProvider.Token` to obtain the cancellation token if it is not provided by the caller code. +如果调用者代码中未提供取消令牌,则 `GetCancellationToken` 会从`ICancellationTokenProvider.Token` 获取取消令牌. -- **Do** create a `IncludeDetails` **extension method** for the `IQueryable` for each aggregate root which has **sub collections**. Example: +- **推荐** 为具有 **子集合** 的聚合根创建 `IQueryable` 返回类型的 `IncludeDetails` **扩展方法**. 例如: ````C# public static IQueryable IncludeDetails( @@ -172,9 +171,9 @@ public static IQueryable IncludeDetails( } ```` -* **Do** use the `IncludeDetails` extension method in the repository methods just like used in the example code above (see FindByNormalizedUserNameAsync). +* **推荐** 推荐在仓储其他方法中使用 `IncludeDetails` 扩展方法, 就像上面的示例代码一样(参阅 FindByNormalizedUserNameAsync). -- **Do** override `IncludeDetails` method of the repository for aggregates root which have **sub collections**. Example: +- **推荐** 覆盖具有 **子集合** 的聚合根仓储中的`IncludeDetails` 方法. 例如: ````C# protected override IQueryable IncludeDetails(IQueryable queryable) @@ -185,9 +184,9 @@ protected override IQueryable IncludeDetails(IQueryable` method. -- **Do** add implemented repositories to the options for the `AddAbpDbContext` method. Example: +- **推荐** 为Entity Framework Core集成包定义一个Module类. +- **推荐** 使用 `AddAbpDbContext` 方法将 `DbContext` 添加到 `IServiceCollection`. +- **推荐** 将已实现的仓储添加到 `AddAbpDbContext` 方法的options中. 例如: ````C# [DependsOn( diff --git a/docs/zh-Hans/Best-Practices/Index.md b/docs/zh-Hans/Best-Practices/Index.md index 93d6409909..c99dec8604 100644 --- a/docs/zh-Hans/Best-Practices/Index.md +++ b/docs/zh-Hans/Best-Practices/Index.md @@ -1,27 +1,26 @@ -## Module Development Best Practices & Conventions +## 模块开发最佳实践 & 约定 -### Introduction +### 介绍 -This document describes the **best practices** and **conventions** for those who want to develop **modules** that satisfy the following specifications: +这篇文档描述了想要满足以下规范的**模块**的**最佳实践**与**约定**: -* Develop modules that conform to the **Domain Driven Design** patterns & best practices. -* Develop modules with **DBMS and ORM independence**. -* Develop modules that can be used as a **remote service / microservice** as well as being compatible with a **monolithic** application. +* 开发应用**领域驱动设计**模式的最佳实践的模块. +* 开发 **DBMS 与 ORM 独立** 的模块. +* 开发可用作 **远程服务 / 微服务** 的模块, 并可以集成到 **单体** 应用程序中. -Also, this guide is mostly usable for general **application development**. +本指南主要用于 **应用程序** 开发. -### Guides - -* Overall - * [Module Architecture](Module-Architecture.md) -* Domain Layer - * [Entities](Entities.md) - * [Repositories](Repositories.md) - * [Domain Services](Domain-Services.md) -* Application Layer - * [Application Services](Application-Services.md) - * [Data Transfer Objects](Data-Transfer-Objects.md) -* Data Access - * [Entity Framework Core Integration](Entity-Framework-Core-Integration.md) - * [MongoDB Integration](MongoDB-Integration.md) +### 指南 +* 总体 + * [模块架构](Module-Architecture.md) +* 领域层 + * [实体](Entities.md) + * [仓储](Repositories.md) + * [领域服务](Domain-Services.md) +* 应用程序层 + * [应用程序服务](Application-Services.md) + * [数据传输对象](Data-Transfer-Objects.md) +* 数据访问 + * [Entity Framework Core 集成](Entity-Framework-Core-Integration.md) + * [MongoDB 集成](MongoDB-Integration.md) \ No newline at end of file diff --git a/docs/zh-Hans/Blog-Posts/2018-09-24-Announcement/Post.md b/docs/zh-Hans/Blog-Posts/2018-09-24-Announcement/Post.md index 437ee87387..85dcebc76e 100644 --- a/docs/zh-Hans/Blog-Posts/2018-09-24-Announcement/Post.md +++ b/docs/zh-Hans/Blog-Posts/2018-09-24-Announcement/Post.md @@ -1,76 +1,97 @@ -### Introduction -For a while, we were working to design a new major version of the ASP.NET Boilerplate framework. Now, it’s time to share it with the community. We are too excited and we believe that you are too. +# ABP vNext介绍 -#### Naming -The name of the framework remains same, except we will call it only as “ABP” instead of “ASP.NET Boilerplate”. Because, the “boilerplate” word leads to misunderstandings and does not reflect that it is a framework (instead of some boilerplate code). We continue to use the “ABP” name since it’s the successor of the current ASP.NET Boilerplate framework, except it’s a rewrite. +## 介绍 -### How To Start +过去的一段时间,我们正在设计一个新的主要版本的ASP.NET Boilerplate框架.现在,是时候与社区分享了.我们非常兴奋,相信你也是. -We have created a startup template. You can just create a new project from https://abp.io/Templates and start your development. For more information, visit [abp.io](https://abp.io). -### Why A Complete Rewrite? -Why we spent our valuable time to rewrite it from scratch instead of incremental changes and improvements. Why? +## 命名 -#### ASP.NET Core -When we first introduced the ABP framework, it was 2013 (5 years ago)! There was no .Net Core & ASP.NET Core and there was no Angular2+. They were all developed from scratch after ABP’s release. +框架的名称保持不变,除了我们将其仅称为“ABP”而不是“ASP.NET Boilerplate”.因为,“Boilerplate(样板)”会导致误解,并没反映出它是一个框架(而不是样板代码).我们继续使用“ABP”名称,因为它是当前ASP.NET Boilerplate框架的继承者,除了它是完全重写的. -ASP.NET Core introduced many built-in solutions (extension libraries) for dependency injection, logging, caching, localization, configuration and so on. These are actually independent from the ASP.NET Core and usable for any type of application. -We were using 3rd-party libraries and our own solutions for these requirements. We immediately integrated to ASP.NET Core features once they were released. But that was an integration, instead of building the ABP framework on top of these extension libraries. For instance, current ASP.NET Boilerplate still depends on Castle Windsor for dependency injection even it’s integrated to ASP.NET Core’s DI system. +## 如何开始 -We wanted to depend on these new extension libraries instead of 3rd-party and custom solutions and this changes fundamental structures of the framework. +我们已经创建了一个启动模板.你可以从[abp.io/Templates](https://abp.io/Templates)创建一个新项目并开始开发.欲了解更多信息,请访问[abp.io](https://abp.io/). -#### Self Modularization -While current ABP is already modular itself and consists of dozens of packages, we still wanted to split the functionalities to more fine grained nuget packages. -For example, the core Abp package contains many features like DDD classes, auditing, authorization, background jobs, event bus, json serialization, localization, multi-tenancy, threading, timing and so on… We wanted to split all these functionality into their own packages and make them optional. +## 为什么要完全重写? -#### Dropping Support for Legacy Technologies -Yes, the new ABP framework will not support ASP.NET MVC 5.x, Entity Framework 6.x and other legacy technologies. +为什么我们花了宝贵的时间从头开始重写它而不是增量更改和改进.为什么? -These legacy technologies are maintained by Microsoft but no new feature is being added. So, if you are still using these technologies, you can continue with the current ASP.NET Boilerplate framework. We will continue to maintain it, fix bugs and will add new features. +### ASP.NET Core -Dropping support for these legacy libraries will improve our development speed (since we currently duplicate our work for some features) and concentrate on the .Net Core & ASP.NET Core. +当我们第一次介绍ABP框架时,那是2013年(5年前)!那时候没有.Net Core和ASP.NET Core,也没有Angular2 +.ABP发布后,它们都是从头开发的. -The new ABP framework will be based on .net standard. So, it’s still possible to use full .net framework or .net core with the new ABP framework. +ASP.NET Core引入了许多内置解决方案(扩展库),用于依赖注入,日志记录,缓存,本地化,配置等.它们实际上独立于ASP.NET Core,可用于任何类型的应用程序. -### Goals -We have learnt much from the community and had experience of developing the current ASP.NET Boilerplate framework. New ABP framework has significant and exciting goals. +我们之前使用第三方库和我们自己的解决方案来满足这些要求.在它们发布后我们立即集成到ASP.NET Core功能中.但这是集成,而不是在这些扩展库之上构建ABP框架.例如,当前的ASP.NET Boilerplate依赖于Castle Windsor进行依赖注入,即使它已集成到ASP.NET Core的DI系统中. -#### Application Modularity -The first goal is to provide a good infrastructure to develop application modules. We think a module as a set of application features with its own database, its own entities, services, APIs, UI pages, components and so on. +我们希望依赖这些新的扩展库而不是第三方和自定义解决方案,这会改变框架的基本结构. -We will create a module market which will contain free & paid application modules. You will also be able to publish your own modules on the market. More information will be coming soon. +### 自身模块化 -#### Microservices -We are designing the new ABP framework to be ready to develop microservices and communicate them to each other. +虽然目前的ABP本身已经是模块化的,并且包含许多包,但我们仍然希望将功能分解为更细粒度的nuget包. -We are designing application modules so that they can be separately deployable as microservices or they can be embedded into a monolithic application. +例如,核心Abp包包含许多功能,如DDD类,审计,授权,后台作业,事件总线,json序列化,本地化,多租户,线程,时间等......我们希望将所有这些功能拆分到各自的包中并使它们可选. -We are creating a [specification / best practice documentation](https://github.com/abpframework/abp/blob/master/docs/Best-Practices/Index.md) for that. +### 放弃对传统技术的支持 -#### Theming and UI Composition -The new ABP framework will provide a theming infrastructure based on the latest Twitter Bootstrap 4.x. We developed a basic theme that only uses the plain Bootstrap 4.x styling. It’s free and open source. We are also developing premium & paid themes. +是的,新的ABP框架将不支持ASP.NET MVC 5.x,Entity Framework 6.x和其他传统技术. -UI Composition is one of the main goals. For this purpose, theme system will provide menus, toolbars and other extensible areas to allow other modules to contribute. +这些传统技术会由Microsoft维护,但不会再添加任何新功能.因此,如果你仍在使用这些技术,则可以继续使用当前的ASP.NET Boilerplate框架.我们将继续维护它,修复错误并添加新功能. -#### ORM/Database Independence & MongoDB Integration -While current ASP.NET Boilerplate framework has implemented the repository pattern for ORM/Database independence, identity integration module (Abp.Zero* packages) has never worked well with ORMs other than EF. +删除对这些传统库的支持将提高我们的开发速度(因为我们目前正在复制我们的某些功能的工作)并专注于.Net Core和ASP.NET Core. -With the new ABP framework, the ultimate goal is completely abstract underlying data store system and develop modules EF Core independent. +新的ABP框架将基于.net standard.因此,仍然可以在新的ABP框架中使用完整的.net framework或.net core. -We embrace the MongoDB as a first-class citizen database and designing entities and repositories without any relational database or ORM assumption. -#### More Extensibility -New ABP framework provides more extensibility points and overriding capabilities for built-in services. +## 目标 -### Some Features -In this section, I will introduce some exciting new features of the new ABP framework. +我们从社区学到了很多东西,并且有开发当前ASP.NET Boilerplate框架的经验.新的ABP框架有着重要而令人兴奋的目标. -#### Bootstrap Tag Helpers -We are creating a library to wrap twitter bootstrap 4.x elements/components into tag helpers. Example: +### 应用程序模块化 -````C# +第一个目标是提供良好的基础设施来开发应用程序模块.我们将模块视为一组应用程序功能,具有自己的数据库,自己的实体,服务,API,UI页面,组件等. + +我们将创建一个包含免费和付费应用程序模块的模块市场.你还可以在市场上发布自己的模块.更多信息即将推出. + +### 微服务 + +我们正在设计新的ABP框架可方便的开发微服务并使它们相互通信. + +我们正在设计应用程序模块,以便它们可以作为微服务单独部署,或者可以嵌入到单个应用程序中. + +我们正在为此创建[规范/最佳实践文档](https://github.com/abpframework/abp/blob/master/docs/Best-Practices/Index.md) + +### 主题和UI组合 + +新的ABP框架将基于最新的Twitter Bootstrap 4.x提供主题基础设施.我们开发了一个仅使用普通Bootstrap 4.x样式的基本主题.它是免费和开源的.我们还在开发高级和付费主题. + +UI组合是主要目标之一.为此,主题系统将提供菜单,工具栏和其他可扩展区域,以允许其他模块交互(contribute). + +### ORM / 数据库无关性和MongoDB集成 + +虽然当前的ASP.NET Boilerplate框架已经实现了ORM /数据库无关的存储库(Repository)模式,但身份集成模块(以Abp.Zero*命名的包)与EF以外的ORM一直运行的不太好. + +使用新的ABP框架,最终目标是完全抽象的底层数据存储系统和开发与EF Core无关的模块. + +我们将MongoDB作为第一级别的数据库,并在没有任何关系数据库或ORM假设的情况下设计实体和存储库. + +### 更多可扩展性 + +新的ABP框架为内置服务提供了更多的扩展点和覆盖的能力. + + +## 一些功能 + +在本节中,我将介绍新ABP框架的一些令人兴奋的新功能. + +### Bootstrap Tag Helpers + +我们正在创建一个库将twitter bootstrap 4.x元素/组件包装到tag helper中.例: + +~~~ html @@ -85,90 +106,104 @@ We are creating a library to wrap twitter bootstrap 4.x elements/components into Go somewhere → -```` +~~~ -"abp-*" tags are ABP tag helpers to simplify writing HTML for Bootstrap 4.x. +“abp-*”标签是ABP tag helper,用于简化为Bootstrap 4.x编写HTML. -#### Dynamic Forms -Dynamic forms tag helper allows you to dynamically create forms for given model classes. Example: +### 动态表单 -````C# +动态表单tag helper允许你为给定的模型类动态地创建表单.例: + +~~~ html -```` +~~~ -Output: +输出: ![dynamic-forms](dynamic-forms.png) -It currently supports most used input types and more in the development. +目前支持最常用的输入类型. 更多类型正在开发中. + +### 虚拟文件系统 -#### Virtual File System -Virtual File System allows you to embed views, pages, components, javascript, css, json and other type of files into your module assembly/package (dll) and use your assembly in any application. Your virtual files behave just like physical files in the containing application with complete ASP.NET Core Integration. +虚拟文件系统允许你将视图,页面,组件,javascript,css,json和其他类型的文件嵌入到模块程序集/包(dll)中,并在任何应用程序中使用.在应用程序中你的虚拟文件就像物理文件一样, 完全的集成在ASP.NET Core中. -Read more [about the Virtual File System](https://medium.com/volosoft/designing-modularity-on-asp-net-core-virtual-file-system-2dd2cc2078bd) and see [its documentation](https://github.com/abpframework/abp/blob/master/docs/Virtual-File-System.md). +更多信息请参阅[关于虚拟文件系统](https://medium.com/volosoft/designing-modularity-on-asp-net-core-virtual-file-system-2dd2cc2078bd)和[相关文档](https://github.com/abpframework/abp/blob/master/docs/Virtual-File-System.md). -#### Dynamic Bundling & Minification System -Dynamic bundling & minification system works on the virtual file system and allows modules to create, modify and contribute to bundles in a modular, dynamic and powerful way. An example: +### 动态捆绑和压缩系统 -````C# +动态捆绑和压缩系统运行在虚拟文件系统上,并且允许模块以模块化,动态和强大的方式创建,修改和交互捆绑包.一个例子: + +~~~ html -```` +~~~ + +这段代码通过包含bootstrap(及其依赖项,如果有)和另外两个css文件来动态创建一个新的样式包.这些文件在生产环境中捆绑和压缩,但将在开发环境中单独添加. + +有关更多信息,请参阅[文档](https://github.com/abpframework/abp/blob/master/docs/AspNetCore/Bundling-Minification.md) + +### 分布式事件总线(Distributed Event Bus) + +在当前的ABP中,有一个IEventBus服务来触发和处理应用程序内的事件.除了这个本地事件总线,我们还创建了一个分布式事件总线抽象(和RabbitMQ集成)来实现分布式消息传递模式. + +### 动态C# HTTP客户端代理 + +ABP已经为所有HTTP API创建动态JavaScript代理.该功能也存在于新的ABP框架中.此外,它现在可以为所有HTTP API创建动态C#代理. + + + +## 未来的工作 + +上面提到的所有东西都已经开发出来了.但是,我们还有一些想法尚未着手. + +### 单页应用程序(Single Page Applications) -This code creates a new style bundle on the fly by including bootstrap (and its dependencies if there are) and two more css files. These files are bundled & minified on production environment, but will be added individually on the development environment. +我们在设计新框架时考虑到了SPA这一点.但是,我们还没有尝试过任何SPA框架,我们还没有为它准备一个启动模板. -See [the documentation](https://github.com/abpframework/abp/blob/master/docs/AspNetCore/Bundling-Minification.md) for more. +## ASP.NET Boilerplate(当前版本)和ASP.NET Zero会如何? -#### Distributed Event Bus -In current ABP, there is an IEventBus service to trigger and handle events inside the application. In addition to this local event bus, we are creating a distributed event bus abstraction (and RabbitMQ integration) to implement distributed messaging patterns. +我们有专门的开发和支持团队积极致力于ASP.NET Boilerplate和ASP.NET Zero项目.这些项目有一个很大的社区,我们也从社区中获得了贡献. -#### Dynamic C# HTTP Client Proxies -ABP was already creating dynamic javascript proxies for all HTTP APIs. This feature does also exists in the new ABP framework. In addition, it now can create dynamic C# proxies for all HTTP APIs. +我们将在很长一段时间内继续为这些项目进行改进,添加新功能和修复错误.因此,你可以安全地继续使用它们. -### Future Works -All the stuffs mentioned above are already in development. However, we haven’t started some concepts yet. +## 新的ABP可用在生产环境吗? -#### Single Page Applications -We designed the new framework SPAs in mind. However, we haven’t tried it with any SPA framework and we haven’t prepared a startup template for it yet. +还没有.我们的第一个目标是使基本功能稳定,然后逐步完成其他功能. -### What About ASP.NET Boilerplate (Current Version) and ASP.NET Zero? +我们会经常发布新版本,每个新版本都可能会有重大变化.我们将在发行说明中写下重大更改. -We have dedicated development & support teams actively working on the [ASP.NET Boilerplate](https://aspnetboilerplate.com/) and [ASP.NET Zero](https://aspnetzero.com/) projects. These projects have a big community and we are also getting contributions from the community. +我们目前将其定义为实验性质.但我们希望这不会持续很长时间.我们无法确定一个准确的日期,请关注我们的发布. -We will continue to make enhancements, add new features and fix bugs for these projects for a long time. So, you can safely continue to use them. +## 包和版本控制 -### Is New ABP Production Ready? -No, not yet. Our first goal is to make fundamental features stable then incrementally complete other features. +新的ABP框架将从v1.0开始,而不是遵循当前的ASP.NET Boilerplate版本, 以反映它是一个重写的事实. -We will frequently release new versions and every new version will probably have breaking changes. We will write breaking changes on the release notes. +我们会经常发布它.你可以期待许多重大变化,直到v1.0.从v1.0开始,我们将注意不要在1.x版本中引入重大更改. -We currently define it experimental. But we hope that this will not continue for a long time. We can not declare a date yet, follow our releases. +当前ABP的包名称以Abp前缀开头(如Abp.EntityFrameworkCore).新的包名称以Volo.Abp前缀开头(如Volo.Abp.EntityFrameworkCore). -### Packages & Versioning -New ABP framework will start with v1.0 instead of following current ASP.NET Boilerplate's version to reflect the fact that it’s a rewrite. +## 我应该用哪一个? -We will frequently [release](https://github.com/abpframework/abp/releases) it. You can expect many breaking changes until v1.0. Starting with the v1.0, we will pay attention to not introduce breaking changes in 1.x releases. +如果你正在创建一个新项目,我们建议你继续使用当前的ASP.NET Boilerplate框架,因为它非常成熟,功能丰富且可用于生产环境. -Current ABP’s package names start with [Abp](https://www.nuget.org/packages/Abp) prefix (like Abp.EntityFrameworkCore). New package names start with [Volo.Abp](https://www.nuget.org/packages/Volo.Abp.Core) prefix (like Volo.Abp.EntityFrameworkCore). +如果你愿意接受重大变化并希望体验新框架,那么你可以从新的ABP开始.我们不建议在临近截止日期和在短期内上线的项目上使用它. -### Which One Should I Start With? -If you are creating a new project, we suggest to continue with the current ASP.NET Boilerplate framework since it’s very mature, feature rich and production ready. +## 贡献 -If you are open to breaking changes and want to have experience on the new framework, you can start with the new ABP. We don’t suggest it yet for projects with close deadlines and go to the production in a short term. +就像当前的ABP框架一样,你可为新框架做出贡献. -### Contribution -Just like the current ABP framework, the new framework is available for your contribution. +* 你可以发送代码或文档的拉取请求. +* 你可以撰写关于它的博客文章或教程. +* 你可以尝试并分享你的经验. +* 你可以提出改进和功能请求. +* 你可以报告错误和其他问题. -* You can send pull requests for code or documentation. -* You can write blog posts or tutorials about it. -* You can try it and share your experiences. -* You can create enhancement and feature requests. -* You can report bugs and other issues. +## 联系/链接 -### Communication / Links -* **Official web site**: [abp.io](https://abp.io) -* **Github**: [github.com/abpframework](https://github.com/abpframework) -* **Twitter**: [@abpframework](https://twitter.com/abpframework) \ No newline at end of file +* 官方网站:[abp.io](https://abp.io/) +* Github:[github.com/abpframework](https://github.com/abpframework) +* Twitter:[@abpframework](https://twitter.com/abpframework) diff --git a/docs/zh-Hans/Dependency-Injection.md b/docs/zh-Hans/Dependency-Injection.md index a001d52ec9..f9c11aeb74 100644 --- a/docs/zh-Hans/Dependency-Injection.md +++ b/docs/zh-Hans/Dependency-Injection.md @@ -1,24 +1,24 @@ -## Dependency Injection +## 依赖注入 -ABP's Dependency Injection system is developed based on Microsoft's [dependency injection extension](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection) library (Microsoft.Extensions.DependencyInjection nuget package). So, it's documentation is valid in ABP too. +ABP的依赖注入系统是基于Microsoft的[依赖注入扩展](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection)库(Microsoft.Extensions.DependencyInjection nuget包)开发的.因此,它的文档在ABP中也是有效的. -### Modularity +### 模块化 -Since ABP is a modular framework, every module defines it's own services and registers via dependency injection in it's own seperate [module class](Module-Development-Basics.md). Example: +由于ABP是一个模块化框架,因此每个模块都通过依赖注入定义它自己的服务并通过它自己的单独[模块类](Module-Development-Basics.md)进行注册.例: ````C# public class BlogModule : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) { - //register dependencies here + //在此处注入依赖项 } } ```` -### Conventional Registration +### 依照约定的注册 -ABP introduces conventional service registration. You need not do anything to register a service by convention. It's automatically done. If you want to disable it, you can set `SkipAutoServiceRegistration` to `true` by overriding the `PreConfigureServices` method. +ABP引入了依照约定的服务注册.依照约定你无需做任何事,它会自动完成.如果要禁用它,你可以通过重写`PreConfigureServices`方法,设置`SkipAutoServiceRegistration`为`true`. ````C# public class BlogModule : AbpModule @@ -30,7 +30,7 @@ public class BlogModule : AbpModule } ```` -Once you skip auto registration, you should manually register your services. In that case, ``AddAssemblyOf`` extension method can help you to register all your services by convention. Example: +一旦跳过自动注册,你应该手动注册你的服务.在这种情况下,`AddAssemblyOf`扩展方法可以帮助你依照约定注册所有服务.例: ````c# public class BlogModule : AbpModule @@ -47,21 +47,21 @@ public class BlogModule : AbpModule } ```` -The section below explains the conventions and configurations. +以下部分解释了约定和配置. -#### Inherently Registered Types +#### 固有的注册类型 -Some specific types are registered to dependency injection by default. Examples: +一些特定类型会默认注册到依赖注入.例子: -* Module classes are registered as singleton. -* MVC controllers (inherit ``Controller`` or ``AbpController``) are registered as transient. -* MVC page models (inherit ``PageModel`` or ``AbpPageModel``) are registered as transient. -* MVC view components (inherit ``ViewComponent`` or ``AbpViewComponent``) are registered as transient. -* Application services (implement ``IApplicationService`` interface or inherit ``ApplicationService`` class) are registered as transient. -* Repositories (implement ``IRepository`` interface) are registered as transient. -* Domain services (implement ``IDomainService`` interface) are registered as transient. +* 模块类注册为singleton. +* MVC控制器(继承``Controller``或``AbpController``)被注册为transient. +* MVC页面模型(继承``PageModel``或``AbpPageModel``)被注册为transient. +* MVC视图组件(继承``ViewComponent``或``AbpViewComponent``)被注册为transient. +* 应用程序服务(实现``IApplicationService``接口或继承``ApplicationService``类)注册为transient. +* 存储库(实现``IRepository``接口)注册为transient. +* 域服务(实现``IDomainService``接口)注册为transient. -Example: +示例: ````C# public class BlogPostAppService : ApplicationService @@ -69,17 +69,17 @@ public class BlogPostAppService : ApplicationService } ```` -``BlogPostAppService`` is automatically registered with transient lifetime since it's derived from a known base class. +``BlogPostAppService`` 由于它是从已知的基类派生的,因此会自动注册transient. -#### Dependency Interfaces +#### 依赖接口 -If you implement these interfaces, your class is registered to dependency injection automatically: +如果实现这些接口,则会自动将类注册到依赖注入: -* ``ITransientDependency`` to register with transient lifetime. -* ``ISingletonDependency`` to register with singleton lifetime. -* ``IScopedDependency`` to register with scoped lifetime. +* ``ITransientDependency`` 注册为transient. +* ``ISingletonDependency`` 注册为singleton. +* ``IScopedDependency`` 注册为scoped. -Example: +示例: ````C# public class TaxCalculator : ITransientDependency @@ -87,17 +87,17 @@ public class TaxCalculator : ITransientDependency } ```` -``TaxCalculator`` is automatically registered with a transient lifetime since it implements ``ITransientDependency``. +``TaxCalculator``因为实现了``ITransientDependency``,所以它会自动注册为transient. -#### Dependency Attribute +#### Dependency 属性 -Another way of configuring a service for dependency injection is to use ``DependencyAttribute``. It has the following properties: +配置依赖注入服务的另一种方法是使用``DependencyAttribute``.它具有以下属性: -* ``Lifetime``: Lifetime of the registration: ``Singleton``, ``Transient`` or ``Scoped``. -* ``TryRegister``: Set ``true`` to register the service only it's not registered before. Uses TryAdd... extension methods of IServiceCollection. -* ``ReplaceServices``: Set ``true`` to replace services if they are already registered before. Uses Replace extension method of IServiceCollection. +* ``Lifetime``: 注册的生命周期:Singleton,Transient或Scoped. +* ``TryRegister``: 设置``true``则只注册以前未注册的服务.使用IServiceCollection的TryAdd ... 扩展方法. +* ``ReplaceServices``: 设置``true``则替换之前已经注册过的服务.使用IServiceCollection的Replace扩展方法. -Example: +示例: ````C# [Dependency(ServiceLifetime.Transient, ReplaceServices = true)] @@ -108,11 +108,11 @@ public class TaxCalculator ```` -``Dependency`` attribute has a higher priority than other dependency interfaces if it defines the ``Lifetime`` property. +``Dependency``如果定义``Lifetime``属性,则具有比其他依赖接口更高的优先级. -#### ExposeServices Attribute +#### ExposeServices 属性 -``ExposeServicesAttribute`` is used to control which services are provided by the related class. Example: +``ExposeServicesAttribute``用于控制相关类提供了什么服务.例: ````C# [ExposeServices(typeof(ITaxCalculator))] @@ -122,18 +122,18 @@ public class TaxCalculator: ICalculator, ITaxCalculator, ICanCalculate, ITransie } ```` -``TaxCalculator`` class only exposes ``ITaxCalculator`` interface. That means you can only inject ``ITaxCalculator``, but can not inject ``TaxCalculator`` or ``ICalculator`` in your application. +``TaxCalculator``类只公开``ITaxCalculator``接口.这意味着你只能注入``ITaxCalculator``,但不能注入``TaxCalculator``或``ICalculator``到你的应用程序中. -#### Exposed Services by Convention +#### 依照约定公开的服务 -If you do not specify which services to expose, ABP expose services by convention. So taking the ``TaxCalculator`` defined above: +如果你未指定要公开的服务,则ABP依照约定公开服务.以上面定义的``TaxCalculator``为例: -* The class itself is exposed by default. That means you can inject it by ``TaxCalculator`` class. -* Default interfaces are exposed by default. Default interfaces are determined by naming convention. In this example, ``ICalculator`` and ``ITaxCalculator`` are default interfaces of ``TaxCalculator``, but ``ICanCalculate`` is not. +* 默认情况下,类本身是公开的.这意味着你可以按``TaxCalculator``类注入它. +* 默认情况下,默认接口是公开的.默认接口是由命名约定确定.在这个例子中,``ICalculator``和``ITaxCalculator``是``TaxCalculator``的默认接口,但``ICanCalculate``不是. -#### Combining All Together +#### 组合到一起 -Combining attributes and interfaces is possible as long as it's meaningful. +只要有意义,就可以组合属性和接口. ````C# [Dependency(ReplaceServices = true)] @@ -144,31 +144,31 @@ public class TaxCalculator : ITaxCalculator, ITransientDependency } ```` -#### Manually Registering +#### 手动注册 -In some cases, you may need to register a service to the `IServiceCollection` manually, especially if you need to use custom factory methods or singleton instances. In that case, you can directly add services just as [Microsoft documentation](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection) describes. Example: +在某些情况下,你可能需要向``IServiceCollection``手动注册服务,尤其是在需要使用自定义工厂方法或singleton实例时.在这种情况下,你可以像[Microsoft文档](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection)描述的那样直接添加服务.例: ````C# public class BlogModule : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) { - //Register an instance as singleton + //注册一个singleton实例 context.Services.AddSingleton(new TaxCalculator(taxRatio: 0.18)); - //Register a factory method that resolves from IServiceProvider + //注册一个从IServiceProvider解析得来的工厂方法 context.Services.AddScoped(sp => sp.GetRequiredService()); } } ```` -### Injecting Dependencies +### 注入依赖关系 -There are three common ways of using a service that has already been registered. +使用已注册的服务有三种常用方法. -#### Contructor Injection +#### 构造方法注入 -This is the most common way of injecting a service into a class. For example: +这是将服务注入类的最常用方法.例如: ````C# public class TaxAppService : ApplicationService @@ -182,18 +182,18 @@ public class TaxAppService : ApplicationService public void DoSomething() { - //...use _taxCalculator... + //...使用 _taxCalculator... } } ```` -``TaxAppService`` gets ``ITaxCalculator`` in it's constructor. The dependency injection system automatically provides the requested service at runtime. +``TaxAppService``在构造方法中得到``ITaxCalculator``.依赖注入系统在运行时自动提供所请求的服务. -Constructor injection is preffered way of injecting dependencies to a class. In that way, the class can not be constructed unless all constructor-injected dependencies are provided. Thus, the class explicitly declares it's required services. +构造方法注入是将依赖项注入类的优先方式.这样,除非提供了所有构造方法注入的依赖项,否则无法构造类.因此,该类明确的声明了它必需的服务. -#### Property Injection +#### 属性注入 -Property injection is not supported by Microsoft Dependency Injection library. However, ABP can integrate with 3rd-party DI providers ([Autofac](https://autofac.org/), for example) to make property injection possible. Example: +Microsoft依赖注入库不支持属性注入.但是,ABP可以与第三方DI提供商(例如[Autofac](https://autofac.org/))集成,以实现属性注入.例: ````C# public class MyService : ITransientDependency @@ -207,24 +207,24 @@ public class MyService : ITransientDependency public void DoSomething() { - //...use Logger to write logs... + //...使用 Logger 写日志... } } ```` -For a property-injection dependency, you declare a public property with public setter. This allows the DI framework to set it after creating your class. +对于属性注入依赖项,使用公开的setter声明公共属性.这允许DI框架在创建类之后设置它. -Property injected dependencies are generally considered as **optional** dependencies. That means the service can properly work without them. ``Logger`` is such a dependency, ``MyService`` can continue to work without logging. +属性注入依赖项通常被视为可选依赖项.这意味着没有它们,服务也可以正常工作.``Logger``就是这样的依赖项,``MyService``可以继续工作而无需日志记录. -To make the dependency properly optional, we generally set a default/fallback value to the dependency. In this sample, NullLogger is used as fallback. Thus, ``MyService`` can work but does not write logs if DI framework or you don't set Logger property after creating ``MyService``. +为了使依赖项成为可选的,我们通常会为依赖项设置默认/后备(fallback)值.在此示例中,NullLogger用作后备.因此,如果DI框架或你在创建``MyService``后未设置Logger属性,则``MyService``依然可以工作但不写日志. -One restriction of property injection is that you cannot use the dependency in your constructor, since it's set after the object construction. +属性注入的一个限制是你不能在构造函数中使用依赖项,因为它是在对象构造之后设置的. -Property injection is also useful when you want to design a base class that has some common services injected by default. If you're going to use constructor injection, all derived classes should also inject depended services into their own constructors which makes development harder. However, be very careful using property injection for non-optional services as it makes it harder to clearly see the requirements of a class. +当你想要设计一个默认注入了一些公共服务的基类时,属性注入也很有用.如果你打算使用构造方法注入,那么所有派生类也应该将依赖的服务注入到它们自己的构造方法中,这使得开发更加困难.但是,对于非可选服务使用属性注入要非常小心,因为它使得类的要求难以清楚地看到. -#### Resolve Service from IServiceProvider +#### 从IServiceProvider解析服务 -You may want to resolve a service directly from ``IServiceProvider``. In that case, you can inject IServiceProvider into your class and use ``GetService`` method as shown below: +你可能希望直接从``IServiceProvider``解析服务.在这种情况下,你可以将``IServiceProvider``注入到你的类并使用``GetService``方法,如下所示: ````C# public class MyService : ITransientDependency @@ -244,17 +244,17 @@ public class MyService : ITransientDependency } ```` -#### Releasing/Disposing Services +#### 释放/处理(Releasing/Disposing)服务 -If you used a constructor or property injection, you don't need to be concerned about releasing the service's resources. However, if you have resolved a service from ``IServiceProvider``, you might, in some cases, need to take care about releasing the service resources. +如果你使用了构造函数或属性注入,则无需担心释放服务的资源.但是,如果你从``IServiceProvider``解析了服务,在某些情况下,你可能需要注意释放服务. -ASP.NET Core releases all services at the end of a current HTTP request, even if you directly resolved from ``IServiceProvider`` (assuming you injected IServiceProvider). But, there are several cases where you may want to release/dispose manually resolved services: +ASP.NET Core会在当前HTTP请求结束时释放所有服务,即使你直接从``IServiceProvider``解析了服务(假设你注入了IServiceProvider).但是,在某些情况下,你可能希望释放/处理手动解析的服务: -* Your code is executed outside of AspNet Core request and the executer hasn't handled the service scope. -* You only have a reference to the root service provider. -* You may want to immediately release & dispose services (for example, you may creating too many services with big memory usage and don't want to overuse memory). +* 你的代码在AspNet Core请求之外执行,执行者没有处理服务范围. +* 你只有对根服务提供者的引用. +* 你可能希望立即释放和处理服务(例如,你可能会创建太多具有大量内存占用且不想过度使用内存的服务). -In any case, you can use such a 'using' code block to safely and immediately release services: +在任何情况下,你都可以使用这样的`using`代码块来安全地立即释放服务: ````C# using (var scope = _serviceProvider.CreateScope()) @@ -264,8 +264,8 @@ using (var scope = _serviceProvider.CreateScope()) } ```` -Both services are released when the created scope is disposed (at the end of the using block). +两个服务在创建的scope被处理时(在using块的末尾)释放. -### See Also +### 请参阅 -* [ASP.NET Core Dependency Injection Best Practices, Tips & Tricks](https://medium.com/volosoft/asp-net-core-dependency-injection-best-practices-tips-tricks-c6e9c67f9d96) +* [ASP.NET Core依赖注入最佳实践,提示和技巧](https://medium.com/volosoft/asp-net-core-dependency-injection-best-practices-tips-tricks-c6e9c67f9d96) diff --git a/docs/zh-Hans/Entity-Framework-Core.md b/docs/zh-Hans/Entity-Framework-Core.md index 1d1a5d5f9d..4a06bb2610 100644 --- a/docs/zh-Hans/Entity-Framework-Core.md +++ b/docs/zh-Hans/Entity-Framework-Core.md @@ -1,16 +1,16 @@ -## Entity Framework Core Integration +## Entity Framework Core 集成 -This document explains how to integrate EF Core as an ORM provider to ABP based applications and how to configure it. +本文档介绍了如何将EF Core作为ORM提供程序集成到基于ABP的应用程序以及如何对其进行配置. -### Installation +### 安装 -`Volo.Abp.EntityFrameworkCore` is the main nuget package for the EF Core integration. Install it to your project (for a layered application, to your data/infrastructure layer): +`Volo.Abp.EntityFrameworkCore` 是EF Core 集成的主要nuget包. 将其安装到你的项目中(在分层应用程序中适用于 数据/基础设施层): -```` +``` Install-Package Volo.Abp.EntityFrameworkCore -```` +``` -Then add `AbpEntityFrameworkCoreModule` module dependency to your [module](Module-Development-Basics.md): +然后添加 `AbpEntityFrameworkCoreModule` 模块依赖项到 [module](Module-Development-Basics.cn.md)(项目中的Mudole类): ````C# using Volo.Abp.EntityFrameworkCore; @@ -26,9 +26,9 @@ namespace MyCompany.MyProject } ```` -### Creating DbContext +### 创建 DbContext -You can create your DbContext as you normally do. It should be derived from `AbpDbContext` as shown below: +你可以平常一样创建DbContext,它需要继承自 `AbpDbContext`. 如下所示: ````C# using Microsoft.EntityFrameworkCore; @@ -48,9 +48,9 @@ namespace MyCompany.MyProject } ```` -### Registering DbContext To Dependency Injection +### 将DbContext注册到依赖注入 -Use `AddAbpDbContext` method in your module to register your DbContext class for [dependency injection](Dependency-Injection.md) system. +在module中的ConfigureServices方法使用 `AddAbpDbContext` 在[依赖注入](Dependency-Injection.md)系统注册DbContext类. ````C# using Microsoft.Extensions.DependencyInjection; @@ -72,9 +72,9 @@ namespace MyCompany.MyProject } ```` -#### Add Default Repositories +#### 添加默认仓储 -ABP can automatically create repositories (TODO: link) for the entities in your DbContext. Just use `AddDefaultRepositories()` option on registration: +ABP会自动为DbContext中的实体创建仓储 (TODO: link). 需要在注册的时使用`AddDefaultRepositories()`: ````C# services.AddAbpDbContext(options => @@ -83,7 +83,8 @@ services.AddAbpDbContext(options => }); ```` -This will create a repository for each aggreate root entity (classes derived from AggregateRoot) by default. If you want to create repositories for other entities too, then set `includeAllEntities` to `true`: +默认情况下为每个聚合根实体(从聚合体派生的类)创建一个仓储. 如果想要为其他实体也创建仓储 +需要把`includeAllEntities` 设置为 `true`: ````C# services.AddAbpDbContext(options => @@ -92,16 +93,16 @@ services.AddAbpDbContext(options => }); ```` -Then you can inject and use `IRepository` or `IQueryableRepository` in your services. +然后你就可以在服务中注入和使用 `IRepository` 或 `IQueryableRepository`. -#### Add Custom Repositories +#### 添加自定义仓储 -TODO... +TODO ... -#### Set Base DbContext Class or Interface for Default Repositories +#### 为默认仓储设置Base DbContext类或接口 -... +TODO ... -#### Replace Other Repository +#### 替换其他仓储 -... \ No newline at end of file +TODO ... \ No newline at end of file diff --git a/docs/zh-Hans/Localization.md b/docs/zh-Hans/Localization.md index ba7bf04238..bcd12a0fc6 100644 --- a/docs/zh-Hans/Localization.md +++ b/docs/zh-Hans/Localization.md @@ -1,18 +1,18 @@ -## Localization +## 本地化 -ABP's localization system is seamlessly integrated to the `Microsoft.Extensions.Localization` package and compatible with the [Microsoft's localization documentation](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/localization). It adds some useful features and enhancements to make it easier to use in real life application scenarios. +ABP的本地化系统与`Microsoft.Extensions.Localization`无缝集成,并与[AspnetCore的本地化文档](https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/localization?view=aspnetcore-2.1)兼容. 它添加了一些实用功能和增强功能, 使其更易于在实际开发中应用. ### Volo.Abp.Localization Package -> This package is already installed by default with the startup template. So, most of the time, you don't need to install it manually. +> 启动模板默认已经安装了此nuget包, 所以在大多数情况下, 你不需要手动安装它. -Volo.Abp.Localization is the core package of the localization system. Install it to your project using the package manager console (PMC): +Volo.Abp.Localization是本地化系统的核心包. 使用程序包管理器控制台 (PMC) 将其安装到项目中: ``` Install-Package Volo.Abp.Localization ``` -Then you can add **AbpLocalizationModule** dependency to your module: +然后,您可以将 **AbpLocalizationModule** 依赖项添加到您的模块: ```c# using Volo.Abp.Modularity; @@ -28,9 +28,9 @@ namespace MyCompany.MyProject } ``` -#### Creating A Localization Resource +#### 创建本地化资源 -A localization resource is used to group related localization strings together and separate them from other localization strings of the application. A module generally defines its own localization resource. Localization resource is just a plain class. Example: +本地化资源用于将相关的本地化字符串组合在一起,并将它们与应用程序的其他本地化字符串分开.通常一个模块会定义自己的本地化资源. 本地化资源就是一个普通的类. 例如: ````C# public class TestResource @@ -38,7 +38,7 @@ public class TestResource } ```` -Then it should be added using `AbpLocalizationOptions` as shown below: +然后应该使用 `AbpLocalizationOptions` 添加如下所示: ````C# [DependsOn(typeof(AbpLocalizationModule))] @@ -52,7 +52,7 @@ public class MyModule : AbpModule }); context.Services.Configure(options => - { + { options.Resources .Add("en") .AddVirtualJson("/Localization/Resources/Test"); @@ -61,17 +61,17 @@ public class MyModule : AbpModule } ```` -In this example; +在这个例子中; -* Added a new localization resource with "en" (English) as the default culture. -* Used JSON files to store the localization strings. -* JSON files are embedded into the assembly using the [virtual file system](Virtual-File-System.md). +* 添加了一个新的本地化资源, 使用"en"(英语)作为默认的本地化. +* 用JSON文件存储本地化字符串. +* 使用[虚拟文件系统](Virtual-File-System.md) 将JSON文件嵌入到程序集中. -JSON files are located under "/Localization/Resources/Test" project folder as shown below: +JSON文件位于 "/Localization/Resources/Test" 项目文件夹下, 如下图所示: ![localization-resource-json-files](images/localization-resource-json-files.png) -A JSON localization file content is shown below: +本地化文件内容如下所示: ````json { @@ -82,12 +82,12 @@ A JSON localization file content is shown below: } ```` -* Every localization file should define the `culture` code for the file (like "en" or "en-US"). -* `texts` section just contains key-value collection of the localization strings (keys may have spaces too). +* 每个本地化文件都需要定义 `culture` (文化) 代码 (例如 "en" 或 "en-US"). +* `texts` 部分只包含本地化字符串的键值集合 (键也可能有空格). -##### Short Localization Resource Name +##### 简短的本地化资源名称 -Localization resources are also available in the client (JavaScript) side. So, setting a short name for the localization resource makes it easy to use localization texts. Example: +本地化资源也可以在客户端(JavaScript)使用. 因此, 为本地化资源设置一个简短的名称可以更方便的本地化文本. 例如: ````C# [LocalizationResourceName("Test")] @@ -96,11 +96,11 @@ public class TestResource } ```` -See the Getting Localized Test / Client Side section below. +请参阅下面的获取本地化资源Test中客户端部分. -##### Inherit From Other Resources +##### 继承其他资源 -A resource can inherit from other resources which makes possible to re-use existing localization strings without referring the existing resource. Example: +资源可以从其他资源继承,这使得可以在不引用现有资源的情况下重用现有的本地化字符串. 例如: ````C# [InheritResource(typeof(AbpValidationResource))] @@ -109,7 +109,7 @@ public class TestResource } ```` -Alternative inheritance by configuring the `AbpLocalizationOptions`: +也可以通过 `AbpLocalizationOptions` 配置: ````C# services.Configure(options => @@ -121,12 +121,12 @@ services.Configure(options => }); ```` -* A resource may inherit from multiple resources. -* If the new resource defines the same localized string, it overrides the string. +* 资源可以从多个资源继承. +* 如果新的本地化资源定义了相同的本地化字符串, 那么它会覆盖该字符串 -##### Extending Existing Resource +##### 扩展现有资源 -Inheriting from a resource creates a new resource without modifying the existing one. In some cases, you may want to not create a new resource but directly extend an existing resource. Example: +继承资源可以创建新的资源, 无需修改现有的资源. 但是在某些情况下, 您可能不想创建新资源,而是直接扩展现有资源. 例如: ````C# services.Configure(options => @@ -137,15 +137,15 @@ services.Configure(options => }); ```` -* If an extension file defines the same localized string, it overrides the string. +* 如果扩展文件定义了相同的本地化字符串, 那么它会覆盖该字符串. -#### Getting Localized Texts +#### 获取本地化文本 -##### Server Side +##### 服务器端 -Getting the localized text on the server side is pretty standard. +在服务端获取本地化文本的用法是非常标准的(它与AspNetCore提供的获取本地化资源方式无缝集成). -###### Simplest Usage In A Class +###### 在类中简单的用法 ````C# public class MyService @@ -164,7 +164,7 @@ public class MyService } ```` -###### Simplest Usage In A Razor View/Page +###### 在Razor视图/Page中简单的用法 ````c# @inject IHtmlLocalizer Localizer @@ -172,20 +172,20 @@ public class MyService

@Localizer["HelloWorld"]

```` -Refer to the [Microsoft's localization documentation](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/localization) for details about using localization on the server side. +有关在服务器端使用本地化的详细使用方法, 请参阅[AspNetCore的本地化文档](https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/localization) -##### Client Side +##### 客户端 -ABP provides JavaScript services to use the same localized texts in the client side. +ABP提供了JavaScript服务, 可以在客户端使用相同的本地化文本. -Get a localization resource: +获取本地化资源: ````js var testResource = abp.localization.getResource('Test'); ```` -Localize a string: +本地化字符串: ````js var str = testResource('HelloWorld'); -```` \ No newline at end of file +```` diff --git a/docs/zh-Hans/Module-Development-Basics.md b/docs/zh-Hans/Module-Development-Basics.md index bb193b613e..5cddcc5e7d 100644 --- a/docs/zh-Hans/Module-Development-Basics.md +++ b/docs/zh-Hans/Module-Development-Basics.md @@ -1,12 +1,12 @@ -## Module Development +## 模块开发 -### Introduction +### 介绍 -ABP is itself a modular framework. It also provides an infrastructure and architectural model to develop your own modules. +ABP本身是一个模块化框架.它还提供了一个基础架构和架构模型来开发你自己的模块. -### Module Class +### 模块类 -Every module should define a module class. The simplest way of defining a module class is to create a class derived from ``AbpModule`` as shown below: +每个模块都应该定义一个模块类.定义模块类的最简单方法是创建一个派生自``AbpModule``的类,如下所示: ````C# public class BlogModule : AbpModule @@ -16,11 +16,11 @@ public class BlogModule : AbpModule ```` -#### Configuring Dependency Injection & Other Modules +#### 配置依赖注入和其他模块 -##### ConfigureServices Method +##### ConfigureServices方法 -``ConfigureServices`` is the main method to add your services to the dependency injection system and configure other modules. Example: +``ConfigureServices``是将你的服务添加到依赖注入系统并配置其他模块的主要方法.例: ````C# public class BlogModule : AbpModule @@ -32,16 +32,16 @@ public class BlogModule : AbpModule } ```` -You can register dependencies one by one as stated in Microsoft's [documentation](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection). But ABP has a **conventional dependency registration system** which automatically register all services in your assembly. See the [dependency Injection](Dependency-Injection.md) documentation for more about the dependency injection system. +你可以按照Microsoft的[文档](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection)中的说明逐个注册依赖项.但ABP有一个**依照约定的依赖注册系统**,可以自动注册程序集中的所有服务.有关依赖项注入系统的更多信息,请参阅[依赖项注入](Dependency-Injection.md)文档. -You can also configure other services and modules in this way. Example: +你也可以通过这种方式配置其他服务和模块.例: ````C# public class BlogModule : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) { - //Configure default connection string for the application + //为应用程序配置默认的连接字符串 context.Services.Configure(options => { options.ConnectionStrings.Default = "......"; @@ -49,20 +49,19 @@ public class BlogModule : AbpModule } } ```` +有关配置系统的更多信息,请参阅配置(TODO:link)文档. -See Configuration (TODO: link) document for more about the configuration system. +##### 配置服务前和后 -##### Pre & Post Configure Services +``AbpModule``类还定义了``PreConfigureServices``和``PostConfigureServices``方法用来在``ConfigureServices``之前或之后覆盖和编写你的代码.请注意,在这些方法中编写的代码将在所有其他模块的``ConfigureServices``方法之前/之后执行. -``AbpModule`` class also defines ``PreConfigureServices`` and ``PostConfigureServices`` methods to override and write your code just before and just after ``ConfigureServices``. Notice that the code you have written into these methods will be executed before/after the ``ConfigureServices`` methods of all other modules. +#### 应用程序初始化 -#### Application Initialization +一旦配置了所有模块的所有服务,应用程序就会通过初始化所有模块来启动.在此阶段,你可以从``IServiceProvider``中获取服务,因为这时它已准备就绪且可用. -Once all the services of all modules are configured, the application starts by initializing all modules. In this phase, you can resolve services from ``IServiceProvider`` since it's ready and available. +##### OnApplicationInitialization方法 -##### OnApplicationInitialization Method - -You can override ``OnApplicationInitialization`` method to execute code while application is being started. Example: +你可以在启动应用程序时覆盖``OnApplicationInitialization``方法来执行代码.例: ````C# public class BlogModule : AbpModule @@ -77,7 +76,7 @@ public class BlogModule : AbpModule } ```` -``OnApplicationInitialization`` is generally used by the startup module to construct the middleware pipeline for ASP.NET Core applications. Example: +``OnApplicationInitialization``通常由启动模块用于构建ASP.NET Core应用程序的中间件管道.例: ````C# [DependsOn(typeof(AbpAspNetCoreMvcModule))] @@ -100,19 +99,19 @@ public class AppModule : AbpModule } ```` -You can also perform startup logic if your module requires it +如果模块需要,你还可以执行启动逻辑 -##### Pre & Post Application Initialization +##### 应用程序初始化前和后 -``AbpModule`` class also defines ``OnPreApplicationInitialization`` and ``OnPostApplicationInitialization`` methods to override and write your code just before and just after ``OnApplicationInitialization``. Notice that the code you have written into these methods will be executed before/after the ``OnApplicationInitialization`` methods of all other modules. +``AbpModule``类还定义了``OnPreApplicationInitialization``和``OnPostApplicationInitialization``方法用来在``OnApplicationInitialization``之前或之后覆盖和编写你的代码.请注意,在这些方法中编写的代码将在所有其他模块的``OnApplicationInitialization``方法之前/之后执行. -#### Application Shutdown +#### 应用程序关闭 -Lastly, you can override ``OnApplicationShutdown`` method if you want to execute some code while application is beign shutdown. +最后,如果要在应用程序关闭时执行某些代码,你可以覆盖``OnApplicationShutdown``方法. -### Module Dependencies +### 模块依赖 -In a modular application, it's not unusual for one module to depend upon another module(s). An Abp module must declare ``[DependsOn]`` attribute if it does have a dependcy upon another module, as shown below: +在模块化应用程序中,一个模块依赖于另一个模块并不罕见.如果一个Abp模块依赖于另一个模块,它必须声明``[DependsOn]``属性,如下所示: ````C# [DependsOn(typeof(AbpAspNetCoreMvcModule))] @@ -123,6 +122,6 @@ public class BlogModule } ```` -You can use multiple ``DependsOn`` attribute or pass multiple module types to a single ``DependsOn`` attribute depending on your preference. +你可以根据需要使用多个``DependsOn``属性或将多个模块类型传递给单个``DependsOn``属性. -A depended module may depend on another module, but you only need to define your direct dependencies. ABP investigates the dependency graph for the application at startup and initializes/shutdowns modules in the correct order. +依赖模块可能依赖于另一个模块,但你只需要定义直接依赖项.ABP在启动时会调查应用程序的依赖关系,并以正确的顺序初始化/关闭模块. diff --git a/docs/zh-Hans/Repositories.md b/docs/zh-Hans/Repositories.md index 228d066a0e..930bfa5af4 100644 --- a/docs/zh-Hans/Repositories.md +++ b/docs/zh-Hans/Repositories.md @@ -1,12 +1,12 @@ -## Repositories +## 仓储 -"*Mediates between the domain and data mapping layers using a collection-like interface for accessing domain objects*" (Martin Fowler). +"*在领域层和数据映射层之间进行中介,使用类似集合的接口来操作领域对象.*" (Martin Fowler). -Repositories, in practice, are used to perform database operations for domain objects (see [Entities](Entities.md)). Generally, a separated repository is used for each **aggregate root** or entity. +实际上,仓储用于领域对象在数据库(参阅[实体](Entities.md))中的操作, 通常每个 **聚合根** 或不同的实体创建对应的仓储. -### Generic Repositories +### 通用(泛型)仓储 -ABP can provide a **default generic repository** for each aggregate root or entity. You can [inject](Dependency-Injection.md) `IRepository` into your service and perform standard **CRUD** operations. Example usage: +ABP为每个聚合根或实体提供了 **默认的通用(泛型)仓储** . 你可以在服务中[注入](Dependency-Injection.md) `IRepository` 使用标准的**CRUD**操作. 用法示例: ````C# public class PersonAppService : ApplicationService @@ -38,49 +38,49 @@ public class PersonAppService : ApplicationService } ```` -In this example; +在这个例子中; -* `PersonAppService` simply injects `IRepository` in it's constructor. -* `Create` method uses `InsertAsync` to save a newly created entity. -* `GetList` method uses the standard LINQ `Where` and `ToList` methods to filter and get a list of people from the data source. +* `PersonAppService` 在它的构造函数中注入了 `IRepository` . +* `Create` 方法使用了 `InsertAsync` 创建并保存新的实体. +* `GetList` 方法使用标准LINQ `Where` 和 `ToList` 方法在数据源中过滤并获取People集合. -> The example above uses hand-made mapping between [entities](Entities.md) and [DTO](Data-Transfer-Objects.md)s. See [object to object mapping document](Object-To-Object-Mapping.md) for an automatic way of mapping. +> 上面的示例在[实体](Entities.md)与[DTO](Data-Transfer-Objects.md)之间使用了手动映射. 参阅 [对象映射](Object-To-Object-Mapping.md) 了解自动映射的使用方式. -Generic Repositories provides some standard CRUD features out of the box: +通用仓储提供了一些开箱即用的标准CRUD功能: -* Providers `Insert` method to save a new entity. -* Providers `Update` and `Delete` methods to update or delete an entity by entity object or it's id. -* Provides `Delete` method to delete multiple entities by a filter. -* Implements `IQueryable`, so you can use LINQ and extension methods like `FirstOrDefault`, `Where`, `OrderBy`, `ToList` and so on... -* Have **sync** and **async** versions for all methods. +* 提供 `Insert` 方法用于保存新实体. +* 提供 `Update` 和 `Delete` 方法通过实体或实体id更新或删除实体. +* 提供 `Delete` 方法使用条件表达式过滤删除多个实体. +* 实现了 `IQueryable`, 所以你可以使用LINQ和扩展方法 `FirstOrDefault`, `Where`, `OrderBy`, `ToList` 等... +* 所有方法都具有 **sync(同步)** 和 **async(异步)** 版本. -#### Generic Repository without a Primary Key +#### 无主键的通用(泛型)仓储 -If your entity does not have an Id primary key (it may have a composite primary key for instance) then you cannot use the `IRepository` defined above. In that case, you can inject and use `IRepository` for your entity. +如果你的实体没有id主键 (例如, 它可能具有复合主键) 那么你不能使用上面定义的 `IRepository`, 在这种情况下你可以仅使用实体(类型)注入 `IRepository`. -> `IRepository` has a few missing methods those normally works with the `Id` property of an entity. Because of the entity has no `Id` property in that case, these methods are not available. One example is the `Get` method that gets an id and returns the entity with given id. However, you can still use `IQueryable` features to query entities by standard LINQ methods. +> `IRepository` 有一些缺失的方法, 通常与实体的 `Id` 属性一起使用. 由于实体在这种情况下没有 `Id` 属性, 因此这些方法不可用. 比如 `Get` 方法通过id获取具有指定id的实体. 不过, 你仍然可以使用`IQueryable`的功能通过标准LINQ方法查询实体. -### Basic Repositories +### 基础仓储 -Standard `IRepository` interface extends standard `IQueryable` and you can freely query using standard LINQ methods. However, some ORM providers or database systems may not support standard `IQueryable` interface. +`IRepository` 接口扩展了标准 `IQueryable` 你可以使用标准LINQ方法自由查询.但是,某些ORM提供程序或数据库系统可能不支持`IQueryable`接口. -ABP provides `IBasicRepository` and `IBasicRepository` interfaces to support such scenarios. You can extend these interfaces (and optionally derive from `BasicRepositoryBase`) to create custom repositories for your entities. +ABP提供了 `IBasicRepository` 和 `IBasicRepository` 接口来支持这样的场景. 你可以扩展这些接口(并可选择性地从`BasicRepositoryBase`派生)为你的实体创建自定义存储库. -Depending on `IBasicRepository` but not depending on `IRepository` has an advantage to make possible to work with all data sources even if they don't support `IQueryable`. But major vendors, like Entity Framework, NHibernate or MongoDb already support `IQueryable`. +依赖于 `IBasicRepository` 而不是依赖 `IRepository` 有一个优点, 即使它们不支持 `IQueryable` 也可以使用所有的数据源, 但主要的供应商, 像 Entity Framework, NHibernate 或 MongoDb 已经支持了 `IQueryable`. -So, working with `IRepository` is the **suggested** way for typical applications. But reusable module developers may consider `IBasicRepository` to support a wider range of data sources. +因此, 使用 `IRepository` 是典型应用程序的 **建议方法**. 但是可重用的模块开发人员可能会考虑使用 `IBasicRepository` 来支持广泛的数据源. -### Custom Repositories +### 自定义仓储 -Default generic repositories will be sufficient for most cases. However, you may need to create a custom repository class for your entity. +对于大多数情况, 默认通用仓储就足够了. 但是, 你可能会需要为实体创建自定义仓储类. -#### Custom Repository Example +#### 自定义仓储示例 -ABP does not force you to implement any interface or inherit from any base class for a repository. It can be just a simple POCO class. However, it's suggested to inherit existing repository interface and classes to make your work easier and get the standard methods out of the box. +ABP不会强制您实现任何接口或从存储库的任何基类继承. 它可以只是一个简单的POCO类. 但是建议继承现有的仓储接口和类, 获得开箱即用的标准方法使你的工作更轻松. -##### Custom Repository Interface +##### 自定义仓储接口 -First, define an interface in your domain layer: +首先在领域层定义一个仓储接口: ```c# public interface IPersonRepository : IRepository @@ -89,11 +89,11 @@ public interface IPersonRepository : IRepository } ``` -This interface extends `IRepository` to take advantage of pre-built repository functionality. +此接口扩展了 `IRepository` 以使用已有的通用仓储功能. -##### Custom Repository Implementation +##### 自定义仓储实现 -A custom repository is tightly coupled to the data access tool type you are using. In this example, we will use Entity Framework Core: +自定义存储库依赖于你使用的数据访问工具. 在此示例中, 我们将使用Entity Framework Core: ````C# public class PersonRepository : EfCoreRepository, IPersonRepository @@ -113,5 +113,4 @@ public class PersonRepository : EfCoreRepository, IPe } ```` -You can directly access the data access provider (`DbContext` in this case) to perform operations. See [entity framework integration document](Entity-Framework-Core.md) for more about custom repositories based on EF Core. - +你可以直接使用数据库访问提供程序 (本例中是 `DbContext` ) 来执行操作. 有关基于EF Core的自定义仓储的更多信息, 请参阅[EF Core 集成文档](Entity-Framework-Core.md). \ No newline at end of file diff --git a/docs/zh-Hans/Tag-Helpers.md b/docs/zh-Hans/Tag-Helpers.md index 2d8b465c23..d4cadc9b18 100644 --- a/docs/zh-Hans/Tag-Helpers.md +++ b/docs/zh-Hans/Tag-Helpers.md @@ -1,3 +1,3 @@ ## ABP Tag Helpers -"ABP tag helpers" is not documented yet. You can see a [demo of components](http://bootstrap-taghelpers.abp.io/) for now. \ No newline at end of file +"ABP tag helpers" 目前还没有文档. 你现在可以看到[组件演示](http://bootstrap-taghelpers.abp.io/). \ No newline at end of file diff --git a/docs/zh-Hans/Virtual-File-System.md b/docs/zh-Hans/Virtual-File-System.md index 9ee0e106d4..dd702d5786 100644 --- a/docs/zh-Hans/Virtual-File-System.md +++ b/docs/zh-Hans/Virtual-File-System.md @@ -1,18 +1,18 @@ -## Virtual File System +## 虚拟文件系统 -The Virtual File System makes it possible to manage files that do not physically exist on the file system (disk). It's mainly used to embed (js, css, image, cshtml...) files into assemblies and use them like physical files at runtime. +虚拟文件系统可以管理文件系统(磁盘)上实际上不存在的文件. 它主要用于将(js, css, image, cshtml ...)文件嵌入到程序集中, 并在运行时将它们用作物理文件. -### Volo.Abp.VirtualFileSystem Package +### Volo.Abp.VirtualFileSystem nuget包 -Volo.Abp.VirtualFileSystem is the core package of the virtual file system. Install it in your project using the package manager console (PMC): +Volo.Abp.VirtualFileSystem是虚拟文件系统的核心包. 使用程序包管理器控制台(PMC)将其安装到项目中: ``` Install-Package Volo.Abp.VirtualFileSystem ``` -> This package is already installed by default with the startup template. So, most of the time, you will not need to install it manually. +> 启动模板默认已经安装了此nuget包, 所以在大多数情况下你不需要手动安装它. -Then you can add **AbpVirtualFileSystemModule** dependency to your module: +然后你可以在module中添加 **AbpVirtualFileSystemModule** 依赖项: ```c# using Volo.Abp.Modularity; @@ -28,13 +28,14 @@ namespace MyCompany.MyProject } ``` -#### Registering Embedded Files +#### 注册嵌入式文件 -A file should be first marked as an embedded resource to embed the file into the assembly. The easiest way to do it is to select the file from the **Solution Explorer** and set **Build Action** to **Embedded Resource** from the **Properties** window. Example: +首先需要把文件标记为嵌入式资源将文件嵌入到程序集中. 最简单的方式是在 **解决方案管理器** 中选择文件, 然后找到 **"属性"** 窗口将 **"生成操作"** 设置为 **"嵌入式资源"**. +例如: ![build-action-embedded-resource-sample](images/build-action-embedded-resource-sample.png) -If you want to add multiple files, this can be tedious. Alternatively, you can directly edit your **.csproj** file: +如果需要添加多个文件, 这会很乏味. 这时可以直接编辑 **.csproj** 文件: ````C# @@ -42,9 +43,9 @@ If you want to add multiple files, this can be tedious. Alternatively, you can d ```` -This configuration recursively adds all files under the **MyResources** folder of the project (including the files you will add in the future). +此配置以递归方式添加项目的 **MyResources** 文件夹下的所有文件(包括将来新添加的文件). -Then the module needs to be configured using `VirtualFileSystemOptions` to register the embedded files to the virtual file system. Example: +然后应该使用 `VirtualFileSystemOptions` 来配置模块, 以便将嵌入式文件注册到虚拟文件系统. 例如: ````C# using Microsoft.Extensions.DependencyInjection; @@ -70,15 +71,15 @@ namespace MyCompany.MyProject } ```` -The `AddEmbedded` extension method takes a class, finds all embedded files from the assembly of the given class and registers them to the virtual file system. More concisely it could be written as follows: +`AddEmbedded` 扩展方法需要一个类, 从给定类的程序集中查找所有嵌入文件, 并将它们注册到虚拟文件系统. 它还有更简洁的写法: ````C# options.FileSets.Add(new EmbeddedFileSet(typeof(MyModule).Assembly)); ```` -#### Getting Virtual Files: IVirtualFileProvider +#### 获取虚拟文件: IVirtualFileProvider -After embedding a file into an assembly and registering it to the virtual file system, the `IVirtualFileProvider` interface can be used to get files or directory contents: +将文件嵌入到程序集中并注册到虚拟文件系统后, 可以使用`IVirtualFileProvider`来获取文件或目录内容: ````C# public class MyService @@ -102,15 +103,15 @@ public class MyService } ```` -#### Dealing With Embedded Files During Development +#### 在开发过程中处理嵌入式文件 -Embedding a file into a module assembly and being able to use it from another project just by referencing the assembly (or adding a nuget package) is invaluable for creating a re-usable module. However, it does make it a little bit harder to develop the module itself. +通过引用程序集(或添加nuget包)将文件嵌入模块程序集并从另一个项目中使用它对于创建可重用模块非常有价值. 但是, 这使得开发模块本身变得有点困难. -Let's assume that you're developing a module that contains an embedded JavaScript file. Whenever you change this file you must re-compile the project, re-start the application and refresh the browser page to take the change. Obviously, this is very time consuming and tedious. +假设您正在开发一个包含嵌入式JavaScript文件的模块. 当你更改文件时, 你必须重新编译项目, 重新启动应用程序并刷新浏览器页面以进行更改. 显然, 这是非常耗时和乏味的. -What is needed is the ability for the application to directly use the physical file at development time and a have a browser refresh reflect any change made in the JavaScript file. The `ReplaceEmbeddedByPyhsical` method makes all this possible. +我们需要的是应用程序在开发时直接使用物理文件的能力, 让浏览器刷新时同步JavaScript文件的任何更改. `ReplaceEmbeddedByPyhsical` 方法使其成为可能. -The example below shows an application that depends on a module (`MyModule`) that itself contains embedded files. The application can reach the source code of the module at development time. +下面的示例展示了应用程序依赖于包含嵌入文件的模块("MyModule"), 并且应用程序可以在开发过程中直接使用模块的源代码. ````C# [DependsOn(typeof(MyModule))] @@ -126,7 +127,7 @@ public class MyWebAppModule : AbpModule { //ReplaceEmbeddedByPyhsical gets the root folder of the MyModule project options.FileSets.ReplaceEmbeddedByPyhsical( - Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}MyModuleProject", Path.DirectorySeparatorChar)) + Path.Combine(hostingEnvironment.ContentRootPath, "..\\MyModuleProject") ); }); } @@ -136,30 +137,30 @@ public class MyWebAppModule : AbpModule } ```` -The code above assumes that `MyWebAppModule` and `MyModule` are two different projects in a Visual Studio solution and `MyWebAppModule` depends on the `MyModule`. +上面的代码假设`MyWebAppModule`和`MyModule`是Visual Studio解决方案中的两个不同的项目, `MyWebAppModule`依赖于`MyModule`. -### ASP.NET Core Integration +### ASP.NET Core 集成 -The Virtual File System is well integrated to ASP.NET Core: +虚拟文件系统与 ASP.NET Core 无缝集成: -* Virtual files can be used just like physical (static) files in a web application. -* Razor Views, Razor Pages, js, css, image files and all other web content types can be embedded into assemblies and used just like the physical files. -* An application (or another module) can override a virtual file of a module just like placing a file with the same name and extension into the same folder of the virtual file. +* 虚拟文件可以像Web应用程序上的物理(静态)文件一样使用. +* Razor Views, Razor Pages, js, css, 图像文件和所有其他Web内容可以嵌入到程序集中并像物理文件一样使用. +* 应用程序(或其他模块)可以覆盖模块的虚拟文件, 就像将具有同名和同扩展名文件放入虚拟文件的同一文件夹中一样. -#### Virtual Files Middleware +#### 虚拟文件中间件 -The Virtual Files Middleware is used to serve embedded (js, css, image...) files to clients/browsers just like physical files in the **wwwroot** folder. Add it just after the static file middleware as shown below: +虚拟文件中间件用于向客户端/浏览器提供嵌入式(js, css, image ...)文件, 就像 **wwwroot** 文件夹中的物理(静态)文件一样. 在静态文件中间件之后添加它, 如下所示: ````C# app.UseVirtualFiles(); ```` -Adding virtual files middleware after the static files middleware makes it possible to override a virtual file with a real physical file simply by placing it in the same location as the virtual file. +在静态文件中间件之后添加虚拟文件中间件, 可以通过放置在同一位置,使用物理文件来覆盖虚拟文件. ->The Virtual File Middleware only serves the virtual wwwroot folder contents - just like the other static files. +> 虚拟文件中间件只是像静态文件一样提供虚拟wwwroot文件夹内容. #### Views & Pages -Embedded razor views/pages are available in the application without any configuration. Simply place them into the standard Views/Pages virtual folders of the module being developed. +无需任何配置即可在应用程序中使用嵌入式的 razor Views/pages. 只需要将它们放入模块开发中的标准 Views/Pages 虚拟文件夹即可. -An embedded view/page can be overrided if a module/application locates a new file into the same location as mentioned above. +如果模块/应用程序将新文件放置同一位置, 则会覆盖嵌入式的 Views/Pages.