配置管理

注意

本电子书于 2017 年春季出版,之后再未更新。 书中有许多内容仍然很有价值,但有些材料已经过时。

设置允许将配置应用行为的数据与代码分离,从而允许在不重新生成应用的情况下更改行为。 设置分为两种类型:应用设置和用户设置。

应用设置是应用创建和管理的数据。 它可以包括固定 Web 服务终结点、API 密钥和运行时状态等数据。 应用设置与应用的存在相关,并且仅对该应用有意义。

用户设置是应用的可自定义设置,可影响应用行为,不需要频繁重新调整。 例如,应用可能允许用户指定检索数据的位置以及在屏幕上显示数据的方式。

Xamarin.Forms 包括可用于存储设置数据的永久性字典。 可以使用 Application.Current.Properties 属性访问此字典,当应用程序进入睡眠状态时,系统会保存放入其中的任何数据,并在应用程序恢复或再次启动时恢复。 此外,Application 类还具有一种 SavePropertiesAsync 方法,此方法允许应用程序按需保存其设置。 有关此字典的详细信息,请参阅“属性字典”。

使用 Xamarin.Forms 永久性字典存储数据的缺点是,系统不能轻松地将其绑定到数据。 因此,eShopOnContainers 移动应用使用 NuGet 提供的 Xam.Plugins.Settings 库。 此库提供一致、类型安全、跨平台的方法来保留和检索应用和用户设置,同时使用每个平台提供的本机设置管理。 此外,使用数据绑定访问库公开的设置数据也很简单。

注意

虽然 Xam.Plugin.Settings 库可以存储应用和用户设置,但两者之间没有区别。

创建 Settings 类

使用 Xam.Plugins.Settings 库时,应创建一个静态类,其中包含应用所需的应用和用户设置。 以下代码示例演示了 eShopOnContainers 移动应用中的 Settings 类:

public static class Settings  
{  
    private static ISettings AppSettings  
    {  
        get  
        {  
            return CrossSettings.Current;  
        }  
    }  
    ...  
}

可以通过 ISettings API 读取和写入设置,该 API 由 Xam.Plugins.Settings 库提供。 该库提供了一个可用于访问 API 的单一实例 CrossSettings.Current,同时应用程序的 Settings 类应通过 ISettings 属性公开此单一实例。

注意

应将 Plugin.Settings 和 Plugin.Settings.Abstractions 命名空间的 using 指令添加到需要访问 Xam.Plugins.Settings 库类型的类中。

添加设置

每个设置都包含一个键、一个默认值和一个属性。 以下代码示例显示了用户设置的所有三个项目,该设置表示 eShopOnContainers 移动应用连接到的联机服务的基 URL:

public static class Settings  
{  
    ...  
    private const string IdUrlBase = "url_base";  
    private static readonly string UrlBaseDefault = GlobalSetting.Instance.BaseEndpoint;  
    ...  

    public static string UrlBase  
    {  
        get  
        {  
            return AppSettings.GetValueOrDefault<string>(IdUrlBase, UrlBaseDefault);  
        }  
        set  
        {  
            AppSettings.AddOrUpdateValue<string>(IdUrlBase, value);  
        }  
    }  
}

键始终是定义键名称的常量字符串,设置的默认值是所需类型的静态只读值。 提供默认值可确保在检索到未设置的设置时有效值可用。

UrlBase 静态属性使用 ISettings API 中的两种方法来读取或写入设置值。 ISettings.GetValueOrDefault 方法用于从特定于平台的存储中检索设置的值。 如果没有为该设置定义值,则会检索其默认值。 同样,ISettings.AddOrUpdateValue 该方法用于将设置的值保存到特定于平台的存储。

UrlBaseDefault 字符串不是在 Settings 类中定义默认值,而是从 GlobalSetting 类中获取其值。 以下代码示例显示了此类中的 BaseEndpoint 属性和 UpdateEndpoint 方法:

public class GlobalSetting  
{  
    ...  
    public string BaseEndpoint  
    {  
        get { return _baseEndpoint; }  
        set  
        {  
            _baseEndpoint = value;  
            UpdateEndpoint(_baseEndpoint);  
        }  
    }  
    ...  

