// [doc-seo]
{
"Description": "了解如何使用模板有效启动ABP应用程序,并掌握自定义所需的集成与配置细节。"
}
ABP 应用程序启动
通常,您会使用 ABP CLI 的 abp new 命令,通过预构建的 启动解决方案模板 之一来 开始使用 。这样做时,通常无需了解 ABP 如何与您的应用程序集成、配置和初始化的细节。启动模板还包含了基础的ABP包,并且 应用程序模块 已预先安装和配置。
始终建议 从启动模板开始 ,并根据需求进行修改。仅当您想了解细节或需要修改ABP启动方式时,才阅读本文档。
尽管ABP具有众多功能和集成,但它设计为轻量级且模块化的框架。它包含 数百个 NuGet 和 NPM 包 ,因此您只需使用所需功能。如果您遵循 从空 ASP.NET Core MVC / Razor Pages 应用程序开始 文档,您将看到如何轻松地将ABP安装到空的ASP.NET Core项目中。您只需安装一个NuGet包并进行少量修改。
本文档面向那些希望更好地理解ABP在启动时如何初始化和配置的开发者。
安装到控制台应用程序
.NET控制台应用程序是最小化的.NET应用程序。因此,以控制台应用程序为例展示ABP的安装过程是最佳选择。
如果您 使用Visual Studio创建新的控制台应用程序(适用于.NET 8.0或更高版本),您将看到以下解决方案结构(我将解决方案命名为MyConsoleDemo):
此示例使用顶级语句,因此仅包含一行代码。
第一步是安装Volo.Abp.Core NuGet包,这是ABP最核心的NuGet包。您可以使用ABP CLI安装它。在要安装包的.csproj文件所在文件夹中执行以下命令:
abp add-package Volo.Abp.Core
或者,您可以在项目的根文件夹(包含MyConsoleDemo.csproj文件的文件夹,以本例为例)中使用命令行终端:
dotnet add package Volo.Abp.Core
添加NuGet包后,我们应为应用程序创建一个根 模块类 。我们可以在项目中创建以下类:
using Volo.Abp.Modularity;
namespace MyConsoleDemo
{
public class MyConsoleDemoModule : AbpModule
{
}
}
这是一个从AbpModule类派生的空类。它是您控制应用程序依赖项、实现配置和启动/关闭逻辑的主类。更多信息,请查看 模块化 文档。
作为第二步也是最后一步,按以下代码块修改Program.cs:
using MyConsoleDemo;
using Volo.Abp;
// 1: 创建ABP应用程序容器
using var application = await AbpApplicationFactory.CreateAsync<MyConsoleDemoModule>();
// 2: 初始化/启动ABP(及所有模块)
await application.InitializeAsync();
Console.WriteLine("ABP已启动...");
// 3: 停止ABP(及所有模块)
await application.ShutdownAsync();
就这样。现在,ABP已在您的应用程序中安装、集成、启动和停止。从现在开始,您可以根据需要安装 ABP包 到您的应用程序。
安装框架包
如果您想从.NET应用程序发送电子邮件,可以使用.NET标准的 SmtpClient类 。ABP还提供了一个IEmailSender服务,简化了 发送电子邮件 并在中心位置配置电子邮件设置。如果您想使用它,应将 Volo.Abp.Emailing NuGet包安装到您的项目中:
dotnet add package Volo.Abp.Emailing
添加新的ABP包/模块后,您还需要从模块类中指定模块依赖项。因此,按以下方式修改MyConsoleDemoModule类:
using Volo.Abp.Emailing;
using Volo.Abp.Modularity;
namespace MyConsoleDemo
{
[DependsOn(typeof(AbpEmailingModule))] // 添加了模块依赖项
public class MyConsoleDemoModule : AbpModule
{
}
}
我刚刚添加了一个[DependsOn]属性,声明我想使用ABP电子邮件模块(AbpEmailingModule)。现在,我可以在Program.cs中使用IEmailSender服务:
using Microsoft.Extensions.DependencyInjection;
using MyConsoleDemo;
using Volo.Abp;
using Volo.Abp.Emailing;
using var application = await AbpApplicationFactory.CreateAsync<MyConsoleDemoModule>();
await application.InitializeAsync();
// 使用IEmailSender服务发送电子邮件
var emailsender = application.ServiceProvider.GetRequiredService<IEmailSender>();
await emailsender.SendAsync(
to: "info@acme.com",
subject: "Hello World",
body: "我的消息正文..."
);
await application.ShutdownAsync();
如果您运行该应用程序,会收到运行时错误,提示电子邮件发送设置尚未完成。您可以查看 电子邮件发送文档 了解如何配置。
就这样。安装一个ABP NuGet包,添加模块依赖项(使用[DependsOn]属性),然后使用NuGet包中的任何服务。
ABP CLI 已经有一个特殊命令,可以一键添加ABP NuGet包,并将[DependsOn]属性添加到您的模块类中:
abp add-package Volo.Abp.Emailing
我们建议您使用abp add-package命令,而不是手动操作。
AbpApplicationFactory
AbpApplicationFactory是创建ABP应用程序容器的主类。它提供了一个静态的CreateAsync(以及如果您无法使用异步编程,则提供Create)方法,具有多个重载。让我们研究这些重载,以了解它们的适用场景。
第一个重载获取一个泛型模块类参数,如本文档之前使用的:
AbpApplicationFactory.CreateAsync<MyConsoleDemoModule>();
泛型类参数应是应用程序的根模块类。所有其他模块都作为该模块的依赖项解析。
第二个重载将模块类作为Type参数,而不是泛型参数。因此,之前的代码块可以重写如下:
AbpApplicationFactory.CreateAsync(typeof(MyConsoleDemoModule));
两个重载的工作方式完全相同。因此,如果您在开发时不知道模块类类型,并在运行时(以某种方式)计算它,可以使用第二个重载。
如果您使用上述方法之一,ABP会创建一个内部服务集合(IServiceCollection)和一个内部服务提供程序(IServiceProvider),以在内部设置 依赖注入 系统。注意,在安装框架包部分,我们使用了application.ServiceProvider属性从依赖注入系统中解析IEmailSender服务。
下一个重载从您那里获取一个IServiceCollection参数,允许您自己设置依赖注入系统,或集成到另一个也内部设置依赖注入系统的框架(如ASP.NET Core)。
我们可以按以下方式修改Program.cs,以外部管理依赖注入设置:
using Microsoft.Extensions.DependencyInjection;
using MyConsoleDemo;
using Volo.Abp;
// 1: 手动创建IServiceCollection
IServiceCollection services = new ServiceCollection();
// 2: 将IServiceCollection外部传递给ABP
using var application = await AbpApplicationFactory
.CreateAsync<MyConsoleDemoModule>(services);
// 3: 手动构建IServiceProvider对象
IServiceProvider serviceProvider = services.BuildServiceProvider();
// 4: 将IServiceProvider外部传递给ABP
await application.InitializeAsync(serviceProvider);
Console.WriteLine("ABP已启动...");
await application.ShutdownAsync();
在此示例中,我们使用了.NET的标准依赖注入容器。services.BuildServiceProvider()调用创建了标准容器。然而,ABP提供了一个替代的扩展方法BuildServiceProviderFromFactory(),即使您使用另一个依赖注入容器,它也能正常工作:
IServiceProvider serviceProvider = services.BuildServiceProviderFromFactory();
最后,CreateAsync方法有一个最终重载,它将模块类名称作为Type参数和一个IServiceCollection对象。因此,我们可以将最后的CreateAsync方法使用重写为以下代码块:
using var application = await AbpApplicationFactory
.CreateAsync(typeof(MyConsoleDemoModule), services);
所有
CreateAsync方法重载都有对应的Create方法。如果您的应用程序类型无法利用异步编程(这意味着您不能使用await关键字),那么您可以使用Create方法代替CreateAsync方法。
AbpApplicationCreationOptions
所有CreateAsync重载都可以获取一个可选的Action<AbpApplicationCreationOptions>参数,用于配置应用程序创建时使用的选项。参见以下示例:
using var application = await AbpApplicationFactory
.CreateAsync<MyConsoleDemoModule>(options =>
{
options.ApplicationName = "MyApp";
});
我们传递了一个lambda方法来配置ApplicationName选项。以下是所有标准选项的列表:
ApplicationName:应用程序的可读名称。它是应用程序的唯一值。Configuration:当托管系统未提供时,可用于设置 应用程序配置 。对于ASP.NET Core和其他.NET托管应用程序,不需要此选项。但是,如果您使用带有内部服务提供程序的AbpApplicationFactory,可以使用此选项配置应用程序配置的构建方式。Environment:应用程序的环境名称。PlugInSources:插件源列表。请参阅 插件模块文档 了解如何使用插件。Services:可用于注册服务依赖项的IServiceCollection对象。您通常不需要它,因为您在 模块类 中配置服务。但是,在为AbpApplicationCreationOptions类编写扩展方法时可以使用它。
ApplicationName选项
如上所述,ApplicationName选项是应用程序的可读名称。它是应用程序的唯一值。
ABP在多个地方使用 ApplicationName 来区分应用程序。例如,审计日志 系统在每个审计日志记录中保存ApplicationName,以便您了解哪个应用程序创建了审计日志条目。因此,如果您的系统由多个应用程序组成(如微服务解决方案),并且这些应用程序将审计日志保存到单个点,您应确保每个应用程序具有不同的ApplicationName。
默认情况下,ApplicationName属性的值从入口程序集的名称(通常是.NET解决方案中的项目名称)自动设置,这在大多数情况下是合适的,因为每个应用程序通常具有唯一的入口程序集名称。
有两种方法将应用程序名称设置为不同的值。在第一种方法中,您可以在应用程序的 配置 中设置 ApplicationName 属性。最简单的方法是在 appsettings.json 文件中添加一个 ApplicationName 字段:
{
"ApplicationName": "Services.Ordering"
}
或者,您可以在创建ABP应用程序时设置AbpApplicationCreationOptions.ApplicationName。您可以在解决方案中找到AddApplication或AddApplicationAsync调用(通常在Program.cs文件中),并按以下方式设置ApplicationName选项:
await builder.AddApplicationAsync<OrderingServiceHttpApiHostModule>(options =>
{
options.ApplicationName = "Services.Ordering";
});
IApplicationInfoAccessor
如果您稍后在解决方案中需要访问ApplicationName,可以注入IApplicationInfoAccessor服务,并从其ApplicationName属性获取值。
IApplicationInfoAccessor还提供一个InstanceId值,这是在您的应用程序启动时生成的随机GUID值。您可以使用该值区分应用程序实例。
IAbpApplication
AbpApplicationFactory从其CreateAsync(或Create)方法返回一个IAbpApplication对象。IAbpApplication是ABP应用程序的主容器。它也被注册到 依赖注入 系统中,因此您可以在服务中注入IAbpApplication以使用其属性和方法。
以下是您可能想了解的IAbpApplication属性列表:
StartupModuleType:获取在创建应用程序容器时使用的根模块(在AbpApplicationFactory.CreateAsync方法中)。Services:所有服务注册的列表(IServiceCollection对象)。您不能在应用程序初始化后向此集合添加新服务(实际上可以添加,但不会有任何效果)。ServiceProvider:对应用程序使用的根服务提供程序的引用。在初始化应用程序之前不能使用此属性。如果您需要从该IServiceProvider对象解析非单例服务,请始终创建一个新的服务范围并在使用后处置它。否则,您的应用程序将存在内存泄漏问题。有关服务范围的更多信息,请参阅 依赖注入 文档的释放/处置服务部分。Modules:加载到当前应用程序中的所有模块的只读列表。或者,如果您需要在应用程序代码中访问模块列表,可以注入IModuleContainer服务。
IAbpApplication接口扩展了IApplicationInfoAccessor接口,因此您可以从它获取ApplicationName和InstanceId值。但是,如果您只需要访问这些属性,请注入并使用IApplicationInfoAccessor服务。
IAbpApplication是可处置的。在退出应用程序之前始终处置它。
IAbpHostEnvironment
有时,在创建应用程序时,我们需要获取当前托管环境并根据其采取行动。在这种情况下,我们可以使用一些服务,如.NET提供的 IWebHostEnvironment 或 IWebAssemblyHostEnvironment ,在最终应用程序中使用。
但是,我们无法在最终应用程序使用的类库中使用这些服务。ABP提供了IAbpHostEnvironment服务,允许您随时获取当前环境名称。ABP在多个地方使用IAbpHostEnvironment来根据环境执行特定操作。例如,ABP在开发环境中减少某些服务的缓存持续时间。
IAbpHostEnvironment按以下顺序获取当前环境名称:
- 如果在
AbpApplicationCreationOptions中指定了环境名称,则获取并设置它。 - 如果未在
AbpApplicationCreationOptions中指定环境名称,则尝试从ASP.NET Core和Blazor WASM应用程序的IWebHostEnvironment或IWebAssemblyHostEnvironment服务获取环境名称。 - 如果未指定环境名称或无法从服务获取,则将环境名称设置为生产。
您可以在创建ABP应用程序时配置AbpApplicationCreationOptions 选项类 ,并将其Environment属性设置为环境名称。您可以在解决方案中找到AddApplication或AddApplicationAsync调用(通常在Program.cs文件中),并按以下方式设置Environment选项:
await builder.AddApplicationAsync<OrderingServiceHttpApiHostModule>(options =>
{
options.Environment = Environments.Staging; //或直接设置为"Staging"
});
然后,每当您需要获取当前环境名称或检查环境时,可以使用IAbpHostEnvironment接口:
public class MyDemoService
{
private readonly IAbpHostEnvironment _abpHostEnvironment;
public MyDemoService(IAbpHostEnvironment abpHostEnvironment)
{
_abpHostEnvironment = abpHostEnvironment;
}
public void MyMethod()
{
var environmentName = _abpHostEnvironment.EnvironmentName;
if (_abpHostEnvironment.IsDevelopment()) { /* ... */ }
if (_abpHostEnvironment.IsStaging()) { /* ... */ }
if (_abpHostEnvironment.IsProduction()) { /* ... */ }
if (_abpHostEnvironment.IsEnvironment("custom-environment")) { /* ... */ }
}
}
.NET通用主机与ASP.NET Core集成
AbpApplicationFactory可以创建独立的ABP应用程序容器,无需任何外部依赖。然而,在大多数情况下,您会希望将其与 .NET的通用主机 或ASP.NET Core集成。对于此类用途,ABP提供了内置的扩展方法,以便轻松创建与这些系统良好集成的ABP应用程序容器。
从空 ASP.NET Core MVC / Razor Pages 应用程序开始 文档清楚地解释了如何在ASP.NET Core应用程序中创建ABP应用程序容器。
您还可以 创建控制台应用程序 以查看其如何与.NET通用主机集成。
大多数时候,您会直接使用 ABP CLI 的
new命令创建ABP应用程序。因此,您无需关心这些集成细节。
抠丁客



