Friday, February 22, 2019

Vb.net change config file at runtime - Windows application

-->
Below help you to switch application configuration at runtime.
Suppose you are maintain different configuration file for different task.
Suppose I have a project name Vehicle, and below are my project config structure



 Main configuration is vehicle.config, and Byke and car has their own configuration setting. Now how my code fetch configuration data from Byke and Car when my application is running? How all code in Byke/car reads from its own configuration?
Solution
1. First create a class which is responsible for config change, below class will do it
Public MustInherit Class AppConfig
    Implements IDisposable

    Public Shared Function ChangeConfigPath(ByVal path As StringAs AppConfig
        Return New ChangeAppConfig(path)
    End Function

    Private _OldConfig As String = String.Empty
    Public Overridable Property OldConfig(As String
        Get
            Return _OldConfig
        End Get
        Set(ByVal value As String)
            _OldConfig = value
        End Set
    End Property

    Private _DisposedValue As Boolean = False
    Public Overridable Property DisposedValue(As Boolean
        Get
            Return _DisposedValue
        End Get
        Set(ByVal value As Boolean)
            _DisposedValue = value
        End Set
    End Property

Public MustOverride Sub Dispose()


  Private Class ChangeAppConfig
        Inherits AppConfig

        Public Sub New(ByVal path As String)

            If OldConfigString.Empty Then
                OldConfigAppDomain.CurrentDomain.GetData("APP_CONFIG_FILE").ToString
            End If

            AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", path)

            GetType(System.Configuration.ConfigurationManager).GetField("s_initState", System.Reflection.BindingFlags.NonPublic OrSystem.Reflection.BindingFlags.[Static]).SetValue(Nothing, 0)

            Dim clConfigSystem As Object = GetType(System.Configuration.ConfigurationManager).GetField("s_configSystem", System.Reflection.BindingFlags.NonPublic Or System.Reflection.BindingFlags.[Static]).GetValue(Nothing)
            Dim clConfigHost As Object = clConfigSystem.GetType.GetField("_configHost", System.Reflection.BindingFlags.NonPublic OrSystem.Reflection.BindingFlags.[Instance]).GetValue(clConfigSystem)
            Dim clConfigPaths As Object = clConfigHost.GetType.GetField("_configPaths", System.Reflection.BindingFlags.NonPublic OrSystem.Reflection.BindingFlags.[Instance]).GetValue(clConfigHost)
            If Not clConfigPaths Is Nothing Then
                clConfigPaths.GetType.GetField("_applicationConfigUri", System.Reflection.BindingFlags.NonPublic Or System.Reflection.BindingFlags.[Instance]).SetValue(clConfigPaths, path)
            End If

        End Sub

        Public Overrides Sub Dispose()
        End Sub
    End Class

    Public Sub Dispose1(Implements System.IDisposable.Dispose
        If Not Me.DisposedValue Then
            Dim configPath As String = OldConfig
            If String.IsNullOrWhiteSpace(configPathThen
                configPathCommon.Application_Config_Path
            End If
            AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", configPath)
            GetType(System.Configuration.ConfigurationManager).GetField("s_initState", System.Reflection.BindingFlags.NonPublic OrSystem.Reflection.BindingFlags.[Static]).SetValue(Nothing, 0)

            Dim clConfigSystem As Object = GetType(System.Configuration.ConfigurationManager).GetField("s_configSystem", System.Reflection.BindingFlags.NonPublic Or System.Reflection.BindingFlags.[Static]).GetValue(Nothing)
            Dim clConfigHost As Object = clConfigSystem.GetType.GetField("_configHost", System.Reflection.BindingFlags.NonPublic OrSystem.Reflection.BindingFlags.[Instance]).GetValue(clConfigSystem)
            Dim clConfigPaths As Object = clConfigHost.GetType.GetField("_configPaths", System.Reflection.BindingFlags.NonPublic OrSystem.Reflection.BindingFlags.[Instance]).GetValue(clConfigHost)
            If Not clConfigPaths Is Nothing Then
                clConfigPaths.GetType.GetField("_applicationConfigUri", System.Reflection.BindingFlags.NonPublic Or System.Reflection.BindingFlags.[Instance]).SetValue(clConfigPaths, Common.Application_Config_Path)
            End If

            Me.DisposedValueTrue
        End If
        GC.SuppressFinalize(Me)
    End Sub
End Class




2. To call above class for changing config file, you needs to put your code inside using block

            Ex: code to read appSetting from Bype app.config, you have to write something like below
           
            Using AppConfig.ChangeConfigPath(“..\Vehicle\Byke\app.config”) ‘write the full app.config path here
           Dim BykemaxSpeed As string = ConfigurationManager.AppSetting[BykeMaxSpeed”]
End Using
Note: app.config path should be a full path
Whenever you needs to read something for your config file, then write those code inside using block.