Click here to Skip to main content
15,907,906 members
Articles / Web Development / HTML
Tip/Trick

AssemblyQualifiedName Parser

Rate me:
Please Sign up or sign in to vote.
4.33/5 (3 votes)
22 Jul 2013Ms-PL1 min read 28.7K   381   7   5
A parser for AssemblyQualifiedName for .NET

What Is It ?

ParsedAssemblyQualifiedName is a simple parser for type.AssemblyQualifiedName for .NET.

It is a fact that the syntax of AssemblyQualifiedName is rather complex. While I am working on a new version of UniversalSerializer, I need such a parser and I am unable to find one in the Internet. So here is a class that may help.

Summary

As I said, the syntax of AssemblyQualifiedName is rather complex, especially with generics.

An example:

C#
Dictionary<int, List<double>>

has this AssemblyQualifiedName:

C#
System.Collections.Generic.Dictionary`2[[System.Int32, mscorlib, Version=4.0.0.0, 
  Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.Collections.Generic.List`1[[System.Double, 
  mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], mscorlib, 
  Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], mscorlib, 
  Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089

Not very comprehensible!

ParsedAssemblyQualifiedName will extract these information:

mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089

System.Collections.Generic.Dictionary<System.Int32, System.Collections.Generic.List<System.Double>>

neutral

b77a5c561934e089

mscorlib

System.Collections.Generic.Dictionary`2[[System.Int32, mscorlib, 
  Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],
  [System.Collections.Generic.List`1[[System.Double, mscorlib, Version=4.0.0.0, 
  Culture=neutral, PublicKeyToken=b77a5c561934e089]], mscorlib, 
  Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]

System.Collections.Generic.Dictionary(Of System.Int32, System.Collections.Generic.List(Of System.Double))

4.0.0.0
  • AssemblyDescriptionString: This is the assembly description part of the AssemblyQualifiedName.
  • AssemblyNameDescriptor: An AssemblyName generated from the AssemblyQualifiedName. It is Lazy.
  • CSharpStyleName: A C#-style type name. It is Lazy.
  • Culture: Culture string of the Assembly.
  • FoundType: Creates the Type corresponding to the AssemblyQualifiedName, if available. It is Lazy.
  • GenericParameters: Gets a list of ParsedAssemblyQualifiedName, one for each generic parameter. Obviously, it is recursive.
  • PublicKeyToken: The token of the Assembly.
  • ShortAssemblyName
  • TypeName: The first part of the AssemblyQualifiedName, without the Assembly information.
  • VBNetStyleName: A VB-style type name. It is Lazy.
  • Version: Version of the Assembly, as a string.

Note

Please note ParsedAssemblyQualifiedName can analyse a type description even if the type does not exist or if it lays in an inaccessible library. In that case, only FoundType will not produce anything (it will return null).

Example of Usage

C#
var parsed = new ParsedAssemblyQualifiedName
    (typeof(Dictionary<int, List<double>>).AssemblyQualifiedName);
var t = parsed.FoundType.Value;
var an = parsed.AssemblyNameDescriptor.Value;
var cs = parsed.CSharpStyleName.Value;
var vb = parsed.VBNetStyleName.Value;

Conclusion

I hope this small class will be useful to many. Future enhancements will be part of UniversalSerializer.

History

  • 2015-01-28 Correction for array types

License

This article, along with any associated source code and files, is licensed under The Microsoft Public License (Ms-PL)


Written By
Software Developer (Senior) independent
France France
Hi !

I made my first program on a Sinclair ZX-81.
Since that day, I have the virus of computers. Smile | :)

Here is my website:
https://chrisbertrand.net

And my blog:
https://chrisbertrandprogramer.wordpress.com/

Comments and Discussions

 
SuggestionA little improvement... Pin
Filippo Bottega17-Feb-15 3:58
Filippo Bottega17-Feb-15 3:58 
I have converted your code in VB.NET adding two new properties: CSharpStyleShortName and VBNetStyleShortName.

This is the VB Code:

VB
' Copyright Christophe Bertrand.

Imports System.Collections.Generic
Imports System.Linq
Imports System.Reflection
Imports System.Text

