Imports System.Reflection

''' <summary>
''' Represents an Activator class that is usable by the .NET Compact Framework.
''' </summary>
''' <remarks></remarks>
Public NotInheritable Class Activator2

    ''' <summary>
    ''' Creates an instance of the specified type using that type's public, default constructor.
    ''' </summary>
    ''' <param name="type">The type of the object to create.</param>
    ''' <returns>A reference to the newly created object.</returns>
    Public Shared Function CreateInstance(ByVal type As Type) As Object
        Return Activator.CreateInstance(type)
    End Function

    ''' <summary>
    ''' Creates an instance of the specified type using the constructor that best matches the specified parameters.
    ''' </summary>
    ''' <param name="type">The type of the object to create.</param>
    ''' <param name="nonPublic">A value indicating whether to include non-public constructors.</param>
    ''' <returns>A reference to the newly created object.</returns>
    Public Shared Function CreateInstance(ByVal type As Type, ByVal nonPublic As Boolean) As Object
        Dim flags = BindingFlags.Instance Or BindingFlags.Public
        If nonPublic Then _
            flags = flags Or BindingFlags.NonPublic
        Return Activator2.CreateInstance(type, flags, Nothing)
    End Function

    ''' <summary>
    ''' Creates an instance of the specified type using the constructor that best matches the specified parameters.
    ''' </summary>
    ''' <param name="type">The type of the object to create.</param>
    ''' <param name="args">An array of arguments that match in number, order, and type 
    ''' the parameters of the constructor to invoke. If args is an empty array or null, 
    ''' the constructor that takes no parameters (the default constructor) is invoked.</param>
    ''' <returns>A reference to the newly created object.</returns>
    Public Shared Function CreateInstance(ByVal type As Type, ByVal ParamArray args() As Object) As Object
        Return Activator2.CreateInstance(type, BindingFlags.Instance Or BindingFlags.Public, args)
    End Function

    ''' <summary>
    ''' Creates an instance of the specified type using the constructor that best matches the specified parameters.
    ''' </summary>
    ''' <param name="type">The type of the object to create.</param>
    ''' <param name="flags">A combination of zero or more bit flags that affect the search for 
    ''' the type constructor. If bindingAttr is zero, a case-sensitive search for public 
    ''' constructors is conducted.</param>
    ''' <param name="args">An array of arguments that match in number, order, and type 
    ''' the parameters of the constructor to invoke. If args is an empty array or null, 
    ''' the constructor that takes no parameters (the default constructor) is invoked.</param>
    ''' <returns>A reference to the newly created object.</returns>
    Public Shared Function CreateInstance(ByVal type As Type, ByVal flags As BindingFlags, ByVal ParamArray args() As Object) As Object
        Return Activator2._CreateInstance(type, flags, args)
    End Function

    Private Shared Function _CreateInstance(ByVal type As Type, ByVal flags As BindingFlags, ByVal args() As Object) As Object
        Dim typesArr() As Type = New Type() {}
        If args IsNot Nothing AndAlso args.Length > 0 Then
            typesArr = New Type(args.Length - 1) {}
            Dim curr As Object = Nothing
            For i As Integer = 0 To args.Length - 1
                curr = args(i)
                If curr IsNot Nothing Then _
                    typesArr.SetValue(curr.GetType(), i)
            Next
        End If
        ' Find constructor
        Dim ctor = type.GetConstructor(flags, Nothing, typesArr, Nothing)
        If ctor Is Nothing Then _
            Throw New MissingMethodException("No matching constructor was found.")
        Return ctor.Invoke(args)
    End Function

End Class