    private void UpdateEndpoint(string baseEndpoint)  
    {  
        RegisterWebsite = string.Format("{0}:5105/Account/Register", baseEndpoint);  
        CatalogEndpoint = string.Format("{0}:5101", baseEndpoint);  
        OrdersEndpoint = string.Format("{0}:5102", baseEndpoint);  
        BasketEndpoint = string.Format("{0}:5103", baseEndpoint);  
        IdentityEndpoint = string.Format("{0}:5105/connect/authorize", baseEndpoint);  
        UserInfoEndpoint = string.Format("{0}:5105/connect/userinfo", baseEndpoint);  
        TokenEndpoint = string.Format("{0}:5105/connect/token", baseEndpoint);  
        LogoutEndpoint = string.Format("{0}:5105/connect/endsession", baseEndpoint);  
        IdentityCallback = string.Format("{0}:5105/xamarincallback", baseEndpoint);  
        LogoutCallback = string.Format("{0}:5105/Account/Redirecting", baseEndpoint);  
    }  
}

每次设置 BaseEndpoint 属性时,系统都会调用 UpdateEndpoint 方法。 此方法会更新一系列属性,所有这些属性都基于 Settings 类提供的 UrlBase 用户设置,这些设置表示 eShopOnContainers 移动应用会连接到的不同终结点。

数据绑定到用户设置

在 eShopOnContainers 移动应用中,SettingsView 会公开两个用户设置。 通过使用这些设置,可配置应用程序是否应从部署为 Docker 容器的微服务中检索数据,或者应用程序是否应从不需要 Internet 连接的模拟服务中检索数据。 选择从容器化微服务检索数据时,必须指定微服务的基本终结点 URL。 图 7-1 显示了用户选择从容器化微服务检索数据时的 SettingsView

User settings exposed by the eShopOnContainers mobile app

图 7-1:eShopOnContainers 移动应用公开的用户设置

数据绑定可用于检索和设置 Settings 类公开的设置。 这是通过将视图绑定到视图模型属性的控件来实现的,这些属性依次访问 Settings 类中的属性,并在值发生更改时发出属性更改通知。 有关 eShopOnContainers 移动应用如何构造视图模型并将其关联到视图的信息,请参阅使用视图模型定位符自动创建视图模型

以下代码示例显示了 SettingsView 中的 Entry 控件,该控件允许用户输入容器化微服务的基本终结点 URL:

<Entry Text="{Binding Endpoint, Mode=TwoWay}" />

Entry 控件使用双向绑定绑定到 SettingsViewModel 类的 Endpoint 属性。 以下代码示例显示了终结点属性:

public string Endpoint  
{  
    get { return _endpoint; }  
    set  
    {  
        _endpoint = value;  

        if(!string.IsNullOrEmpty(_endpoint))  
        {  
            UpdateEndpoint(_endpoint);  
        }  

        RaisePropertyChanged(() => Endpoint);  
    }  
}

设置 Endpoint 属性时,如果提供的值有效,则调用 UpdateEndpoint 方法,这会触发属性更改通知。 下面的代码示例说明 UpdateEndpoint 方法:

private void UpdateEndpoint(string endpoint)  
{  
    Settings.UrlBase = endpoint;  
}

此方法使用用户输入的基本终结点 URL 值更新 Settings 类中的 UrlBase 属性,从而使其永久保存到特定于平台的存储中。

导航到 SettingsView 时,系统会执行 SettingsViewModel 类中的 InitializeAsync 方法。 下面的代码示例演示此方法:

public override Task InitializeAsync(object navigationData)  
{  
    ...  
    Endpoint = Settings.UrlBase;  
    ...  
}

该方法将 Endpoint 属性设置为 Settings 类中 UrlBase 属性的值。 访问 UrlBase 属性会使 Xam.Plugins.Settings 库从特定于平台的存储中检索设置值。 有关如何调用 InitializeAsync 方法的信息,请参阅在导航过程中传递参数

此机制可确保每当用户导航到 SettingsView 时,都会从特定于平台的存储中检索用户设置并通过数据绑定呈现。 然后,如果用户更改设置值,数据绑定可确保它们立即保留回特定于平台的存储。

总结

设置允许将配置应用行为的数据与代码分离,从而允许在不重新生成应用的情况下更改行为。 应用设置是应用创建和管理的数据,而用户设置是应用的可自定义设置,可影响应用行为,不需要频繁重新调整。

Xam.Plugins.Settings 库提供了一致、类型安全、跨平台的方法来保存和检索应用程序和用户设置,并且数据绑定可用于访问使用该库创建的设置。