Login or Sign Up to become a member!
LessThanDot Sit Logo

LessThanDot

Community Wiki

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.

LTD Social Sitings

Lessthandot twitter Lessthandot Linkedin Lessthandot friendfeed Lessthandot facebook Lessthandot rss

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

Navigation

Google Ads

Invoke Singletonprovider giving a string as classname

From Wiki

Jump to: navigation, search

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.

  1. Public Class Factory
  2.    Public Shared Function NewClass as INewClass
  3.       Dim _Settings As New FactorySettings
  4.       Select Case _Settings.Factory
  5.          Case 1
  6.             Return SingletonProvider(Of NewClass1).Instance
  7.          Case 2
  8.             Return SingletonProvider(Of NewClass2).Instance
  9.          End Select
  10.    End Function
  11. 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.

  1. Public Class Factory
  2.    Public Shared Function NewClass as INewClass
  3.       Dim _Settings As New FactorySettings
  4.       Dim _GenericType As Type = GetType(SingletonProvider(Of ))
  5.       Dim _ParameterTypes() As Type = {[Assembly].GetExecutingAssembly.GetType("AssemblyName.NewClass" & _Settings.Factory)}
  6.       Dim _Object As Object = _GenericType.MakeGenericType(_ParameterTypes)
  7.       Dim _MethodInfo As MethodInfo = _GenericType.MakeGenericType(_ParameterTypes).GetMethod("get_Instance")
  8.       Return CType(_MethodInfo.Invoke(_Object, Nothing), INewClass)
  9.    End Function
  10. 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.

  1. Imports System.Reflection
  2.  
  3. Namespace Singleton
  4.     ''' <summary>
  5.     ''' A class that has methods to return a singleton instance of a class by giving it's name
  6.     ''' </summary>
  7.     ''' <remarks></remarks>
  8.     Public Class InvokeSingletonprovider
  9.         ''' <summary>
  10.         ''' By giving the Fully Qualified name of a class you will get a singleton returned
  11.         ''' </summary>
  12.         ''' <param name="InstanceType">Fully Qualified Name</param>
  13.         ''' <returns>An Object or nothing if the class can't be found</returns>
  14.         ''' <remarks></remarks>
  15.         Public Shared Function Instance(ByVal InstanceType As String) As Object
  16.             Dim _GenericType As Type
  17.             Dim _ParameterTypes() As Type
  18.             Dim _Object As Object
  19.             Dim _ReturnObject As Object
  20.             Dim _MethodInfo As MethodInfo
  21.             Try
  22.                 _GenericType = GetType(CommonFunctions.SingletonProvider(Of ))
  23.                 _ParameterTypes = New Type() {[Assembly].GetCallingAssembly.GetType(InstanceType)}
  24.                 _Object = _GenericType.MakeGenericType(_ParameterTypes)
  25.                 _MethodInfo = _GenericType.MakeGenericType(_ParameterTypes).GetMethod("get_Instance")
  26.                 _ReturnObject = _MethodInfo.Invoke(_Object, Nothing)
  27.             Catch
  28.                 _ReturnObject = Nothing
  29.             End Try
  30.             Return _ReturnObject
  31.         End Function
  32.  
  33.         ''' <summary>
  34.         ''' By giving the Fully Qualified name of a class you will get a singleton returned
  35.         ''' </summary>
  36.         ''' <param name="InstanceType">Fully Qualified Name</param>
  37.         ''' <returns>An Object of type T or nothing if the class can't be found</returns>
  38.         ''' <remarks></remarks>
  39.         Public Shared Function Instance(Of T)(ByVal InstanceType As String) As T
  40.             Dim _GenericType As Type
  41.             Dim _ParameterTypes() As Type
  42.             Dim _Object As Object
  43.             Dim _ReturnObject As T
  44.             Dim _MethodInfo As MethodInfo
  45.             Try
  46.                 _GenericType = GetType(CommonFunctions.SingletonProvider(Of ))
  47.                 _ParameterTypes = New Type() {[Assembly].GetCallingAssembly.GetType(InstanceType)}
  48.                 _Object = _GenericType.MakeGenericType(_ParameterTypes)
  49.                 _MethodInfo = _GenericType.MakeGenericType(_ParameterTypes).GetMethod("get_Instance")
  50.                 _ReturnObject = CType(_MethodInfo.Invoke(_Object, Nothing), T)
  51.             Catch ex As Exception
  52.                 _ReturnObject = Nothing
  53.             End Try
  54.             Return _ReturnObject
  55.         End Function
  56.     End Class
  57. End Namespace


This has a generic and a non generic method. This is how you would use the generic method.

  1. Public Class Factory
  2.    Public Shared Function NewClass as INewClass
  3.       Return Singleton.InvokeSingletonprovider.Instance(Of INewClass)("AssemblyName.NewClass" & _Settings.Factory)
  4.    End Function
  5. End Class


Now that is a lot less typing, isn't it.

224 Rating: 2.3/5 (4 votes cast)