入門系列-設置管理

Settings

配置系統 是在啓動時配置應用程序很好的方式. 除了配置之外, ABP提供了另外一種設置和獲取應用程序設置的方式。

設置存儲在動態數據源(通常是數據庫)中的鍵值對. 設置系統預構建了用戶,租戶,全局和默認設置方法並且可以進行擴展。

定義設置

使用設置之前需要定義它. ABP是 模塊化的, 不同的模塊可以擁有不同的設置. 模塊中派生 SettingDefinitionProvider 類定義模塊內的配置. 示例如下:

public class EmailSettingProvider : SettingDefinitionProvider
{
    public override void Define(ISettingDefinitionContext context)
    {
        context.Add(
            new SettingDefinition("Smtp.Host", "127.0.0.1"),
            new SettingDefinition("Smtp.Port", "25"),
            new SettingDefinition("Smtp.UserName"),
            new SettingDefinition("Smtp.Password", isEncrypted: true),
            new SettingDefinition("Smtp.EnableSsl", "false")
        );
    }
}

ABP會自動發現並註冊設置的定義。

SettingDefinition

SettingDefinition 類具有以下屬性:

  • Name: 應用程序中設置的唯一名稱. 是具有約束的唯一屬性, 在應用程序獲取/設置此設置的值 (設置名稱定義爲常量而不是magic字符串是個好主意).
  • DefaultValue: 設置的默認值.
  • DisplayName: 本地化的字符串,用於在UI上顯示名稱.
  • Description: 本地化的字符串,用於在UI上顯示描述.
  • IsVisibleToClients: 布爾值,表示此設置是否在客戶端可用. 默認爲false,避免意外暴漏內部關鍵設置.
  • IsInherited: 布爾值,此設置值是否從其他提供程序繼承. 如果沒有爲請求的提供程序設置設定值,那麼默認值是true並回退到下一個提供程序 (參閱設置值提供程序部分了解更多).
  • IsEncrypted: 布爾值,表示是否在保存值是加密,讀取時解密. 在數據庫中存儲加密的值.
  • Providers: 限制可用於特定的設置值提供程序(參閱設置值提供程序部分了解更多).
  • Properties: 設置此值的自定義屬性 名稱/值 集合,可以在之後的應用程序代碼中使用.

更改依賴模塊的設置定義

在某些情況下,你可能希望更改應用程序/模塊所依賴的其他模塊中定義的設置的某些屬性. 設置定義提供程序可以查詢和更新設置定義。

下面的示例中獲取了由 Volo.Abp.Emailing 包定義的設置並將其更改:

public class MySettingDefinitionProvider : SettingDefinitionProvider
{
    public override void Define(ISettingDefinitionContext context)
    {
        var smtpHost = context.GetOrNull("Abp.Mailing.Smtp.Host");
        if (smtpHost != null)
        {
            smtpHost.DefaultValue = "mail.mydomain.com";
            smtpHost.DisplayName =
                new LocalizableString(
                    typeof(MyLocalizationResource),
                    "SmtpServer_DisplayName"
                );
        }
    }
}

使用常量作爲設置名稱是一種好習慣,ABP的包就是這樣做的. Abp.Mailing.Smtp設置名稱是在EmailSettingNames類(在Volo.Abp.Emailing名稱空間中)定義的常量。

讀取設置值

ISettingProvider

ISettingProvider 用於獲取指定設置的值或所有設置的值. 示例用法:

public class MyService
{
    private readonly ISettingProvider _settingProvider;

    //Inject ISettingProvider in the constructor
    public MyService(ISettingProvider settingProvider)
    {
        _settingProvider = settingProvider;
    }

    public async Task FooAsync()
    {
        //Get a value as string.
        string userName = await _settingProvider.GetOrNullAsync("Smtp.UserName");

        //Get a bool value and fallback to the default value (false) if not set.
        bool enableSsl = await _settingProvider.GetAsync<bool>("Smtp.EnableSsl");

        //Get a bool value and fallback to the provided default value (true) if not set.
        bool enableSsl = await _settingProvider.GetAsync<bool>(
            "Smtp.EnableSsl", defaultValue: true);

        //Get a bool value with the IsTrueAsync shortcut extension method
        bool enableSsl = await _settingProvider.IsTrueAsync("Smtp.EnableSsl");

        //Get an int value or the default value (0) if not set
        int port = (await _settingProvider.GetAsync<int>("Smtp.Port"));

        //Get an int value or null if not provided
        int? port = (await _settingProvider.GetOrNullAsync("Smtp.Port"))?.To<int>();
    }
}

ISettingProvider 是非常常用的服務,一些基類中(如IApplicationService)已經將其屬性注入. 這種情況下可以直接使用SettingProvider。

在客戶端讀取設置值

如果允許在客戶端顯示某個設置,可以使用 JavaScript 代碼讀取設置值. 示例:

