Created
September 29, 2011 16:41
-
-
Save dmohl/1251208 to your computer and use it in GitHub Desktop.
Example of a simple TypeProvider for reading AppSettings
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace AppSettingsTypeProvider | |
open System | |
open System.IO | |
open System.Reflection | |
open Samples.FSharpPreviewRelease2011.ProvidedTypes | |
open Microsoft.FSharp.Core.CompilerServices | |
open System.Configuration | |
[<TypeProvider>] | |
type public AppSettingsProvider(config:TypeProviderConfig) as this = | |
inherit TypeProviderForNamespaces() | |
let namespaceName = "AppSettingsTypeProvider" | |
let currentAssembly = Assembly.GetExecutingAssembly() | |
let tySettings = ProvidedTypeDefinition(currentAssembly, namespaceName, "AppSettings", Some typeof<obj>) | |
let addSettings (configFileName:string) (tyDef:ProvidedTypeDefinition) = | |
tyDef.AddXmlDocDelayed(fun () -> sprintf "Provides a strongly typed representation of the appSettings in a provided config file.") | |
let filePath = Path.Combine(config.ResolutionFolder, configFileName) | |
let fileMap = ExeConfigurationFileMap(ExeConfigFilename=filePath) | |
let appSettings = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None).AppSettings.Settings | |
let tryParseWith func = func >> function | |
| true, value -> Some value | |
| false, _ -> None | |
let (|Bool|_|) = tryParseWith Boolean.TryParse | |
let (|Int|_|) = tryParseWith Int32.TryParse | |
let (|Double|_|) = tryParseWith Double.TryParse | |
do Seq.iter (fun (key) -> | |
let keyElement = match (appSettings.Item key).Value with | |
| Int fieldValue -> ProvidedLiteralField(key, typeof<int>, fieldValue) | |
| Bool fieldValue -> ProvidedLiteralField(key, typeof<bool>, fieldValue) | |
| Double fieldValue -> ProvidedLiteralField(key, typeof<Double>, fieldValue) | |
| fieldValue -> ProvidedLiteralField(key, typeof<string>, fieldValue.ToString()) | |
do keyElement.AddXmlDocDelayed(fun () -> sprintf "Returns the value from the appSetting with key %s" key) | |
do tyDef.AddMember keyElement ) appSettings.AllKeys | |
let staticParams = [ProvidedStaticParameter("configFilePath", typeof<string>)] | |
do tySettings.DefineStaticParameters(staticParams, | |
fun typeName args -> | |
match args with | |
| [| :? string as configFileName |] -> | |
let ty = ProvidedTypeDefinition(assembly = currentAssembly, | |
namespaceName = namespaceName, typeName = typeName, | |
baseType = Some typeof<obj>, HideObjectMethods = true) | |
addSettings configFileName ty | |
ty | |
| _ -> failwith "unexpected parameter values") | |
do this.AddNamespace(namespaceName, [tySettings]) | |
[<assembly:TypeProviderAssembly>] | |
do() |
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="test2" value="Some Test Value 5"/>
<add key="TestInt" value="102"/>
<add key="TestBool" value="True"/>
<add key="TestDouble" value="10.01"/>
</appSettings>
</configuration>
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
// Example of this TypeProvider in use
r "System"
r @"bin\debug\AppSettingsTypeProvider.dll"
open System
open AppSettingsTypeProvider
type settings = AppSettings<"App.config">
printfn "Test2 String: %s" settings.test2
printfn "Test Int: %i" settings.TestInt
printfn "Test Bool: %b" settings.TestBool
printfn "Test Double: %f" settings.TestDouble