' Custom ExpressionBuilder so <%$ ConnectionStrings:csStockControl %> resolves from env (SecureConfig) when Web.config is not writable (e.g. on server).
' Register in Web.config with expressionPrefix="EnvConnectionStrings". ASPX uses <%$ EnvConnectionStrings:csStockControl %>.

Imports System.CodeDom
Imports System.Configuration
Imports System.Web.Compilation
Imports System.Web.Configuration

Namespace Stock_Control
  Public NotInheritable Class EnvConnectionStringsExpressionBuilder
    Inherits System.Web.Compilation.ExpressionBuilder

    Public Overrides Function GetCodeExpression(ByVal entry As BoundPropertyEntry, ByVal parsedData As Object, ByVal context As ExpressionBuilderContext) As CodeExpression
      Dim connectionName As String = entry.Expression.Trim()
      Dim args(0) As CodeExpression
      args(0) = New CodePrimitiveExpression(connectionName)
      Return New CodeMethodInvokeExpression(
        New CodeTypeReferenceExpression(GetType(EnvConnectionStringsExpressionBuilder)),
        "GetConnectionStringForExpression",
        args)
    End Function

    ''' <summary>
    ''' Called at runtime by generated page code. For csStockControl: config first (if non-empty), else SecureConfig (env). Other names: from config only.
    ''' </summary>
    Public Shared Function GetConnectionStringForExpression(ByVal connectionName As String) As String
      Dim css As ConnectionStringSettings = WebConfigurationManager.ConnectionStrings(connectionName)
      If css IsNot Nothing AndAlso Not String.IsNullOrEmpty(css.ConnectionString) Then
        Return css.ConnectionString
      End If
      If String.Equals(connectionName, "csStockControl", StringComparison.OrdinalIgnoreCase) Then
        Return SecureConfig.GetConnectionString("csStockControl")
      End If
      Return String.Empty
    End Function
  End Class
End Namespace
