In my Azure Service Fabric Web API project, I am able to add my appsettings.json files to my config using this code in my Api.cs
class:
protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
{
return new ServiceInstanceListener[]
{
new ServiceInstanceListener(serviceContext =>
new KestrelCommunicationListener(serviceContext, "ServiceEndpoint", (url, listener) =>
{
ServiceEventSource.Current.ServiceMessage(serviceContext, $"Starting Kestrel on {url}");
return new WebHostBuilder()
.UseKestrel()
.ConfigureAppConfiguration((builderContext, config) =>
{
var env = builderContext.HostingEnvironment;
config.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
.AddEnvironmentVariables();
})
.ConfigureServices((hostingContext, services) => services
.AddSingleton<StatelessServiceContext>(serviceContext)
.AddApplicationInsightsTelemetry(hostingContext.Configuration))
.UseContentRoot(Directory.GetCurrentDirectory())
.UseStartup<Startup>()
.UseServiceFabricIntegration(listener, ServiceFabricIntegrationOptions.None)
.UseUrls(url)
.Build();
}))
};
}
The env.ContentRootPath
contains this value:
C:\SfDevCluster\Data\_App\_Node_0\Abc.IntegrationType_App197\Abc.Integration.ApiPkg.Code.1.0.0
In this folder I can see the appsettings.json files.
However, in my Azure Service Fabric Stateless Service project, I have this code in my Service.cs
class:
protected override async Task RunAsync(CancellationToken cancellationToken)
{
Microsoft.AspNetCore.WebHost.CreateDefaultBuilder()
.ConfigureAppConfiguration((builderContext, config) =>
{
var env = builderContext.HostingEnvironment;
var appName = AppDomain.CurrentDomain.FriendlyName;
var parentFolderPath = Directory.GetParent(env.ContentRootPath).FullName;
var packageCodeFolderPath = Path.Combine(parentFolderPath, appName + "Pkg.Code.1.0.0");
config.SetBasePath(packageCodeFolderPath)
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
.AddEnvironmentVariables();
})
.UseStartup<Startup>()
.Build()
.Run();
}
Here env.ContentRootPath
contains this value:
C:\SfDevCluster\Data\_App\_Node_0\Abc.Integration.OpticalType_App198\work
However because the appsettings.json
files are located in:
C:\SfDevCluster\Data\_App\_Node_0\Abc.Integration.OpticalType_App198\Abc.Integration.Optical.ServicePkg.Code.1.0.0
,
I'm forced to construct the packageCodeFolderPath
variable you can see above.
This doesn't seem like a very elegant solution, and I'm worried the version number in Pkg.Code.1.0.0
might change (if that is even a version number?).
How can I set env.ContentRootPath
to be the path to the folder containing the appsettings.json
files? Or is there a better way to go about accessing these files?
In your service manifest, you should set the WorkingFolder
to CodePackage
to have the ContentRootPath set to the code Abc.Integration.Optical.ServicePkg.Code.1.0.0
instead of work
.
i.e:
<EntryPoint>
<ExeHost>
<Program>myapp.exe</Program>
<WorkingFolder>CodePackage</WorkingFolder>
</ExeHost>
</EntryPoint>
Check the docs here
Other option is get the information from the environment variables set by SF. Take a look in here: https://learn.microsoft.com/en-us/azure/service-fabric/service-fabric-environment-variables-reference
Or, use the context.CodePackageActivationContext.WorkDirectory
as suggested by Loek in his answer.