Less Than Dot is a community of passionate IT professionals and enthusiasts dedicated to sharing technical knowledge, experience, and assistance. Inside you will find reference materials, interesting technical discussions, and expert tips and commentary. Once you register for an account you will have immediate access to the forums and all past articles and commentaries.
Invoke Singletonprovider giving a string as classname
From Wiki
Weird title, I know ;-).
But let me try to explain it.
I have a factory. For that factory I have a settingsfile to store my configuration so that I can change its settings at runtime without having to rebuild the application.
So let's say the factory gives you an interface of type INewClass. INewClass has 2 implementations namely NewClass1 and NewClass2 now we have a settingsfile with a property in it called factory that stores an integer. When it is 1 it gives NewClass1 when it is set to 2 it gives an instance of NewClass2. So this is how you could write it.
- Public Class Factory
- Public Shared Function NewClass as INewClass
- Dim _Settings As New FactorySettings
- Select Case _Settings.Factory
- Case 1
- Return SingletonProvider(Of NewClass1).Instance
- Case 2
- Return SingletonProvider(Of NewClass2).Instance
- End Select
- End Function
- End Class
The trouble with this is when we get more implementations of INewClass it will soon get very boring to add Case's to the Select-statement.
So reflection to the rescue.
- Public Class Factory
- Public Shared Function NewClass as INewClass
- Dim _Settings As New FactorySettings
- Dim _GenericType As Type = GetType(SingletonProvider(Of ))
- Dim _ParameterTypes() As Type = {[Assembly].GetExecutingAssembly.GetType("AssemblyName.NewClass" & _Settings.Factory)}
- Dim _Object As Object = _GenericType.MakeGenericType(_ParameterTypes)
- Dim _MethodInfo As MethodInfo = _GenericType.MakeGenericType(_ParameterTypes).GetMethod("get_Instance")
- Return CType(_MethodInfo.Invoke(_Object, Nothing), INewClass)
- End Function
- End Class
Some things to note.
1) You will have to change the Assemblyname to your actual AssemblyName in this piece of code "AssemblyName.NewClass".
2) Note that the getmethod looks for get_Instance and not Instance since we are invoking the getter of the property.
3) This is seems like more code.
4) Performance will be down, but I don't think it will matter in this case.
In the end you would of course throw all of this in a seperate shared function. Like this.
- Imports System.Reflection
- Namespace Singleton
- ''' <summary>
- ''' A class that has methods to return a singleton instance of a class by giving it's name
- ''' </summary>
- ''' <remarks></remarks>
- Public Class InvokeSingletonprovider
- ''' <summary>
- ''' By giving the Fully Qualified name of a class you will get a singleton returned
- ''' </summary>
- ''' <param name="InstanceType">Fully Qualified Name</param>
- ''' <returns>An Object or nothing if the class can't be found</returns>
- ''' <remarks></remarks>
- Public Shared Function Instance(ByVal InstanceType As String) As Object
- Dim _GenericType As Type
- Dim _ParameterTypes() As Type
- Dim _Object As Object
- Dim _ReturnObject As Object
- Dim _MethodInfo As MethodInfo
- Try
- _GenericType = GetType(CommonFunctions.SingletonProvider(Of ))
- _ParameterTypes = New Type() {[Assembly].GetCallingAssembly.GetType(InstanceType)}
- _Object = _GenericType.MakeGenericType(_ParameterTypes)
- _MethodInfo = _GenericType.MakeGenericType(_ParameterTypes).GetMethod("get_Instance")
- _ReturnObject = _MethodInfo.Invoke(_Object, Nothing)
- Catch
- _ReturnObject = Nothing
- End Try
- Return _ReturnObject
- End Function
- ''' <summary>
- ''' By giving the Fully Qualified name of a class you will get a singleton returned
- ''' </summary>
- ''' <param name="InstanceType">Fully Qualified Name</param>
- ''' <returns>An Object of type T or nothing if the class can't be found</returns>
- ''' <remarks></remarks>
- Public Shared Function Instance(Of T)(ByVal InstanceType As String) As T
- Dim _GenericType As Type
- Dim _ParameterTypes() As Type
- Dim _Object As Object
- Dim _ReturnObject As T
- Dim _MethodInfo As MethodInfo
- Try
- _GenericType = GetType(CommonFunctions.SingletonProvider(Of ))
- _ParameterTypes = New Type() {[Assembly].GetCallingAssembly.GetType(InstanceType)}
- _Object = _GenericType.MakeGenericType(_ParameterTypes)
- _MethodInfo = _GenericType.MakeGenericType(_ParameterTypes).GetMethod("get_Instance")
- _ReturnObject = CType(_MethodInfo.Invoke(_Object, Nothing), T)
- Catch ex As Exception
- _ReturnObject = Nothing
- End Try
- Return _ReturnObject
- End Function
- End Class
- End Namespace
This has a generic and a non generic method. This is how you would use the generic method.
- Public Class Factory
- Public Shared Function NewClass as INewClass
- Return Singleton.InvokeSingletonprovider.Instance(Of INewClass)("AssemblyName.NewClass" & _Settings.Factory)
- End Function
- End Class
Now that is a lot less typing, isn't it.



LTD Social Sitings
Note: Watch for social icons on posts by your favorite authors to follow their postings on these and other social sites.