.NET Framework Developer Center > .NET Development Forums > .NET Base Class Library > System.Type.GetType from across assemblies / namespaces
Ask a questionAsk a question
 

AnswerSystem.Type.GetType from across assemblies / namespaces

  • Wednesday, November 04, 2009 11:07 PMJordan At Kawa Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Has Code
    Hi,

    I'm writing a reflection module where I'm storing all reflection related methods.  I would like to move this module into a different assembly (and namespace) but the functions cease to work.

    I will paste the method in its entirety bellow, as well as some sample code.

    The statement that fails, however, is the following

    generic = System.Type.GetType(objectName, True, True).MakeGenericType(types_for_Generic)
    
    
    



    In this case, the "ObjectName" refers to a generic type in another assembly, and "Types_for_Generic" refers to type contained in the SAME assembly
    as the Reflection Functions.

    If I move the Reflection module back into the main project, it works again!

    ex:
    Project: MyLibrary

    namespace: MyLibrary

    Public Module ReflectionHelpers
    
        '''The following method provodies for the creation of Objects with support for generics
    
        Public Function CreateObject(ByVal name As String, Optional ByVal types_for_Generic As Type() = Nothing) As Object
            Dim objectName As String
            Dim generic As Type
            Try
                If Not types_for_Generic Is Nothing Then
                    objectName = name & "`" & types_for_Generic.Length
                    generic = System.Type.GetType(objectName).MakeGenericType(types_for_Generic)
                Else
                    generic = System.Type.GetType(name)
                End If
    
    
                If generic Is Nothing Then
                    Return generic
                Else : Return (Activator.CreateInstance(generic))
                End If
            Catch ex As Exception
                Throw New Exception("Failed to instantiate object " & name, ex)
            End Try
    
        End Function
    
    End Module
    
    
    Public Class AClassInMyLibrary
    
        Public data As String = "foo"
    End Class
    
    


    Project: TestApp
    Namespace: TestAppApplication

    Public Class TestReflection
    
        Private Function GetReportTest(ByVal reportName As String, ByVal propNames As List(Of String), ByVal srcType As Type) As Object
            Dim reportClass As Object = ReflectionModule.CreateObject(GetFullyQualifiedName(reportName), New Type() {srcType})
            Dim controller As Object = reportClass.GenerateReportController(propNames)
            Return controller
        End Function
    
        Private Function GetFullyQualifiedName(ByVal className As String) As String
            Return Me.GetType.Namespace & "." & className
        End Function
    End Class
    


    The CreateObject call receives

    "TestAppApplication.Report1" and the type  MyLibrary.AClassInMyLibrary

    I came across a few other posts like this one
    http://social.msdn.microsoft.com/Forums/en-US/netfxbcl/thread/6928930c-54b4-45bf-a0d0-ecc15c89d570/?prof=required&wa=wsignin1.0

    but they did not cover my particular issue with GetType on a generic.

    Any help is greatly appreciated.


    • Edited byJordan At Kawa Wednesday, November 04, 2009 11:23 PMCode was mangled
    •  

Answers

All Replies

  • Thursday, November 05, 2009 1:03 PMDavid M MortonMVP, ModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    There are a few unknowns here....

    1. Can we see the class definition of TestAppApplication.Report1.
    2. What is the exact error and stack trace.  ("ceases to work" is a bit vague).
    3. Are you able to at least perform the GetType portion without the MakeGenericType? (The stack trace should help you determine that)


    Coding Light - Illuminated Ideas and Algorithms in Software
    Coding Light WikiLinkedInForumsBrowser
  • Thursday, November 05, 2009 7:27 PMJordan At Kawa Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Has Code
    Hi David,

    Sorry, should have included the error/stack trace.  I really appreciate the help.  I'm going to answer your questions a little out of order. 

    Question 3:

    I tried ReflectionModule.CreateObject with a non-generic.  The failure is that  System.Type.GetType(objectName, True, True) fails to generate a type and returns null (or throws an exception if param 2 = True.).  Because of this ".MakeGenericType(...)" is never reached.



    Question 2:

    I tried to simplify the code example to avoid pasting a hundred lines of code.  As a result I should probably explain the stack error & trace a little.

    The stack trace for

    generic = System.Type.GetType(objectName,

    True, True).MakeGenericType(types_for_Generic)

    is as follows:

    The references "TransactionManagerApplication" which in my original post was represented by TestAppApplication.

    The "TMServiceLib" is represented by "MyLibrary" in my simplified example.

    Basically the reflection call is looking within its own assembly, and not the TestAppApplication.

    Error Msg:

    Could not load type 'TransactionManagerApplication.CurrencyExposure`1' from assembly 'TMServiceLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.

    Stack Trace:

       at System.RuntimeTypeHandle._GetTypeByName(String name, Boolean throwOnError, Boolean ignoreCase, Boolean reflectionOnly, StackCrawlMark& stackMark, Boolean loadTypeFromPartialName)
       at System.RuntimeTypeHandle.GetTypeByName(String name, Boolean throwOnError, Boolean ignoreCase, Boolean reflectionOnly, StackCrawlMark& stackMark)
       at System.RuntimeType.PrivateGetType(String typeName, Boolean throwOnError, Boolean ignoreCase, Boolean reflectionOnly, StackCrawlMark& stackMark)
       at System.Type.GetType(String typeName, Boolean throwOnError, Boolean ignoreCase)
       at TMServiceLib.ReflectionModule.CreateObject(String name, Type[] types_for_Generic)



    Question 1

    I have multiple "Report" classes so I'll just paste on of them below.  This is located in the TransactionManagerApplication project & namespace

    Public Class CurrencyExposure(Of ItemType)
        Implements iGenerateReportController(Of ItemType)
    
        Public Function GenerateReportController(ByVal propNames As List(Of String)) As ReportDataController(Of ItemType) Implements iGenerateReportController(Of ItemType).GenerateReportController
            Dim res As New ReportDataController(Of ItemType)
    
            Dim ObjPropropLst As New List(Of ObjectPropertyStringAndFormatCode)
            ObjPropropLst.Add(New ObjectPropertyStringAndFormatCode(propNames.Item(0), "", "Currency"))
            ObjPropropLst.Add(New ObjectPropertyStringAndFormatCode(propNames.Item(1), "C2", "Market Value"))
            ObjPropropLst.Add(New ObjectPropertyStringAndFormatCode(propNames.Item(2), "P2", "% Assets"))
    
            res.PropertyAndFormatList = ObjPropropLst.ToArray
    
            'Format the cells
            For i As Integer = 0 To res.PropertyAndFormatList.Length - 1
                res.FormatTemplateByColumn(i).Size = "8pt"
                res.FormatTemplateByColumn(i).Weight = RDLCFont_Weight.f_Medium
            Next
    
            res.GroupByTemplate.Weight = RDLCFont_Weight.h_Bold
            res.GroupFooterFormatTemplate.Size = "8pt"
            res.GroupFooterFormatTemplate.Weight = RDLCFont_Weight.e_Normal
            res.GroupFooterFormatTemplate.Style = RDLCFont_Style.Italic
            res.HeaderFormatTemplate.Weight = RDLCFont_Weight.h_Bold
            res.HeaderFormatTemplate.Size = "8pt"
    
            Return res
        End Function
    
    End Class
    
  • Thursday, November 05, 2009 7:32 PMDavid M MortonMVP, ModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer
    You'll have to specify the assembly name:

    'TransactionManagerApplication.CurrencyExposure`1, TransactionManagerApplication'

    Is the string that should be used to resolve this type.  Note the assembly name appended at the end, following the comma.
    Coding Light - Illuminated Ideas and Algorithms in Software
    Coding Light WikiLinkedInForumsBrowser
  • Thursday, November 05, 2009 7:53 PMJordan At Kawa Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Thank you David, you're a life saver!!!
    I spent way to much time trying to figure that out . . . and of course the solution was so simple.