¿Dónde establece y accede a los parámetros de configuración en tiempo de ejecución por entorno para la estructura de servicio?

82

Para dos entornos, local y en la nube, ¿cómo configuraría configuraciones o parámetros personalizados para recursos como bases de datos SQL, cuentas de almacenamiento, etc.? Idealmente, sería un nombre de parámetro llamado en el código para decir, apuntar un DbContext hacia un particular base de datos, que en configuraciones para un entorno local o en la nube sea diferente. Gracias.

StampyTurtle
fuente
Aunque me gustaría que incluyeran el código de la aplicación para utilizar realmente la configuración, Microsoft muestra cómo configurarlo en el siguiente artículo: docs.microsoft.com/en-us/azure/service-fabric/…
Adam Plocher

Respuestas:

144

Para tener por variables de entorno para ejecutar Service Fabric localmente y en la nube, esto es lo que debe hacer:

  1. Agregue su sección de configuración personalizada y parámetros al archivo Settings.xml del proyecto de Servicio / Actor (ubicado en \ PackageRoot \ Config \ Settings.xml desde la raíz del proyecto). Deje los parámetros en blanco, ya que los configuraremos en otro lugar por entorno. Aquí hay un ejemplo.
<?xml version="1.0" encoding="utf-8" ?>
<Settings xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/2011/01/fabric">
<!-- Add your custom configuration sections and parameters here -->
    <Section Name="UserDatabase">
        <Parameter Name="UserDatabaseConnectionString" Value="" />
    </Section>
</Settings>
  1. En el archivo ApplicationManifest.xml de su proyecto de Service Fabric, habrá <ServiceManifestImport>elementos para cada uno de sus proyectos incluidos. Debajo habrá un <ConfigOverrides>elemento donde declararemos qué valores para nuestras configuraciones serán suplantados por los valores establecidos por entorno en los archivos xml local y en la nube debajo de ApplicationParameters en nuestro proyecto de Service Fabric. En ese mismo archivo ApplicationManifest.xml, deberá agregar el parámetro que estará presente en los archivos xml local y en la nube; de ​​lo contrario, se sobrescribirán en la compilación.

Continuando con el ejemplo anterior, así se configuraría.

<Parameters>
    <Parameter Name="ServiceName_InstanceCount" DefaultValue="-1" />
    <Parameter Name="UserDatabaseConnectionString" DefaultValue="" />
</Parameters>
<ConfigOverrides>
    <ConfigOverride Name="Config">
        <Settings>
            <Section Name="UserDatabase">
                <Parameter Name="UserDatabaseConnectionString" Value="[UserDatabaseConnectionString]" />
            </Section>
        </Settings>
    </ConfigOverride>
</ConfigOverrides>
  1. En los archivos local.xml y cloud.xml debajo de ApplicationParameters en su proyecto de Service Fabric, especificará las variables específicas de su entorno así.
<?xml version="1.0" encoding="utf-8"?>
<Application xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Name="fabric:/AppFabricName.ServiceFabric" xmlns="http://schemas.microsoft.com/2011/01/fabric">
    <Parameters>
        <Parameter Name="ServiceName_InstanceCount" Value="1" />
        <Parameter Name="UserDatabaseConnectionString" Value="Server=(localdb)\MsSqlLocalDb;Database=Users;User=ReadOnlyUser;Password=XXXXX;" />
    </Parameters>
</Application>
  1. Finalmente, en su Servicio / Actor puede acceder a estas variables de configuración por entorno como tal.
var configurationPackage = Context.CodePackageActivationContext.GetConfigurationPackageObject("Config");

var connectionStringParameter = configurationPackage.Settings.Sections["UserDatabase"].Parameters["UserDatabaseConnectionString"];
StampyTurtle
fuente
100
¿Puedo decir "¡puaj!". Esto es irremediablemente complicado para un entorno simple basado en el entorno. Esto está listo para un esfuerzo de desarrollo del equipo SF.
BrettRobi
No estoy seguro de lo que me estoy perdiendo, pero mi contexto no tiene un CodePackageActivationContext. Veo en mis servicios sin estado que se pasa en el constructor a OwinCommunicationListener. Pero no estoy seguro de dónde conseguirlo en Actor.
Steve
7
Preguntado prematuramente. Los comentarios aquí: azure.microsoft.com/en-us/documentation/articles/… Apunta a usar esto: CodePackageActivationContext activaciónContext = FabricRuntime.GetActivationContext ();
Steve
11
Esto es mucho mejor que la documentación real, ¡gracias! También acordé que es muy complicado ... ¡arregla este equipo de SF!
naspinski
2
Estaba teniendo un problema en el que estas configuraciones no se anulaban. Tienes que definir los parámetros arriba ServiceManifestImport(hijo de ApplicationManifest) pero ConfigOverridestienes que ir en él (hijo de ServiceManifestImport).
Mardoxx
42