//Gets a value as string.
var language = abp.setting.get('Abp.Localization.DefaultLanguage');

//Gets an integer value.
var requiredLength = abp.setting.getInt('Abp.Identity.Password.RequiredLength');

//Gets a boolean value.
var requireDigit = abp.setting.getBoolean('Abp.Identity.Password.RequireDigit');

使用 abp.setting.values 可以讀取所有設置值的字典。

設置值提供程序

設置系統是可擴展的, 你可以定義設置值提供程序擴展它,根據任何條件從任何來源獲取設置值。

ISettingProvider 使用設置值提供程序來獲取設置值. 如果值提供程序無法獲取設置值,則會回退到下一個值提供程序。

有五個預構建設置值提供程序按以下順序註冊:

  • DefaultValueSettingValueProvider: 從設置定義的默認值中獲取值(參見上面的SettingDefinition部分)。
  • ConfigurationSettingValueProvider: 從IConfiguration服務中獲取值。
  • GlobalSettingValueProvider: 獲取設置的全局(系統範圍)值。
  • TenantSettingValueProvider: 獲取當前租戶的設置值(參閱 多租戶文檔)。
  • UserSettingValueProvider: 獲取當前用戶的設置值(參閱 當前用戶 文檔)。

設置回退系統從底部 (用戶) 到 (默認) 方向起用用.

全局,租戶和用戶設置值提供程序使用 ISettingStore 從數據源讀取值(參見下面的小節)。

在應用程序配置中設置值

上一節提到 ConfigurationSettingValueProvider 從 IConfiguration 服務中讀取設置, 該服務默認從 appsettings.json 中讀取值. 所以在 appsettings.json 文件中配置設置值是最簡單的方式。

例如你可以像以下方式一樣配置 IEmailSender 設置:

{
  "Settings": {
    "Abp.Mailing.DefaultFromAddress": "[email protected]",
    "Abp.Mailing.DefaultFromDisplayName": "My Application",
    "Abp.Mailing.Smtp.Host": "mail.mydomain.com",
    "Abp.Mailing.Smtp.Port": "547",
    "Abp.Mailing.Smtp.UserName": "myusername",
    "Abp.Mailing.Smtp.Password": "mySecretPassW00rd",
    "Abp.Mailing.Smtp.EnableSsl": "True"
  }
}

設置值應該在 Settings 部分配置,如本例所示。

IConfiguration是.NET Core的服務,它不僅可以從 appsettings.json 中讀取值,還可以從環境,用戶機密...等中讀取值. 有關更多信息請參閱微軟文檔

自定義設置值提供程序

擴展設置系統的方式是定義一個派生自 SettingValueProvider 的類。示例:

public class CustomSettingValueProvider : SettingValueProvider
{
    public override string Name => "Custom";

    public CustomSettingValueProvider(ISettingStore settingStore) 
        : base(settingStore)
    {
    }

    public override Task<string> GetOrNullAsync(SettingDefinition setting)
    {
        /* Return the setting value or null
           Use the SettingStore or another data source */
    }
}

或者你直接可以實現 ISettingValueProvider 接口. 這時需要記得將其註冊到 依賴注入

每一個提供程序都應該具有唯一的名稱 (這裏的名稱是 "Custom" ). 內置提供程序使用給定的名稱:

  • DefaultValueSettingValueProvider: "D".
  • ConfigurationSettingValueProvider: "C".
  • GlobalSettingValueProvider: "G".
  • TenantSettingValueProvider: "T".
  • UserSettingValueProvider: "U".

最好使用一個字母的名稱來減少數據庫中的數據大小(提供者名稱在每行中重複)。

定義自定義設置值提供程序後,需要將其顯式註冊到 AbpSettingOptions:

Configure<AbpSettingOptions>(options =>
{
    options.ValueProviders.Add<CustomSettingValueProvider>();
});

本示例將其添加到最後一項,因此它將成爲ISettingProvider使用的第一個值提供程序. 你也可以將其添加到options.ValueProviders列表的另一個位置。

ISettingStore

儘管設置值提供程序可以自由使用任何來源來獲取設置值,但 ISettingStore 服務是設置值的默認來源。全局,租戶和用戶設置值提供者都使用它。

ISettingEncryptionService

ISettingEncryptionService 用於在設置定義的 isencryption 屬性設置爲 true 時加密/解密設置值。

你可以在依賴項入系統中替換此服務,自定義實現加密/解密過程. 默認實現 StringEncryptionService 使用AES算法。

設置管理模塊

設置系統核心是相當獨立的,不做任何關於如何管理(更改)設置值的假設. 默認的ISettingStore實現也是NullSettingStore,它爲所有設置值返回null。

設置管理模塊通過管理數據庫中的設置值來完成邏輯(實現ISettingStore).有關更多信息參閱設置管理模塊學習更多。

 

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章