Imports System.ServiceModel
Imports System.ServiceModel.Channels
Imports System.ServiceModel.Description

Public Class ServiceHost(Of T)
    Inherits ServiceHost

    Public Sub New(baseAddresses As Uri())
        MyBase.New(GetType(T), baseAddresses)
    End Sub

    Public Sub EnableMetadataExchange(ByVal Optional EnableHttpGet As Boolean = True)
        If State = CommunicationState.Opened Then
            Throw New InvalidOperationException("Host is already opened")
        End If

        Dim oMetadataBehavior As ServiceMetadataBehavior = Description.Behaviors.Find(Of ServiceMetadataBehavior)()

        If oMetadataBehavior Is Nothing Then
            oMetadataBehavior = New ServiceMetadataBehavior()
            Description.Behaviors.Add(oMetadataBehavior)

            If BaseAddresses.Any(Function(uri) uri.Scheme = "http") Then
                oMetadataBehavior.HttpGetEnabled = EnableHttpGet
            Else
                oMetadataBehavior.HttpGetEnabled = False
            End If
        End If

        AddAllMexEndPoints()
    End Sub

    Public ReadOnly Property HasMexEndpoint As Boolean
        Get
            Return Description.Endpoints.Any(Function(endpoint) endpoint.Contract.ContractType = GetType(IMetadataExchange))
        End Get
    End Property

    Public Sub AddAllMexEndPoints()
        Debug.Assert(HasMexEndpoint = False)

        For Each baseAddress As Uri In BaseAddresses
            Dim oBinding As Binding = Nothing

            Select Case baseAddress.Scheme
                Case "net.tcp"
                    oBinding = MetadataExchangeBindings.CreateMexTcpBinding()
                    Exit Select
                Case "net.pipe"
                    oBinding = MetadataExchangeBindings.CreateMexNamedPipeBinding()
                    Exit Select
                Case "http"
                    oBinding = MetadataExchangeBindings.CreateMexHttpBinding()
                    Exit Select
                Case "https"
                    oBinding = MetadataExchangeBindings.CreateMexHttpsBinding()
                    Exit Select
            End Select

            If oBinding IsNot Nothing Then
                AddServiceEndpoint(GetType(IMetadataExchange), oBinding, "mex")
            End If
        Next
    End Sub
End Class