Puede usar variables de entorno como cualquier otra aplicación, esto también funciona con el ejecutable invitado dentro de la estructura de servicio, a diferencia de settings.xmlesto, ya que requiere el tiempo de ejecución de la estructura de servicio integrado.

Dentro de su aplicación, puede acceder a las variables de entorno como cualquier otra aplicación .net a través del GetEnvironmentVariablemétodo de la Environmentclase:

var baseUri = Environment.GetEnvironmentVariable("SuperWebServiceBaseUri");

Luego, necesitamos configurar algunos valores de variables de entorno predeterminados, esto se hace dentro del ServiceManifest.xmlarchivo de manifiesto del servicio.

<?xml version="1.0" encoding="utf-8" ?>
<ServiceManifest Name="MyServicePkg" Version="1.0.0" xmlns="http://schemas.microsoft.com/2011/01/fabric" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <!-- snip -->
    <CodePackage Name="Code" Version="1.0.0">
        <!-- snip -->
        <EnvironmentVariables>
            <EnvironmentVariable Name="SuperWebServiceBaseUri" Value="http://localhost:12345"/>
        </EnvironmentVariables>
    </CodePackage>
    <!-- snip -->
</ServiceManifest>

Luego, estas variables de entorno se pueden anular dentro del ApplicationManifest.xmlarchivo mediante el siguiente código:

<?xml version="1.0" encoding="utf-8"?>
<ApplicationManifest xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ApplicationTypeName="ChileTargetType" ApplicationTypeVersion="1.0.0" xmlns="http://schemas.microsoft.com/2011/01/fabric">
    <Parameters>
        <!-- snip -->
    </Parameters>
    <ServiceManifestImport>
        <ServiceManifestRef ServiceManifestName="MyServicePkg" ServiceManifestVersion="1.0.0" />
        <EnvironmentOverrides CodePackageRef="Code">
            <EnvironmentVariable Name="SuperWebServiceBaseUri" Value="https://the-real-live-super-base-uri.com/"/>
        </EnvironmentOverrides>
    </ServiceManifestImport>
    <!-- snip -->
</ApplicationManifest>

Esto luego se puede parametrizar como cualquier otra configuración de manifiesto de aplicación utilizando local.xmly cloud.xml.

<?xml version="1.0" encoding="utf-8"?>
<Application xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Name="fabric:/AppFabricName.ServiceFabric" xmlns="http://schemas.microsoft.com/2011/01/fabric">
    <Parameters>
        <Parameter Name="MyService_SuperWebServiceBaseUri" Value="https://another-base-uri.com/" />
    </Parameters>
</Application>

Entonces tendremos que actualizar el ApplicationManifest.xmlpara admitir estos parámetros;

<?xml version="1.0" encoding="utf-8"?>
<ApplicationManifest xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ApplicationTypeName="ChileTargetType" ApplicationTypeVersion="1.0.0" xmlns="http://schemas.microsoft.com/2011/01/fabric">
    <Parameters>
        <Parameter Name="MyService_SuperWebServiceBaseUri" DefaultValue="https://the-real-live-super-base-uri.com/" />
    </Parameters>
    <ServiceManifestImport>
        <ServiceManifestRef ServiceManifestName="MyServicePkg" ServiceManifestVersion="1.0.0" />
        <EnvironmentOverrides CodePackageRef="Code">
            <EnvironmentVariable Name="SuperWebServiceBaseUri" Value="[MyService_SuperWebServiceBaseUri]"/>
        </EnvironmentOverrides>
    </ServiceManifestImport>
    <!-- snip -->
</ApplicationManifest>
Kevin Smith
fuente
2
Una forma más ordenada de establecer la variable de entorno
hungryMind
2
Este enlace también me ayudó: binaryradix.com/2016/10/…
Darrel K.
7

Las respuestas anteriores explican bien cómo se hace. Quiero agregar una marca lateral, por qué es tan ' complicado ':

Tiene que ser así, ya que los servicios están destinados a ser autónomos. Deben ejecutarse de forma predeterminada en cualquier aplicación a la que estén vinculados. Independiente del Manifiesto de la aplicación. Por lo tanto, el servicio solo puede depender de parámetros, que al menos están predefinidos en su propia configuración.

La aplicación puede sobrescribir estos ajustes predeterminados. Este es el único enfoque universal.

BaluJr.
fuente