Inside Service Fabric Я вообще не использую appsetings. Я придерживаюсь подхода, в котором все параметры всех служб хранятся в одном месте, а именно ApplicationPackageRoot / ApplicationManifest.xml внутри проекта Service Fabric.
Так, например, если у меня есть две службы, 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>
Во время развертывания приложения вы просто указываете, какой файл вы хотите использовать.
Теперь, чтобы использовать config внутри сервиса, вам нужно изменить файл 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, чтобы вы могли использовать его в других классах:
.ConfigureServices(services => services
.AddSingleton<IConfigSettings>(new ConfigSettings(serviceContext)))
EDIT:
Если у вас есть свой конфиг в основном контейнере IoC asp.net, вы можете использовать его путем внедрения конструктора следующим образом:
public class TestClass
{
private readonly IConfigSettings _config;
public TestClass(IConfigSettings config)
{
_config = config;
}
public string TestMethod()
{
return _config.TestServiceName;
}
}