在 Service Fabric 内部,我根本不使用应用设置。我遵循的方法是将所有服务的每个设置都保存在一个位置,即 Service Fabric 项目中的 ApplicationPackageRoot/ApplicationManifest.xml。
例如,如果我有两个服务,ApplicationManifest 可能如下所示:
<?xml version="1.0" encoding="utf-8"?>
<ApplicationManifest xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ApplicationTypeName="TestAppType"
ApplicationTypeVersion="1.0.0" xmlns="http://schemas.microsoft.com/2011/01/fabric">
<Parameters>
<Parameter Name="Environment" DefaultValue="" />
<Parameter Name="TestWebApi_InstanceCount" DefaultValue="" />
<Parameter Name="TestServiceName" DefaultValue="TestService" />
<Parameter Name="TestService_InstanceCount" DefaultValue="" />
</Parameters>
<ServiceManifestImport>
<ServiceManifestRef ServiceManifestName="TestServicePkg" ServiceManifestVersion="1.0.0" />
<ConfigOverrides>
<ConfigOverride Name="Config">
<Settings>
<Section Name="General">
<Parameter Name="Environment" Value="[Environment]" />
<Parameter Name="TestServiceName" Value="[TestServiceName]" />
</Section>
</Settings>
</ConfigOverride>
</ConfigOverrides>
</ServiceManifestImport>
<ServiceManifestImport>
<ServiceManifestRef ServiceManifestName="TestWebApiPkg" ServiceManifestVersion="1.0.0" />
<ConfigOverrides>
<ConfigOverride Name="Config">
<Settings>
<Section Name="General">
<Parameter Name="Environment" Value="[Environment]" />
</Section>
</Settings>
</ConfigOverride>
</ConfigOverrides>
</ServiceManifestImport>
<DefaultServices>
<Service Name="TestService" ServicePackageActivationMode="ExclusiveProcess">
<StatelessService ServiceTypeName="TestServiceType" InstanceCount="[TestService_InstanceCount]">
<SingletonPartition />
</StatelessService>
</Service>
<Service Name="TestWebApi" ServicePackageActivationMode="ExclusiveProcess">
<StatelessService ServiceTypeName="TestWebApiType" InstanceCount="[TestWebApi_InstanceCount]">
<SingletonPartition />
</StatelessService>
</Service>
</DefaultServices>
</ApplicationManifest>
我只是将用于应用程序的参数定义以及每个服务的特定配置放在那里。下一步是为您放置实际值的每个环境准备应用程序参数文件,例如 Dev.xml:
<?xml version="1.0" encoding="utf-8"?>
<Application xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Name="fabric:/TestApp" xmlns="http://schemas.microsoft.com/2011/01/fabric">
<Parameters>
<Parameter Name="Environment" Value="Dev" />
<Parameter Name="TestWebApi_InstanceCount" Value="1" />
<Parameter Name="TestServiceName" Value="TestService" />
<Parameter Name="TestService_InstanceCount" Value="-1" />
</Parameters>
</Application>
在应用程序部署期间,您只需指定要使用的文件。
现在要在服务中使用配置,您需要为每个服务修改 PackageRoot/Config/Settings.xml 文件:
<?xml version="1.0" encoding="utf-8" ?>
<Settings xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/2011/01/fabric">
<Section Name="General">
<Parameter Name="Environment" Value=""/>
<Parameter Name="TestServiceName" Value=""/>
</Section>
</Settings>
同样,您没有在此处指定值,它们将从 ApplicationManifest 中获取。您只需告诉您要将哪一个用于特定服务。
现在是代码。我创建了帮助类来检索配置值:
public class ConfigSettings : IConfigSettings
{
public ConfigSettings(StatelessServiceContext context)
{
context.CodePackageActivationContext.ConfigurationPackageModifiedEvent += this.CodePackageActivationContext_ConfigurationPackageModifiedEvent;
UpdateConfigSettings(context.CodePackageActivationContext.GetConfigurationPackageObject("Config").Settings);
}
private void CodePackageActivationContext_ConfigurationPackageModifiedEvent(object sender, PackageModifiedEventArgs<ConfigurationPackage> e)
{
this.UpdateConfigSettings(e.NewPackage.Settings);
}
public string Environment { get; private set; }
public string TestServiceName { get; private set; }
private void UpdateConfigSettings(ConfigurationSettings settings)
{
var generalSectionParams = settings.Sections["General"].Parameters;
Environment = generalSectionParams["Environment"].Value;
TestServiceName = generalSectionParams["TestServiceName"].Value;
}
}
public interface IConfigSettings
{
string Environment { get; }
string TestServiceName { get; }
}
这个类还有一个事件订阅,如果它在服务运行时被更改,它将更新配置。
剩下的就是在启动过程中使用服务上下文初始化你的ConfigSettings,并将它添加到内置的 ASP.NET CORE Container 中,以便你可以在其他类中使用它:
.ConfigureServices(services => services
.AddSingleton<IConfigSettings>(new ConfigSettings(serviceContext)))
编辑:
在 asp.net core IoC Container 中配置好配置后,您可以像这样通过构造函数注入来使用它:
public class TestClass
{
private readonly IConfigSettings _config;
public TestClass(IConfigSettings config)
{
_config = config;
}
public string TestMethod()
{
return _config.TestServiceName;
}
}