配置應用程式
ASP.NET Core 的配置系統提供了一個基於鍵值對的配置方法。它是一個可擴充套件的系統,可以從各種資源中讀取鍵值對,例如 JSON 設定檔案、環境變數、命令列引數等等。
設定配置值
預設使用appsettings.json
檔案是配置的最簡單方法。假設我們正在構建一個使用 Azure 傳送 SMS 的服務,並且我們需要以下配置值:
Sender
: 發件人號碼ConnectionString
: 你的 Azure 資源的連線字串
我們可以在appsettings.json
檔案的配置部分定義這些:
{
...
"AzureSmsService": {
"Sender": "+901112223344",
"ConnectionString": "..."
}
}
這裡的鍵名是完全任意的,只要您在程式碼中使用相同的鍵,您就可以輕鬆地讀取它們的值。
讀取配置值
您可以在需要讀取配置值的地方注入IConfiguration
以使用該服務。例如,我們可以在 AzureSmsService
中獲取Azure 配置值用於傳送 SMS:
using System.Threading.Tasks;
using Microsoft.Extensions.Configuration;
using Volo.Abp.DependencyInjection;
namespace SmsSending
{
public class AzureSmsService : ISmsService, ITransientDependency
{
private readonly IConfiguration _configuration;
public AzureSmsService(IConfiguration configuration)
{
_configuration = configuration;
}
public async Task SendAsync(string phoneNumber, string message)
{
string sender = _configuration["AzureSmsService:Sender"];
string ConnectionString = _configuration["AzureSmsService:ConnectionString"];
//TODO: Use Azure to send the SMS message
}
}
}
IConfiguration
服務也可用於ConfigureServices
中:
public override void ConfigureServices(ServiceConfigurationContext context)
{
IConfiguration configuration = context.Services.GetConfiguration();
string sender = configuration["AzureSmsService:Sender"];
}
這裡,我們可以在服務注入之前訪問配置值。
以上的配置方式固然方便,但是,如果您正在構建一個可重用的庫,則選項模式可能是更好的方法,因為它是型別安全。
實現選項模式
為了使用選項模式,我們使用一個普通的類(有時稱為POCO–Plain Old C# Object),我們從如何定義、配置和使用配置開始。
定義選項類
選項類是一個簡單的類。我們為 Azure SMS 服務定義一個選項類,如以下程式碼塊所示:
public class AzureSmsServiceOptions
{
public string Sender { get; set; }
public string ConnectionString { get; set; }
}
將字尾Options
新增到選項類是一種約定。
配置選項
您可以在模組的ConfigureServices
方法中配置,可以使用IServiceCollection.Configure
的擴充套件方法為任何選項類設定值。看下下面的程式碼塊是如何配置的:
[DependsOn(typeof(SmsSendingModule))]
public class MyStartupModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.Configure<AzureSmsServiceOptions>(options =>
{
options.Sender = "+901112223344";
options.ConnectionString = "...";
});
}
}
context.Services.Configure
方法是獲取選項類的通用方法。它還需要一個委託來設定選項值。在此示例中,我們通過在指定的 lambda 表示式中設定Sender
和ConnectionString
屬性來進行配置。
AbpModule
基類提供了一個Configure
方法作為context.Services.Configure
方法的快捷方式,因此您可以重寫程式碼如下:
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AzureSmsServiceOptions>(options =>
{
options.Sender = "+901112223344";
options.ConnectionString = "...";
});
}
你應該看到了一點點區別了吧?
使用配置選項值
ASP.NET Core 提供了一個IOptions<T>
介面來注入選項類。我們使用AzureSmsServiceOptions
重寫AzureSmsService
裡的IConfiguration
服務,如以下程式碼塊所示:
public class AzureSmsService : ISmsService, ITransientDependency
{
private readonly AzureSmsServiceOptions _options;
public AzureSmsService(IOptions<AzureSmsServiceOptions> options)
{
_options = options.Value;
}
public async Task SendAsync(string phoneNumber, string message)
{
string sender = _options.Sender;
string ConnectionString = _options.ConnectionString;
//TODO...
}
}
我們注入IOptions<AzureSmsServiceOptions>
並使用其Value
屬性來獲取配置值。IOptions<T>
介面定義在Microsoft.Extensions.Options
包裡,是一種標準的選項類注入方式,如果你直接注入AzureSmsServiceOptions
類,你會得到一個依賴注入異常。所以要通過IOptions<T>
把選項類包裹起來.
上面只是簡單地定義、配置和使用了這些選項。如果我們想結合配置系統來設定選項該怎麼辦?
首先,我們用IConfiguration
讀取配置,並設定選項值:
[DependsOn(typeof(SmsSendingModule))]
public class MyStartupModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
var configuration = context.Services.GetConfiguration();
Configure<AzureSmsServiceOptions>(options =>
{
options.Sender = configuration\["AzureSmsService:Sender"\];
options.ConnectionString = configuration\["AzureSmsService:ConnectionString"\];
});
}
}
我們通過上下文的context.Services.GetConfiguration()
方法獲得IConfiguration
介面,然後進行賦值操作。
由於這種用法很常見,我們可以重寫一下程式碼,如下塊所示:
public override void ConfigureServices(ServiceConfigurationContext context)
{
var configuration = context.Services.GetConfiguration();
Configure<AzureSmsServiceOptions>(configuration.GetSection("AzureSmsService"));
}
[success] 翻譯點評:雖然改動量很小,但是非常漂亮,可見作者精益求精的態度。
使用這種用法,配置代替了委託操作,它通過命名約定自動將配置鍵與選項類的屬性進行匹配。如果AzureSmsService
未在配置中定義,則此程式碼也不會影響選項。
選項模式為開發人員提供了更大的靈活性:他們可以從IConfiguration
或者其他資料來源進行選項設定。
[success] 提示:預設情況下從配置中設定選項
如果您正在構建可重用模組,最好儘可能從配置中設定選項。也就是說,您可以將前面的程式碼寫入您的模組中。這樣,開發人員可以直接從appsettings.json
檔案中配置他們的模組。
ASP.NET Core 和 ABP 選項
ASP.NET Core 和 ABP 框架都集中預先使用選項模式配置選項。
以下示例顯示了在 ABP 框架中配置選項:
Configure<AbpAuditingOptions>(options =>
{
options.IgnoredTypes.Add(typeof(ProductDto));
});
AbpAuditingOptions
由 ABP 框架的審計日誌系統定義。我們正在新增一個型別,用於在審計日誌中忽略ProductDto
。
下一個示例顯示在 ASP.NET Core 中配置選項:
Configure<MvcOptions>(options =>
{
options.RespectBrowserAcceptHeader = true;
});
MvcOptions
由 ASP.NET Core 內部定義,用於配置 ASP.NET Core MVC 框架的行為。
選項類中的複雜型別
請注意,AbpAuditingOptions.IgnoredTypes
是一個的Type
列表,它不是在appsettings.json
檔案中定義的那種簡單原始型別,這是選項模式的好處之一:您可以定義具有複雜型別的屬性甚至回撥動作。
配置和選項系統提供了一種便捷的方式來配置服務的行為。
日誌系統
日誌記錄是每個應用的基礎設施。ASP.NET Core 提供了一個簡單而高效的日誌系統。它可以與流行的日誌庫整合,例如 NLog、Log4Net 和 Serilog。
Serilog 是一個廣泛使用的庫,它為日誌目標提供了許多選項,包括控制檯、文字檔案和 Elasticsearch。ABP 啟動模板帶有預安裝和配置的 Serilog 庫。它將日誌寫入應用的Logs
資料夾中,如果需要,您可以配置 Serilog 以將日誌寫入不同的目標(所有配置都包含在啟動模板中)。請參考 Serilog 的官方文件來配置 Serilog 選項。
Serilog 不是 ABP 框架的核心依賴,因此,我們可以輕鬆使用其他提供商進行替換。
該ILogger<T>
介面用於在 ASP.NET Core 中寫入日誌,T
通常是您的服務型別。
下面是一個寫入日誌的示例服務:
public class AzureSmsService : ISmsService, ITransientDependency
{
private readonly ILogger<AzureSmsService> _logger;
public AzureSmsService(ILogger<AzureSmsService> logger)
{
_logger = logger;
}
public async Task SendAsync(string phoneNumber, string message)
{
_logger.LogInformation($"Sending SMS to {phoneNumber}: {message}");
//TODO...
}
}
該類在其建構函式中注入ILogger<AzureSmsService>
服務並使用LogInformation
方法將日誌寫入日誌系統。
ILogger
介面上有更多的方法可以寫入不同嚴重級別的日誌,例如LogError和LogDebug。有關所有詳細資訊,請參閱 ASP.NET Core 的文件日誌系統。
概括
本文介紹了 ASP.NET Core 和 ABP 框架的核心模組。
你已經瞭解瞭如何使用Startup
類、配置系統和選項模式來配置 ASP.NET Core 和 ABP 框架服務。
ABP 提供了一個模組化系統,相比 ASP.NET Core 的初始化和配置,ABP支援建立多個模組,其中每個模組支援獨立的初始化和配置。通過這種方式,您可以將應用拆分為多個模組,以更好地方式組織程式碼或建立在不同應用中可重用的模組。
依賴注入系統是ASP.NET Core 最基本的基礎設施。一個服務通常使用依賴注入系統消費其他服務。這裡介紹了依賴注入系統的基本方面,並解釋了 ABP 如何簡化服務註冊。
下一篇講重點介紹資料訪問基礎架構,這是業務應用程式的一個重要方面。我們將看到 ABP 框架如何標準化定義實體和使用儲存庫來抽象和執行資料庫操作,同時自動化資料庫連線和事務管理。