Как устанавливается IHostingEnvironment.ContentRootPath? - PullRequest
2 голосов
/ 24 апреля 2019

В моем проекте веб-API Azure Service Fabric я могу добавить файлы appsettings.json в свою конфигурацию, используя этот код в моем классе Api.cs:

    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();
                }))
        };
    }

env.ContentRootPath содержит это значение:

C:\SfDevCluster\Data\_App\_Node_0\Abc.IntegrationType_App197\Abc.Integration.ApiPkg.Code.1.0.0

В этой папке я вижу файлы appsettings.json.

Однако в моем проекте Azure Service Fabric Stateless Service этот код содержится в моем Service.cs классе:

    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();
    }

Здесь env.ContentRootPath содержит это значение:

C:\SfDevCluster\Data\_App\_Node_0\Abc.Integration.OpticalType_App198\work

Однако, поскольку файлы appsettings.json находятся в: C:\SfDevCluster\Data\_App\_Node_0\Abc.Integration.OpticalType_App198\Abc.Integration.Optical.ServicePkg.Code.1.0.0

Я вынужден создать переменную packageCodeFolderPath, которую вы видите выше.

Это не похоже на очень элегантное решение, и я беспокоюсь, что номер версии в Pkg.Code.1.0.0 может измениться (если это даже номер версии?).

Как установить env.ContentRootPath в качестве пути к папке, содержащей файлы appsettings.json? Или есть лучший способ получить доступ к этим файлам?

Ответы [ 2 ]

2 голосов
/ 25 апреля 2019

В вашем сервисном манифесте вы должны установить для WorkingFolder значение CodePackage, чтобы ContentRootPath установил код Abc.Integration.Optical.ServicePkg.Code.1.0.0 вместо work.

т.е:

<EntryPoint>
  <ExeHost>
    <Program>myapp.exe</Program>
    <WorkingFolder>CodePackage</WorkingFolder>
  </ExeHost>
</EntryPoint>

Проверьте документы здесь

Другой вариант - получить информацию из переменных среды, установленных SF. Посмотрите здесь: https://docs.microsoft.com/en-us/azure/service-fabric/service-fabric-environment-variables-reference

Или используйте context.CodePackageActivationContext.WorkDirectory, как подсказал Лук в своем ответе.

1 голос
/ 24 апреля 2019

Я рекомендую использовать свойство serviceContext CodePackageActivationContext, чтобы найти рабочую папку SF и использовать ее в качестве ориентира.(Значение Environment.CurrentDirectory зависит от кластера 1 узла против 5, поэтому оно ненадежно.)

Поэтому используйте: context.CodePackageActivationContext.WorkDirectory

CodePackageActivationContext также содержит пакет кода version string (это действительно определение версии).

...