通过Service Fabric项目进行调试时未使用的环境变量

时间:2016-08-23 19:56:09

标签: c# asp.net-core azure-service-fabric

创建ASP.NET Core应用程序时,将为您设置一个名为ASPNETCORE_ENVIRONMENT=Development的环境变量,在进行调试时,您会看到IHostingEnvironment设置为Development

问题在于,当我在为Service Fabric设置的解决方案中使用相同的项目时,环境变量似乎不会被注入,而IHostingEnvironment只会返回"生产"。

我该如何解决这个问题?

注意:我在启动类中设置了一个断点来观察IHostingEnvironment变量。

3 个答案:

答案 0 :(得分:12)

此答案的参考:https://docs.microsoft.com/en-us/azure/service-fabric/service-fabric-manage-multiple-environment-app-configuration

我遇到了与默认模板相同的问题。以下类似于Duncan的答案,但有两个重要区别:1)您不必更改服务中的任何模板代码,2)IHostingEnvironment将被正确设置。

首先,将ASPNETCORE_ENVIRONMENT变量添加到应用程序服务的<CodePackage>文件的PackageRoot\ServiceManifest.xml元素中:

<CodePackage Name="Code" Version="1.0.0">
  <EntryPoint>
    <ExeHost>
      <Program>MyService.exe</Program>
      <WorkingFolder>CodePackage</WorkingFolder>
    </ExeHost>
  </EntryPoint>
  <EnvironmentVariables>
    <EnvironmentVariable Name="ASPNETCORE_ENVIRONMENT" Value=""/>
  </EnvironmentVariables>
</CodePackage>

与Duncan的回复一样,您将对Service Fabric应用程序项目的ApplicationManifest.xml进行两项更改。首先,设置一个参数(变量),以便在根据部署项目的方式替换ApplicationParameters文件时对其进行修改。然后,在EnvironmentalOverrides元素中添加ServiceManifestImport部分。两个添加的结果将如下所示:

<Parameters>
  <Parameter Name="MyService_InstanceCount" DefaultValue="-1" />
  <Parameter Name="AspNetCoreEnvironment" DefaultValue="" />
</Parameters>

<ServiceManifestImport>
  <ServiceManifestRef ServiceManifestName="MyServicePkg" ServiceManifestVersion="1.0.0" />
  <EnvironmentOverrides CodePackageRef="Code">
    <EnvironmentVariable Name="ASPNETCORE_ENVIRONMENT" Value="[AspNetCoreEnvironment]" />
  </EnvironmentOverrides>
</ServiceManifestImport>

最后,您可以在各个ApplicationParameters文件中添加适当的值:

<Parameters>
  <Parameter Name="MyService_InstanceCount" Value="-1" />
  <Parameter Name="AspNetCoreEnvironment" Value="Development" />
</Parameters>

此时,您可以从服务的属性 - 调试环境变量中删除变量。

答案 1 :(得分:7)

我遇到了同样的问题,并且能够创建一个适合我的解决方案。

如果查看ASP.NET Core项目,您应该看到 Program.cs 文件。在它的底部,您应该看到以下接口实现:

Task<string> ICommunicationListener.OpenAsync(CancellationToken cancellationToken)
{
...
}

您首先要将其更改为以下内容:

Task<string> ICommunicationListener.OpenAsync(CancellationToken cancellationToken)
{
    var context = FabricRuntime.GetActivationContext();
    var endpoint = context.GetEndpoint(_endpointName);
    var config = context.GetConfigurationPackageObject("Config");
    var environment = config.Settings.Sections["Environment"].Parameters["ASPNETCORE_ENVIRONMENT"].Value;

    var serverUrl = $"{endpoint.Protocol}://{FabricRuntime.GetNodeContext().IPAddressOrFQDN}:{endpoint.Port}";

    _webHost = new WebHostBuilder().UseKestrel()
                                   .UseContentRoot(Directory.GetCurrentDirectory())
                                   .UseStartup<Startup>()
                                   .UseEnvironment(environment)
                                   .UseUrls(serverUrl)
                                   .Build();

    _webHost.Start();

    return Task.FromResult(serverUrl);
}

关键部分是.UseEnvironment(environment)调用,以及从配置中支持检索环境。这将为ASP.NET Core提供选择环境所需的必要信息。

完成此操作后,您显然需要将 ASPNETCORE_ENVIRONMENT 设置添加到配置部分。看起来如下:

在您的ASP.NET Core项目下,您将找到名为 PackageRoot / Config 的目录。其中应该有一个 Settings.xml 文件。在<Settings>代码中添加以下代码...

<Section Name="Environment">
  <Parameter Name="ASPNETCORE_ENVIRONMENT" Value="" />
</Section>

接下来,您将要查看实际 Service Fabric项目中的 ApplicationPackageRoot / ApplicationManifest.xml 文件(这不是ASP。 NET核心项目)。需要更改两个文件。

  1. 在文件顶部的<Parameters>标记内添加ASPNETCORE_ENVIRONMENT参数,如下所示:

    <Parameter Name="ASPNETCORE_ENVIRONMENT" DefaultValue="" />
    
  2. 修改您的<ServiceManifestImport>代码以包含<ConfigOverrides>部分,如下所示:

    <ConfigOverrides>
      <ConfigOverride Name="Config">
        <Settings>
          <Section Name="Environment">
            <Parameter Name="ASPNETCORE_ENVIRONMENT" Value="[ASPNETCORE_ENVIRONMENT]" />
          </Section>
        </Settings>
      </ConfigOverride>
    </ConfigOverrides>
    
  3. 最后,修改 ApplicationParameters / Local.1Node.xml 和好友以包含ASPNETCORE_ENVIRONMENT参数:

    <Parameter Name="ASPNETCORE_ENVIRONMENT" Value="Development" />
    

    添加可以检索的怪异变量有很多步骤,但它确实允许您具有很大的灵活性,并遵循标准的Service Fabric模式来简化部署。我希望这有帮助!

答案 2 :(得分:1)

answer from Duncan对我有用,但对我来说有一些变化,可能是由于我使用的ASP.NET Core和Service Fabric版本。

我需要覆盖Web无状态服务中的方法CreateServiceInstanceListeners。 这意味着我将拥有此代码:

protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
{
    return new ServiceInstanceListener[]
    {
        new ServiceInstanceListener(serviceContext =>
            new WebListenerCommunicationListener(serviceContext, "ServiceEndpoint", (url, listener) =>
            {
                ServiceEventSource.Current.ServiceMessage(serviceContext, $"Starting WebListener on {url}");

                var environment = FabricRuntime.GetActivationContext()
                    ?.GetConfigurationPackageObject("Config")
                    ?.Settings.Sections["Environment"]
                    ?.Parameters["ASPNETCORE_ENVIRONMENT"]?.Value;

                return new WebHostBuilder().UseWebListener()
                    .ConfigureServices(
                        services => services
                            .AddSingleton<StatelessServiceContext>(serviceContext))
                    .UseContentRoot(Directory.GetCurrentDirectory())
                    .UseStartup<Startup>()
                    .UseEnvironment(environment)
                    .UseApplicationInsights()
                    .UseUrls(url)
                    .Build();
            }))
    };
}

当然,您需要按照Duncan的说明设置ASPNETCORE_ENVIRONMENT变量。