From 3d5e2a99da6b977aeec763be4447e54d68c8e96a Mon Sep 17 00:00:00 2001 From: Richard Webb Date: Sun, 31 Dec 2023 14:22:26 +0000 Subject: [PATCH] Experiment: Separate out the System.Configuration.ConfigurationManager support --- Argu.slnx | 1 + .../Argu.ConfigurationManager.fsproj | 22 +++++++++ src/Argu.ConfigurationManager/Library.fs | 49 +++++++++++++++++++ src/Argu/Argu.fsproj | 3 +- src/Argu/ArgumentParser.fs | 2 +- src/Argu/ConfigReaders.fs | 38 -------------- tests/Argu.Tests/Argu.Tests.fsproj | 3 +- 7 files changed, 76 insertions(+), 42 deletions(-) create mode 100644 src/Argu.ConfigurationManager/Argu.ConfigurationManager.fsproj create mode 100644 src/Argu.ConfigurationManager/Library.fs diff --git a/Argu.slnx b/Argu.slnx index 998efbc..d7c697a 100644 --- a/Argu.slnx +++ b/Argu.slnx @@ -43,4 +43,5 @@ + diff --git a/src/Argu.ConfigurationManager/Argu.ConfigurationManager.fsproj b/src/Argu.ConfigurationManager/Argu.ConfigurationManager.fsproj new file mode 100644 index 0000000..250b17d --- /dev/null +++ b/src/Argu.ConfigurationManager/Argu.ConfigurationManager.fsproj @@ -0,0 +1,22 @@ + + + + netstandard2.0 + true + + + + + + + + + + + + + + + + + diff --git a/src/Argu.ConfigurationManager/Library.fs b/src/Argu.ConfigurationManager/Library.fs new file mode 100644 index 0000000..3155833 --- /dev/null +++ b/src/Argu.ConfigurationManager/Library.fs @@ -0,0 +1,49 @@ +namespace Argu + +open System.Configuration +open System.IO + +/// AppSettings XML configuration reader +type AppSettingsConfigurationReader () = + interface IConfigurationReader with + member _.Name = "AppSettings configuration reader" + member _.GetValue(key : string) = ConfigurationManager.AppSettings[key] + +/// AppSettings XML configuration reader +type AppSettingsConfigurationFileReader private (xmlPath : string, kv : KeyValueConfigurationCollection) = + member _.Path = xmlPath + interface IConfigurationReader with + member _.Name = $"App.config configuration reader: %s{xmlPath}" + member _.GetValue(key : string) = + match kv[key] with + | null -> null + | entry -> entry.Value + + /// Create used supplied XML file path + static member Create(path : string) = + if not <| File.Exists path then raise <| FileNotFoundException(path) + let fileMap = ExeConfigurationFileMap(ExeConfigFilename = path) + let config = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None) + AppSettingsConfigurationFileReader(path, config.AppSettings.Settings) + +[] +module ConfigurationReaderExtensions = + open System.Reflection + open System + + /// Configuration reader implementations + type ConfigurationReader with + + /// Create a configuration reader instance using the application's resident AppSettings configuration + static member FromAppSettings() : IConfigurationReader = AppSettingsConfigurationReader() + + /// Create a configuration reader instance using a local xml App.Config file + static member FromAppSettingsFile(path : string) : IConfigurationReader = AppSettingsConfigurationFileReader.Create path + + /// Create a configuration reader instance using the location of an assembly file + static member FromAppSettings(assembly : Assembly) : IConfigurationReader = + let path = assembly.Location + if String.IsNullOrEmpty path then + invalidArg assembly.FullName $"Assembly location for '{assembly.Location}' is null or empty." + + AppSettingsConfigurationFileReader.Create(path + ".config") :> IConfigurationReader diff --git a/src/Argu/Argu.fsproj b/src/Argu/Argu.fsproj index 2e93b9d..eb84523 100644 --- a/src/Argu/Argu.fsproj +++ b/src/Argu/Argu.fsproj @@ -36,7 +36,6 @@ - - + \ No newline at end of file diff --git a/src/Argu/ArgumentParser.fs b/src/Argu/ArgumentParser.fs index 9da0f5e..52098fa 100644 --- a/src/Argu/ArgumentParser.fs +++ b/src/Argu/ArgumentParser.fs @@ -229,7 +229,7 @@ and [] let configurationReader = match configurationReader with | Some c -> c - | None -> ConfigurationReader.FromAppSettings() + | None -> ConfigurationReader.NullReader try let appSettingsResults = parseKeyValueConfig configurationReader argInfo diff --git a/src/Argu/ConfigReaders.fs b/src/Argu/ConfigReaders.fs index 09f4858..858b5b9 100644 --- a/src/Argu/ConfigReaders.fs +++ b/src/Argu/ConfigReaders.fs @@ -1,10 +1,7 @@ namespace Argu open System -open System.Configuration open System.Collections.Generic -open System.IO -open System.Reflection /// Abstract key/value configuration reader type IConfigurationReader = @@ -54,29 +51,6 @@ type FunctionConfigurationReader (configFunc : string -> string option, ?name : member _.Name = name member _.GetValue(key : string) = configFunc key |> Option.toObj -/// AppSettings XML configuration reader -type AppSettingsConfigurationReader () = - interface IConfigurationReader with - member _.Name = "AppSettings configuration reader" - member _.GetValue(key : string) = ConfigurationManager.AppSettings[key] - -/// AppSettings XML configuration reader -type AppSettingsConfigurationFileReader private (xmlPath : string, kv : KeyValueConfigurationCollection) = - member _.Path = xmlPath - interface IConfigurationReader with - member _.Name = $"App.config configuration reader: %s{xmlPath}" - member _.GetValue(key : string) = - match kv[key] with - | null -> null - | entry -> entry.Value - - /// Create used supplied XML file path - static member Create(path : string) = - if not <| File.Exists path then raise <| FileNotFoundException(path) - let fileMap = ExeConfigurationFileMap(ExeConfigFilename = path) - let config = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None) - AppSettingsConfigurationFileReader(path, config.AppSettings.Settings) - /// Configuration reader implementations [] type ConfigurationReader = @@ -108,15 +82,3 @@ type ConfigurationReader = let read (key : string) = inner.GetValue(prefix + key) |> Option.ofObj FunctionConfigurationReader(read, name = $"Environment Variables (prefix=%s{prefix})") - /// Create a configuration reader instance using the application's resident AppSettings configuration - static member FromAppSettings() : IConfigurationReader = AppSettingsConfigurationReader() - - /// Create a configuration reader instance using a local xml App.Config file - static member FromAppSettingsFile(path : string) : IConfigurationReader = AppSettingsConfigurationFileReader.Create path - - /// Create a configuration reader instance using the location of an assembly file - static member FromAppSettings(assembly : Assembly) : IConfigurationReader = - let path = assembly.Location - if String.IsNullOrEmpty path then - invalidArg assembly.FullName $"Assembly location for '{assembly.Location}' is null or empty." - AppSettingsConfigurationFileReader.Create(path + ".config") :> IConfigurationReader diff --git a/tests/Argu.Tests/Argu.Tests.fsproj b/tests/Argu.Tests/Argu.Tests.fsproj index d0c2522..4d7ed36 100644 --- a/tests/Argu.Tests/Argu.Tests.fsproj +++ b/tests/Argu.Tests/Argu.Tests.fsproj @@ -14,7 +14,8 @@ - + +