问题
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?
回答1:
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://docs.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.
回答2:
I recommend using the serviceContext
property CodePackageActivationContext
to locate the SF work folder and use that as your point of reference. (The value of Environment.CurrentDirectory
varies on 1 node vs 5 node cluster, so it's unreliable.)
So use:
context.CodePackageActivationContext.WorkDirectory
The CodePackageActivationContext
also holds the code package version string (which is indeed a version definition).
来源:https://stackoverflow.com/questions/55822261/how-does-ihostingenvironment-contentrootpath-get-set