Как получить доступ к appsettings.json из службы состояний без Azure Service Fabric - PullRequest
1 голос
/ 22 апреля 2019

У меня есть решение с проектом службы без сохранения состояния (.sfproj) и соответствующим проектом консольного приложения.

Я добавил appsettings.json в проект консольного приложения и пытаюсь настроить доступ к нему с помощьюthis:

protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
{
    //return this.CreateServiceRemotingInstanceListeners(); //This line works
    return new ServiceInstanceListener[] //This line causes an error in Service Fabric Explorer
    {
        new ServiceInstanceListener(serviceContext =>
            new KestrelCommunicationListener(serviceContext, "ServiceEndpoint", (url, listener) =>
            {
                ServiceEventSource.Current.ServiceMessage(serviceContext, $"Starting Kestrel on {url}");

                return new WebHostBuilder()
                    .UseKestrel()
                    .ConfigureAppConfiguration((builderContext, config) =>
                    {
                        config.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
                    })
                    .ConfigureServices(
                        services => services
                            .AddSingleton<StatelessServiceContext>(serviceContext))
                    .UseContentRoot(Directory.GetCurrentDirectory())
                    //.UseStartup<Startup>() //Startup.cs does not exist
                    .UseServiceFabricIntegration(listener, ServiceFabricIntegrationOptions.None)
                    .UseUrls(url)
                    .Build();
            }))
    };
}

Это не компилируется, потому что у меня нет класса Startup, так как это не проект веб-API, он использует службу без сохранения состояния.Единственные классы, которые у меня есть в консольном приложении, это Program.cs, Service.cs и ServiceEventSource.cs

. Я попытался удалить .UseStartup<Startup>(), чтобы заставить его скомпилироваться, однако при запуске приложения я получаюСледующая ошибка в Service Fabric Explorer:

'System.FM' reported Error for property 'State'.
Partition is below target replica or instance count.
fabric:/Integration/Integration.Service 1 1 9810816d-5be9-4b53-9eed-c5be403219b0
  InBuild _Node_1 132003711574580709
  (Showing 1 out of 1 instances. Total available instances: 0)

Я могу исправить это с помощью return this.CreateServiceRemotingInstanceListeners();, однако тогда я не знаю, как настроить доступ к appsettings.json.

Как я могу получить доступ к appsettings.json из службы без сохранения состояния?

РЕДАКТИРОВАТЬ:

Мне удалось заставить его работать, используя это в Service.cs:

        protected override async Task RunAsync(CancellationToken cancellationToken)
        {
            Microsoft.AspNetCore.WebHost.CreateDefaultBuilder()
                .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();
                })
                .UseStartup<Startup>()
                .Build()
                .Run();
        }

Я добавил это к ServiceManifest.xml, чтобы убедиться, что env.ContentRootPath указывает на папку пакета кода, содержащую файлы appsettings.json (по умолчанию, как представляется, рабочая папка пуста для меня):

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

Я добавил этот Startup класс:

public class Startup
{
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    { }
}

Мне кажется, что должен быть лучший способ доступа к appsettings.json, особенно учитывая, что метод Startup.Configure() ничего не делает.

Кто-нибудь знает лучший способ доступа appsettings.json?

1 Ответ

0 голосов
/ 23 апреля 2019

это происходит потому, что вы должны указать имя сборки, на которой выполняется точка входа приложения. В документах объясняется, как следует устанавливать.

Когда вы используете .UseStartup<Startup>(), он получает информацию о сборке из класса Startup, поскольку у вас его нет, он не знает, где находится точка входа.

Эта проблема github и this показывает похожие проблемы.

Вот пример, который я получил от одного из моих приложений, работающих в SF:

        var builder = new WebHostBuilder()
            .UseKestrel()
            .UseContentRoot(Directory.GetCurrentDirectory())
            .ConfigureServices(services => services.AddSingleton(startup))
            .UseApplicationInsights()
            .UseSetting(WebHostDefaults.ApplicationKey, startup.GetType().Assembly.FullName);

В приведенном выше примере startup является экземпляром класса, который реализует Microsoft.AspNetCore.Hosting.IStartup со следующими методами:

    void Configure(IApplicationBuilder app);
    IServiceProvider ConfigureServices(IServiceCollection services);

PS: Вы не используете .UseStartup<Startup>() в приведенном выше примере, но вы могли бы использовать его в проекте.

...