Mike
Mike

Reputation: 369

Load WCF application settings from database at runtime

For clarity's sake what I'd like to achieve is to modify <applicationSettings> in memory at runtime. My solution is ntier and the WCF service contains settings for dependent libraries too so these will also need to be modified ie :

   <applicationSettings>

        <!-- WCF Service Settings-->
        <TestWebService.Properties.Settings>
            <setting name="TestProperty"
                     serializeAs="String">
                <value>False</value>
            </setting>
        </TestWebService.Properties.Settings>   

        <!--Dependent Class Library Settings-->
        <TestLibrary.Properties.Settings>
            <setting name="TestProperty2"
                     serializeAs="String">
                <value>ABC</value>
            </setting>
        </TestLibrary.Properties.Settings>

</applicationSettings>

Should become :

   <applicationSettings>

        <!-- WCF Service Settings-->
        <TestWebService.Properties.Settings>
            <setting name="TestProperty"
                     serializeAs="String">
                <value>Updated  at runtime</value>
            </setting>
        </TestWebService.Properties.Settings>   

        <!--Dependent Class Library Settings-->
        <TestLibrary.Properties.Settings>
            <setting name="TestProperty2"
                     serializeAs="String">
                <value>Updated  at runtime</value>
            </setting>
        </TestLibrary.Properties.Settings>

</applicationSettings>

I am aware that application scope settings are read only and there are security implications in modifying the physical config file so I am looking for a solution where I can change the values in the DOM if possible?

Upvotes: 0

Views: 145

Answers (1)

Brian
Brian

Reputation: 3713

OK, using the config file obviously won't work, so the first step is to get rid of that and configure your web service in code as shown below.

Here are the basic steps in code (I use VB due to client requirement, but if you're using C#, you can run this code through a converter):

    'Database stuff
    dim sSQL as string = "select * from wcfConfig"
    dim sPort as string 
    dim sDomain as string  
    dim sService as string 
    dim sPortcol as string  
    Using connection As New SqlConnection(connectionString)
        connection.Open()

        Dim command As New SqlCommand(sSQL, connection)
        Dim reader As SqlDataReader = command.ExecuteReader()
        While reader.Read()
            sPort = reader("port").toString
            sDomain = reader("Domain").toString
            sPortcol = reader("protocol").toString
            sService = reader("service").toString
        End While 
    End Using 

    'should look something like http ://localhost:8888/ServiceName/ServiceMethod

    Dim sURL As String = sProtocol & "://" & sDomain & ":" & sPort & "/" & sService
    Dim ServiceHostURI As New Uri(sURL)
    Dim ServiceHost As New ServiceHost(GetType(YourClass), ServiceHostURI) 
    'Your class is the functioning class that catches and processes the request

    Dim objReadQuotas = New System.Xml.XmlDictionaryReaderQuotas
    With objReadQuotas
        .MaxStringContentLength = Integer.MaxValue
        .MaxArrayLength = Integer.MaxValue
        .MaxBytesPerRead = Integer.MaxValue
        .MaxDepth = 1000
        .MaxNameTableCharCount = Integer.MaxValue
    End With

    'basic binding setup
    Dim b As BasicHttpBinding
    b = New BasicHttpBinding(BasicHttpSecurityMode.None)
    b.TransferMode = TransferMode.Buffered
    b.MaxReceivedMessageSize = Integer.MaxValue
    b.MessageEncoding = WSMessageEncoding.Text
    b.TextEncoding = System.Text.Encoding.UTF8 

    'behaviors for binding
    Dim mb As ServiceMetadataBehavior = New ServiceMetadataBehavior()
    ServiceHost.Description.Behaviors.Add(mb)
    mb.HttpsGetEnabled = False
    mb.HttpGetEnabled = True
    ServiceHost.AddServiceEndpoint(ServiceMetadataBehavior.MexContractName, MetadataExchangeBindings.CreateMexHttpBinding(), "mex")

    'add the end point
    ServiceHost.AddServiceEndpoint(GetType(Accenture.Cas.Replication.SynchronizationWS.IHostInterface), binding, ServiceHostEndPoint.ToString)

    'open the port
    ServiceHost.Open()

    'monitor the host
    While True
      'broken connection case
      If ServiceHost.State <> CommunicationState.Opened Then
        Throw New Exception("SynchronizationWS Service Host failed.")   
             'dump from loop and throw error
        Exit While
      End If

    Threading.Thread.Sleep(1000) 'sleep 1 second before going trying next
    End While

Upvotes: 1

Related Questions