Namespace ParsedAssemblyQualifiedName
  Public Class ParsedAssemblyQualifiedName
    Public AssemblyNameDescriptor As Lazy(Of AssemblyName)
    Public FoundType As Lazy(Of Type)
    Public ReadOnly AssemblyDescriptionString As String
    Public ReadOnly TypeName As String
    Public ReadOnly ShortAssemblyName As String
    Public ReadOnly Version As String
    Public ReadOnly Culture As String
    Public ReadOnly PublicKeyToken As String
    Public ReadOnly GenericParameters As New List(Of ParsedAssemblyQualifiedName)()
    Public ReadOnly CSharpStyleName As Lazy(Of String)
    Public ReadOnly VBNetStyleName As Lazy(Of String)
    Public ReadOnly CSharpStyleShortName As Lazy(Of String)
    Public ReadOnly VBNetStyleShortName As Lazy(Of String)

    Public Sub New(AssemblyQualifiedName As String)
      Dim index As Integer = -1
      Dim rootBlock As New block()
      If True Then
        Dim bcount As Integer = 0
        Dim currentBlock As block = rootBlock
        For i As Integer = 0 To AssemblyQualifiedName.Length - 1
          Dim c As Char = AssemblyQualifiedName(i)
          If c = "["c Then
            If AssemblyQualifiedName(i + 1) = "]"c Then
              ' Array type.
              i += 1
            Else
              bcount += 1
              Dim b = New block() With { _
                .iStart = i + 1, _
                .level = bcount, _
                .parentBlock = currentBlock _
              }
              currentBlock.innerBlocks.Add(b)
              currentBlock = b
            End If
          ElseIf c = "]"c Then
            currentBlock.iEnd = i - 1
            If AssemblyQualifiedName(currentBlock.iStart) <> "["c Then
              currentBlock.parsedAssemblyQualifiedName = New ParsedAssemblyQualifiedName(AssemblyQualifiedName.Substring(currentBlock.iStart, i - currentBlock.iStart))
              If bcount = 2 Then
                Me.GenericParameters.Add(currentBlock.parsedAssemblyQualifiedName)
              End If
            End If
            currentBlock = currentBlock.parentBlock
            bcount -= 1
          ElseIf bcount = 0 AndAlso c = ","c Then
            index = i
            Exit For
          End If
        Next
      End If

      Me.TypeName = AssemblyQualifiedName.Substring(0, index)

      Me.CSharpStyleName = New Lazy(Of String)(Function()
                                                 Return Me.LanguageStyle("<", ">")

                                               End Function)

      Me.VBNetStyleName = New Lazy(Of String)(Function()
                                                Return Me.LanguageStyle("(Of ", ")")

                                              End Function)

      Me.CSharpStyleShortName = New Lazy(Of String)(Function()
                                                      Return Me.LanguageStyle("<", ">", True)

                                                    End Function)

      Me.VBNetStyleShortName = New Lazy(Of String)(Function()
                                                     Return Me.LanguageStyle("(Of ", ")", True)

                                                   End Function)

      Me.AssemblyDescriptionString = AssemblyQualifiedName.Substring(index + 2)

      If True Then
        Dim parts As List(Of String) = AssemblyDescriptionString.Split(","c).[Select](Function(x) x.Trim()).ToList()
        Me.Version = LookForPairThenRemove(parts, "Version")
        Me.Culture = LookForPairThenRemove(parts, "Culture")
        Me.PublicKeyToken = LookForPairThenRemove(parts, "PublicKeyToken")
        If parts.Count > 0 Then
          Me.ShortAssemblyName = parts(0)
        End If
      End If

      Me.AssemblyNameDescriptor = New Lazy(Of AssemblyName)(Function() New System.Reflection.AssemblyName(Me.AssemblyDescriptionString))

      Me.FoundType = New Lazy(Of Type)(Function()
                                         Dim searchedType = Type.[GetType](AssemblyQualifiedName)
                                         If searchedType IsNot Nothing Then
                                           Return searchedType
                                         End If
                                         For Each assem In Assemblies.Value
                                           searchedType = assem.[GetType](AssemblyQualifiedName)
                                           If searchedType IsNot Nothing Then
                                             Return searchedType
                                           End If
                                         Next
                                         ' Not found.
                                         Return Nothing

                                       End Function)
    End Sub

    Friend Function LanguageStyle(prefix As String, suffix As String, Optional shortStyle As Boolean = False) As String
      If Me.GenericParameters.Count > 0 Then
        Dim sb As New StringBuilder(Me.TypeName.Substring(0, Me.TypeName.IndexOf("`"c)))
        If shortStyle Then
          Dim TypeNameTokens = Split(sb.ToString, ".")
          sb = New StringBuilder(TypeNameTokens(TypeNameTokens.Length - 1))
        End If
        sb.Append(prefix)
        Dim pendingElement As Boolean = False
        For Each param In Me.GenericParameters
          If pendingElement Then
            sb.Append(", ")
          End If
          sb.Append(param.LanguageStyle(prefix, suffix, shortStyle))
          pendingElement = True
        Next
        sb.Append(suffix)
        Return sb.ToString()
      Else
        If shortStyle Then
          Dim TypeNameTokens = Split(Me.TypeName, ".")
          Return TypeNameTokens(TypeNameTokens.Length - 1)
        End If
        Return Me.TypeName
      End If
    End Function
    Private Class block
      Friend iStart As Integer
      Friend iEnd As Integer
      Friend level As Integer
      Friend parentBlock As block
      Friend innerBlocks As New List(Of block)()
      Friend parsedAssemblyQualifiedName As ParsedAssemblyQualifiedName
    End Class

    Private Shared Function LookForPairThenRemove(strings As List(Of String), Name As String) As String
      For istr As Integer = 0 To strings.Count - 1
        Dim s As String = strings(istr)
        Dim i As Integer = s.IndexOf(Name)
        If i = 0 Then
          Dim i2 As Integer = s.IndexOf("="c)
          If i2 > 0 Then
            Dim ret As String = s.Substring(i2 + 1)
            strings.RemoveAt(istr)
            Return ret
          End If
        End If
      Next
      Return Nothing
    End Function

    Shared ReadOnly Assemblies As New Lazy(Of Assembly())(Function() AppDomain.CurrentDomain.GetAssemblies())

#If DEBUG Then
    ' Makes debugging easier.
    Public Overrides Function ToString() As String
      Return Me.CSharpStyleName.ToString()
    End Function
#End If
  End Class



End Namespace

'=======================================================
'Service provided by Telerik (www.telerik.com)
'Conversion powered by NRefactory.
'Twitter: @telerik
'Facebook: facebook.com/telerik
'=======================================================


Thank you!

Filippo
GeneralRe: A little improvement... Pin
Christophe Bertrand20-Feb-15 6:55
Christophe Bertrand20-Feb-15 6:55 
GeneralMy vote of 3 Pin
Member 1092263116-Jan-15 9:11
Member 1092263116-Jan-15 9:11 
AnswerRe: My vote of 3 Pin
Christophe Bertrand29-Jan-15 23:39
Christophe Bertrand29-Jan-15 23:39 
GeneralMy vote of 5 Pin
Member 767332830-Sep-13 17:10
Member 767332830-Sep-13 17:10 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.