|
|
(4 intermediate revisions by the same user not shown) |
Line 3: |
Line 3: |
|
| |
|
| There are following kinds of high-level configuration: | | There are following kinds of high-level configuration: |
| ; [[Implicit Component Configuration]]: Always available. You can set the parameters of components externally (using e.g. environment variables, or ''appsettings.json'' files). The software does not have to be prepared upfront. [[Implicit Component Configuration|Details]] | | ; [[High-Level Intrinsic Configuration]]: Always available. You can set the parameters of the software externally (using e.g. environment variables, or ''appsettings.json'' files). The program does not have to be prepared upfront. [[High-Level Implicit Configuration|Details]] |
| ; Programmatic Component Configuration: Available when you decide to use it. You can instantiate the components while passing them a configuration to use. See the User's Guide for instructions. | | ; Programmatic Component Configuration: Available when you decide to use it. You can instantiate the components while passing them a configuration to use. See the User's Guide for instructions. |
|
| |
|
| See also: [[:Category:Low-Level Configuration|Low-Level Configuration]] | | See also: [[:Category:Low-Level Configuration|Low-Level Configuration]] |
| = Implicit Configuration =
| |
| == Introduction ==
| |
| The parameters of main QuickOPC components can be configured externally, without you having to write a specific code for it. The external configuration can be provided by multiple means, e.g. settings file (such as ''appsettings.json''), environment variables, or Azure App configuration, and the functionality for it is already built-in to the components. This feature belongs to [[:Category:High-Level Configuration|High-Level Configuration]], and allows tweaking of component parameters for experiments, testing, and in production. Its main benefit is that the component parameters can be changed without somebody having to implement the code for it first, and/or without having to change and rebuild the application (which may come really handy if rebuilding the application is not an option for you, e.g. in many restricted production environments).
| |
|
| |
| Where the configuration is read from (the "configuration providers") is determined by the default settings for your application host. For the usual hosts, these defaults are described here:
| |
| * In ASP.NET Core: [https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/ Configuration in ASP.NET Core] (Microsoft).
| |
| * In .NET console apps: [https://docs.microsoft.com/en-us/dotnet/core/extensions/configuration Configuration in .NET] (Microsoft).
| |
| Since this is a standard mechanism used by software libraries and applications, you will be able to place the configuration settings for QuickOPC component alongside with configuration settings for other parts of the software.
| |
|
| |
| By far, the most commonly used configuration provider will probably the [https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/ JSON configuration provider], and you will place your configuration data into the ''appsettings.json'' or ''appsettings.<code>Environment</code>.json'' file (e.g. ''appsettings.Production.json'').
| |
| == Error Handling ==
| |
| All errors that occur when the components read their parameters from the implicit configuration are silently ignored. This behavior was chosen because the reading of the configuration happens at time that is generally unpredictable to the developers (such as inside the static constructors of the components), and exceptions thrown at unpredictable place would have potential to crash the application. When an error occurs, the configuration may be read just partially.
| |
| == Note on Programmatic Component Configuration ==
| |
| The sequence of high-level component configuration evaluation is as follows:
| |
| # The values are set to their (constant, documented) defaults (both static and instance members).
| |
| # Implicit configuration, if present, is applied (this can involve multiple configuration providers in specific sequence). This affects both the static and instance members of the component.
| |
| # If the component supports programmatic component configuration, and the code that creates the component specifies a configuration interface, using a constructor designed for IoC (Inversion of Control), the configuration given by the specified interface is applied (this, again, can involve multiple configuration providers in specific sequence). Only instance members of the component can be configured in this way.
| |
| # The program code can then further modify values of any component parameters.
| |
| As you can see, if the programmatic component configuration or settings the parameters through code is used, the initial values (of instance members) that the component will end up using may be different from what you specify using the implicit component configuration feature.
| |
|
| |
| == Changing the Configuration Providers ==
| |
| If your application requires a set of configuration providers different from the default, you can configure them differently through <code>IHostBuilder</code> interface by accessing the result value of <code>StaticHost.GetHostBuilder()</code> (<code>StaticHost</code> is in the <code>OpcLabs.BaseLib.Extensions.Hosting</code> namespace).
| |
|
| |
| Of course, changing the configuration providers *does* require a code change; the configuration providers cannot be changed externally on an application that is already built.
| |
|
| |
| Some applications built with QuickOPC already add configuration providers over those that are available by default. For example, the [[:Category:OpcCmd Utility|OpcCmd Utility]] adds the INI and XML configuration providers, and you can therefore use configuration files like these in the examples below with the OpcCmd utility.
| |
| === Example: Adding and using the INI configuration provider ===
| |
| For example, to support a possibility to configure component parameters by key pairs from INI files, reference the <code>Microsoft.Extensions.Configurations.Ini</code> NuGet package, and add the following code at the beginning of your program:
| |
| <syntaxhighlight lang="csharp">
| |
| StaticHost.GetHostBuilder().ConfigureAppConfiguration((hostingContext, config) =>
| |
| {
| |
| IHostEnvironment hostEnvironment = hostingContext.HostingEnvironment;
| |
| config
| |
| .AddIniFile("appsettings.ini", optional: true, reloadOnChange: false)
| |
| .AddIniFile($"appsettings.{hostEnvironment.EnvironmentName}.ini",
| |
| optional: true, reloadOnChange: false);
| |
| });
| |
| </syntaxhighlight>
| |
| The contents of the INI file which corresponds to the JSON example given earlier is as follows:
| |
| <syntaxhighlight lang="ini">
| |
| [OpcLabs.EasyOpc.UA.EasyUAClient:InstanceParameters:GdsEndpointDescriptor]
| |
| UrlString="opc.tcp://opcua.demo-this.com:58810/GlobalDiscoveryServer"
| |
| </syntaxhighlight>
| |
| === Example: Adding and using the XML configuration provider ===
| |
| For example, to support a possibility to configure component parameters by elements read from XML files, reference the <code>Microsoft.Extensions.Configurations.Xml</code> NuGet package, and add the following code at the beginning of your program:
| |
| <syntaxhighlight lang="csharp">
| |
| StaticHost.GetHostBuilder().ConfigureAppConfiguration((hostingContext, config) =>
| |
| {
| |
| IHostEnvironment hostEnvironment = hostingContext.HostingEnvironment;
| |
| config
| |
| .AddXmlFile("appsettings.xml", optional: true, reloadOnChange: false)
| |
| .AddXmlFile($"appsettings.{hostEnvironment.EnvironmentName}.xml",
| |
| optional: true, reloadOnChange: false);
| |
| });
| |
| </syntaxhighlight>
| |
| The contents of the XML file which corresponds to the JSON example given earlier is as follows:
| |
| <syntaxhighlight lang="xml">
| |
| <?xml version="1.0" encoding="utf-8" ?>
| |
| <configuration>
| |
| <OpcLabs.EasyOpc.UA.EasyUAClient>
| |
| <InstanceParameters>
| |
| <GdsEndpointDescriptor>
| |
| <UrlString>opc.tcp://opcua.demo-this.com:58810/GlobalDiscoveryServer</UrlString>
| |
| </GdsEndpointDescriptor>
| |
| </InstanceParameters>
| |
| </OpcLabs.EasyOpc.UA.EasyUAClient>
| |
| </configuration>
| |
| </syntaxhighlight>
| |