DLL de carga dinámica .Net

Estoy tratando de escribir algún código que me permita cargar dinámicamente archivos DLL en mi aplicación, dependiendo de la configuración de la aplicación. La idea es que la base de datos a la que se accede esté configurada en la configuración de la aplicación y luego esto carga el archivo DLL apropiado y lo asigna a una instancia de una interfaz para que acceda mi aplicación.

Este es mi código en este momento:

        Dim SQLDataSource As ICRDataLayer
    Dim ass As Assembly = Assembly. _
    LoadFrom("M:\MyProgs\WebService\DynamicAssemblyLoading\SQLServer\bin\Debug\SQLServer.dll")

    Dim obj As Object = ass.CreateInstance(GetType(ICRDataLayer).ToString, True)
    SQLDataSource = DirectCast(obj, ICRDataLayer)

    MsgBox(SQLDataSource.ModuleName & vbNewLine & SQLDataSource.ModuleDescription)

Tengo mi interfaz (ICRDataLayer) y el SQLServer.dll contiene una implementación de esta interfaz. Solo quiero cargar el ensamblado y asignarlo al objeto SQLDataSource.

El código anterior simplemente no funciona. No se lanzan excepciones, incluso el Msgbox no aparece. Hubiera esperado que al menos el cuadro de mensaje apareciera sin nada, ¡pero incluso esto no sucede!

¿Hay alguna manera de determinar si el ensamblado cargado implementa una interfaz específica? Intenté lo siguiente, ¡pero esto tampoco parece hacer nada!

        For Each loadedType As Type In ass.GetTypes
        If GetType(ICRDataLayer).IsAssignableFrom(loadedType) Then
            Dim obj1 As Object = ass.CreateInstance(GetType(ICRDataLayer).ToString, True)
            SQLDataSource = DirectCast(obj1, ICRDataLayer)
        End If
    Next

EDITAR: Nuevo código de los ejemplos de Vlad:

    Module CRDataLayerFactory
    Sub New()
    End Sub
    ' class name is a contract,
    ' should be the same for all plugins
    Private Function Create() As ICRDataLayer
        Return New SQLServer()
    End Function
End Module

Arriba está el Módulo en cada DLL, convertido del ejemplo C # de Vlad.

A continuación se muestra mi código para traer la DLL:

Dim SQLDataSource As ICRDataLayer
    Dim ass As Assembly = Assembly. _
    LoadFrom("M:\MyProgs\WebService\DynamicAssemblyLoading\SQLServer\bin\Debug\SQLServer.dll")

    Dim factory As Object = ass.CreateInstance("CRDataLayerFactory", True)
    Dim t As Type = factory.GetType
    Dim method As MethodInfo = t.GetMethod("Create")
    Dim obj As Object = method.Invoke(factory, Nothing)
    SQLDataSource = DirectCast(obj, ICRDataLayer)

EDITAR: Implementación basada en el código de Paul Kohler

Dim file As String
        For Each file In Directory.GetFiles(baseDir, searchPattern, SearchOption.TopDirectoryOnly)
            Dim assemblyType As System.Type
            For Each assemblyType In Assembly.LoadFrom(file).GetTypes

                Dim s As System.Type() = assemblyType.GetInterfaces
                For Each ty As System.Type In s

                    If ty.Name.Contains("ICRDataLayer") Then
                        MsgBox(ty.Name)
                        plugin = DirectCast(Activator.CreateInstance(assemblyType), ICRDataLayer)
                        MessageBox.Show(plugin.ModuleName)
                    End If
                Next

Me sale el siguiente error con este código:

No se puede convertir el objeto de tipo 'SQLServer.CRDataSource.SQLServer' para escribir 'DynamicAssemblyLoading.ICRDataLayer'.

La DLL real está en un proyecto diferente llamado SQLServer en la misma solución que mi código de implementación. CRDataSource es un espacio de nombres y SQLServer es el nombre de clase real de la DLL. La clase SQLServer implementa ICRDataLayer, por lo que no entiendo por qué no podría lanzarlo. El nombre es significativo aquí, no hubiera pensado que sería.

Código de trabajo final

Contenido de PluginUtility:

enter code here    Public Shared Function GetInstances1(Of Type)(ByVal baseDir As String, ByVal searchPattern As String) As System.Type()
    Dim tmpInstances As New List(Of Type)
    Try
        Dim file As String
        For Each file In Directory.GetFiles(baseDir, searchPattern, SearchOption.TopDirectoryOnly)
            Dim assemblyType As System.Type
            For Each assemblyType In Assembly.LoadFrom(file).GetTypes

                Dim s As System.Type() = assemblyType.GetInterfaces
                Return s.ToArray()

            Next
        Next
    Catch exp As TargetInvocationException
        If (Not exp.InnerException Is Nothing) Then
            Throw exp.InnerException
        End If
    End Try
End Function

Código para cargar la DLL:

enter code here
    Dim basedir As String = "M:\MyProgs\WebService\DynamicAssemblyLoading\SQLServer\bin\Debug\"
    Dim searchPattern As String = "*SQL*.dll"
    Dim plugin As CRDataLayer.ICRDataLayer

    Try
        Dim file As String
        For Each file In Directory.GetFiles(baseDir, searchPattern, SearchOption.TopDirectoryOnly)
            Dim assemblyType As System.Type
            For Each assemblyType In Assembly.LoadFrom(file).GetExportedTypes

                If assemblyType.GetInterface("CRDataLayer.ICRDataLayer") IsNot Nothing Then
                    plugin = DirectCast(Activator.CreateInstance(assemblyType), CRDataLayer.ICRDataLayer)
                    MessageBox.Show(plugin.ModuleDescription)
                End If

            Next
        Next
    Catch exp As TargetInvocationException
        If (Not exp.InnerException Is Nothing) Then
            Throw exp.InnerException
        End If
    Catch ex As Exception
        MsgBox(ex.Message)
        Clipboard.SetText(ex.Message)
    End Try

Respuestas a la pregunta(3)

Su respuesta a la pregunta