Coding For a Living

rss

A place to share and comment about coding for a living.


Use Linq with Reflection in Visual Basic Mike McIntyre

The Reflector class below generates an HTML document outlining the public API for a given assembly.

First, an XML document is emitted in memory (see Emit*()).

The document captures the relevant aspects of the assembly's metadata.

Next, an HTML document is extracted from the XML document (see Extract*()).

I love Linq.

Public Class Reflector
    Public document As XDocument

    Public Sub Reflect(ByVal assemblyFile As String)
        Dim Assembly As Assembly = Assembly.LoadFrom(assemblyFile)
        document = New XDocument(EmitAssembly(Assembly))
    End Sub

    Public Sub Transform(ByVal writer As XmlWriter)
        If document Is Nothing Then Return
        Dim assembly As XElement = document.Element("assembly")
        Dim transform As New XDocument(ExtractAssembly(assembly))
        transform.Save(writer)
    End Sub

    Public Function EmitAssembly(ByVal assembly As Assembly) As XElement
        Return 
                   
               
    End Function

    Public Function EmitNamespace(ByVal ns As String, ByVal types As IEnumerable(Of Type)) As XElement
        Return 
                   
               
    End Function

    Public Function EmitType(ByVal type As Type) As XElement
        Return < name=>
                   
                   
                   
                   
                   
                   
                   
                   
                   
               
    End Function

    Public Function EmitGenericArguments(ByVal args As IEnumerable(Of Type)) As IEnumerable(Of XElement)
        Return From arg In args _
                Select 
                           
                       
    End Function

    Public Function EmitModifiers(ByVal type As Type) As XElement
        Dim builder As StringBuilder = New StringBuilder()
        If type.IsPublic Then
            builder.Append("public")
        ElseIf type.IsNestedPublic Then
            builder.Append("public")
        ElseIf type.IsNestedFamily Then
            builder.Append("protected")
        ElseIf type.IsNestedFamANDAssem Then
            builder.Append("protected internal")
        End If
        If type.IsSealed Then builder.Append(" sealed")
        If type.IsAbstract Then builder.Append(" abstract")

        Return 
                   
               
    End Function

    Public Function EmitExtends(ByVal baseType As Type) As XElement
        If baseType Is Nothing Or baseType Is GetType(Object) Or baseType Is GetType(ValueType) Or baseType Is GetType(System.Enum) Then Return Nothing
        Return 
                   
               
    End Function

    Public Function EmitImplements(ByVal ifaces As IEnumerable(Of Type)) As IEnumerable(Of XElement)
        Return From iface In ifaces _
               Select 
                          
                      
    End Function

    Public Function EmitDeclaringType(ByVal declaringType As Type) As XElement
        If declaringType Is Nothing Then Return Nothing
        Return 
                   
               
    End Function

    Public Function EmitNestedTypes(ByVal ntypes As IEnumerable(Of Type)) As IEnumerable(Of XElement)
        Return From ntype In ntypes _
                Where GetVisible(ntype) _
                Select EmitType(ntype)
    End Function

    Public Function EmitMethods(ByVal metds As IEnumerable(Of MethodBase)) As IEnumerable(Of XElement)
        Return From metd In metds _
        Where GetVisible(metd) _
        Select 
                   
                   
                   
                   
                   
               
    End Function

    Public Function EmitProperties(ByVal props As IEnumerable(Of PropertyInfo)) As IEnumerable(Of XElement)

        Return From prop In props _
                    Where GetVisible(prop.GetGetMethod()) Or _
                    GetVisible(prop.GetSetMethod()) _
                    Select 
                               
                               
                           


    End Function

    Public Function EmitReference(ByVal type As Type) As IEnumerable(Of Object)

        If (Not type.IsGenericType) Then
            Return New Object() {New XAttribute("name", type.Name), _
                                 New XAttribute("namespace", GetNamespace(type))}
        Else
            Return New Object() {New XAttribute("name", type.Name), _
                                 New XAttribute("namespace", GetNamespace(type)), _
                                 EmitGenericArguments(type.GetGenericArguments())}
        End If
    End Function

    Public Function EmitModifiers(ByVal metd As MethodBase) As XElement
        Dim builder As StringBuilder = New StringBuilder()
        If metd.IsPublic Then
            builder.Append("public")
        ElseIf metd.IsFamily Then
            builder.Append("protected")
        ElseIf metd.IsFamilyAndAssembly Then
            builder.Append("protected internal")
        End If

        If metd.IsAbstract Then builder.Append(" abstract")
        If metd.IsStatic Then builder.Append(" static")
        If metd.IsVirtual Then builder.Append(" virtual")

        Return New XElement("modifiers", builder.ToString())
    End Function

    Public Function EmitReturnType(ByVal metd As MethodBase) As XElement
        Dim metdInfo As MethodInfo = TryCast(metd, MethodInfo)
        If metdInfo Is Nothing Then Return Nothing
        Return 
                   
               
    End Function

    Public Function EmitExtension(ByVal metd As MethodBase) As XElement
        Return 
               
    End Function

    Public Function EmitParameters(ByVal parms As IEnumerable(Of ParameterInfo)) As IEnumerable(Of XElement)
        Return From parm In parms _
               Select 
                          
                              
                          
                      
    End Function

    Public Shared Function GetNamespace(ByVal type As Type) As String
        Dim ns As String = type.Namespace
        Return If(ns IsNot Nothing, ns, String.Empty)
    End Function

    Public Shared Function GetVisible(ByVal type As Type) As Boolean
        Return type.IsPublic Or type.IsNestedPublic Or type.IsNestedFamily Or type.IsNestedFamANDAssem
    End Function

    Public Shared Function GetVisible(ByVal metd As MethodBase) As Boolean
        Return metd IsNot Nothing AndAlso (metd.IsPublic Or metd.IsFamily Or metd.IsFamilyAndAssembly)
    End Function

    Public Function ExtractAssembly(ByVal assembly As XElement) As XElement
        Return 
                   
                       
                           
                       
                   
                   
                       

Assembly:

End Function Public Function ExtractNamespace(ByVal ns As XElement) As XElement Return

Namespace:

End Function Public Function ExtractType(ByVal type As XElement) As XElement Return

End Function Public Function ExtractModifiers(ByVal element As XElement) As String Return element.Element("modifiers").Value End Function Public Function ExtractName(ByVal element As XElement) As String Dim name As String = element.Attribute("name").Value Dim i As Integer = name.LastIndexOf("`") If i > 0 Then name = name.Substring(0, i) ' fix generic name Return name End Function Public Function ExtractGenericArguments(ByVal element As XElement) As String If Not element.Elements("genericArgument").Any() Then Return String.Empty Dim builder As StringBuilder = New StringBuilder("<") For Each genericArgument As XElement In element.Elements("genericArgument") If builder.Length <> 1 Then builder.Append(", ") builder.Append(ExtractReference(genericArgument)) Next builder.Append(">") Return builder.ToString() End Function Public Function ExtractReference(ByVal element As XElement) As String Return ExtractName(element) + ExtractGenericArguments(element) End Function Public Function ExtractInherits(ByVal type As XElement) As String If Not type.Elements("extends").Concat(type.Elements("implements")).Any() Then Return String.Empty Dim builder As New StringBuilder() For Each [inherits] As XElement In type.Elements("extends").Concat(type.Elements("implements")) If builder.Length = 0 Then builder.Append(" : ") Else builder.Append(", ") End If builder.Append(ExtractReference([inherits])) Next Return builder.ToString() End Function Public Function ExtractConstructors(ByVal type As XElement) As XElement Dim ctors = From ctor In type.Elements("method") _ Where ExtractName(ctor) = ".ctor" _ Select
  • If Not ctors.Any() Then Return Nothing Return

    Constructors:

      End Function Public Function ExtractProperties(ByVal type As XElement) As XElement Dim props = From prop In type.Elements("property") _ Let propName = ExtractName(prop) _ Let getter = "get_" + propName _ Let setter = "set_" + propName _ Select
      If Not props.Any() Then Return Nothing Return

      Properties:

      End Function Public Function ExtractOperators(ByVal type As XElement) As XElement Dim ops = From op In type.Elements("method") _ Let name = ExtractName(op) _ Where name.StartsWith("op_") _ Select
      If Not ops.Any() Then Return Nothing Return

      Operators:

      End Function Public Function ExtractMethods(ByVal type As XElement) As XElement Dim metds = From metd In type.Elements("method") _ Let name = ExtractName(metd) _ Where name <> ".ctor" And _ Not type.Elements("property").Where(Function(prop) name = "get_" & ExtractName(prop) Or _ name = "set_" + ExtractName(prop)).Any() And Not name.StartsWith("op_") _ Select ExtractMethod(metd) If Not metds.Any() Then Return Nothing Return New XElement("div", New XElement("h4", "Methods: "), New XElement("ul", metds)) End Function Public Function ExtractMethod(ByVal metd As XElement) As XElement Return
    • End Function Public Function ExtractParameters(ByVal metd As XElement) As String Dim builder As StringBuilder = New StringBuilder("(") For Each parm As XElement In metd.Elements("parameter") If builder.Length = 1 Then If metd.Element("extension") IsNot Nothing Then builder.Append("this ") Else builder.Append(", ") End If builder.Append(ExtractReference(parm.Element("parameterType"))) builder.Append(" ") builder.Append(ExtractName(parm)) Next builder.Append(")") Return builder.ToString() End Function End Class


      Visual Basic If Operator Mike McIntyre

      It looks like a function but it is an operator.  The Visual Basic If operator provides the functionality of the IIF function and more - including short-circuiting. It can be use as a ternary operator which mimics the functionality of the IIF function while adding some more to it, and as a binary operator which provides a comparison/assignment feature. image

      The operator uses short-circuit evaluation to conditionally return one of two values. The If operator can be called with three arguments or with two arguments.

      When If is called by using three arguments, the first argument must evaluate to a value that can be cast as a Boolean. That Boolean value will determine which of the other two arguments is evaluated and returned.

      ' This statement prints TruePart, because the first argument is true. Console.WriteLine(If(True, "TruePart", "FalsePart")) ' This statement prints FalsePart, because the first argument is false. Console.WriteLine(If(False, "TruePart", "FalsePart")) Dim number = 3 ' With number set to 3, this statement prints Positive. Console.WriteLine(If(number >= 0, "Positive", "Negative")) number = -1 ' With number set to -1, this statement prints Negative. Console.WriteLine(If(number >= 0, "Positive", "Negative"))

      Gadgeteer Book–Learn to Program With VB & .Net Mike McIntyre

      This book is a free resource from Microsoft Press which helps students learn to program with the .Net Gadgeteer, a device originated at the Microsoft Research in Cambridge, U.K.. image

      The Gadgeteer book explains how to program with VB and .Net using the FEZ Cerberus Tinker Kit modules such as the mainboard, USPClientSP power module, the Joystick, the LED strip, and the Display N18 module.

      Students plug together modules then use Visual Studio 2012 or Visual Studio 2010 to build a .Net Gadgeteer project.

      The Visual Studio project includes lots of visual tools for connecting and configuring modules.

      image 

      I love this book and the FEZ Tinker Kit. 

      Back in the day I remember buying electronic parts, wiring up boards and hooking up devices based on computer magazine articles.

      This kit gives a similar ‘hands on experience’ with the power of VB and .NET added in. 

      This book and the FEZ Cerberus Tinker Kit are highly recommended for the young nerds in your life.  The book is free and the kit costs around $100 U.S.


      What can you do with Roslyn? Scripting Mike McIntyre

      With Microsoft Roslyn you can write applications that evaluate code at runtime.

      While it’s been possible to implement scripting since the release of .Net it’s not been easy. Check out Brian Rasmussen’s blog on scripting:

           Learn about the Roslyn scripting API


      Return a string, and just a string, from HTTP Post Mike McIntyre

      You want to return a string, just a string, from an HTTP POST call.

      You code it like this:

      Response.Write("Hello World")

      The HTTP POST returns:

      All you wanted was “Hello World”.

      You should have coded it like this:

      Response.Write("Hello World") ' The Response.End method causes the Web server to stop processing the script and return the current result. The remaining contents of the file are not processed. Response.End()

      Opening the black box with Microsoft® Roslyn Mike McIntyre

      image 

      Until now the VB and C# compilers have been black boxes, un accessible to Microsoft.Net developers.

      Enter Microsoft Roslyn, “a set of APIs for exposing the Microsoft C# and Visual Basic .NET compilers as services available at runtime.”

      This software is currently available as a community technology preview (CTP).

      Roslyn can be imagined as a “compiler as a Windows service” which VB and C# developers can access through the new Roslyn APIs.

      It allows the entire compile-execute process to be invoked from within .Net applications to, for example, give VB and C# a dynamic languages ability to generate and invoke code at runtime.

      Or, how about incorporating Roslyn into a .NET application that accepts user input then uses Roslyn APIs to process the input (remember how good old class VB could evaluate a string?)

      Roslyn is powerful but you won’t know how powerful it is until you try it out yourself.

      Download it today!


      Visual Basic WPF Using the Microsoft.Ink Library Mike McIntyre

      Incorporating digital ink into Visual Basic WPF applications is done with the Microsoft.Ink DLL. Ink has evolved COM and Windows Forms to full integration into the WPF. You do not need to install separate SDKs or runtime libraries.

      Below is an example of using procedural code with Ink. Ink can also be used with XAML.

       
      Imports Microsoft.Ink Public Class Form1 Dim WithEvents myInkOverlay As InkOverlay Dim selectedMode As InkOverlayEditingMode Sub New() ' This call is required by the Windows Form Designer. InitializeComponent() myInkOverlay = New InkOverlay(Panel1) myInkOverlay.Enabled = True End Sub 'Back of pen erase Sub CursorInRangeEventHandler(ByVal sender As Object, ByVal e As InkCollectorCursorInRangeEventArgs) Handles myInkOverlay.CursorInRange 'If the pen is inverted, set mode to "delete" If (e.Cursor.Inverted) Then myInkOverlay.EditingMode = InkOverlayEditingMode.Delete Else 'Pen is not inverted, so select whatever mode the user requested myInkOverlay.EditingMode = selectedMode End If End Sub 'Ink mode radio button Sub InkRadioClickedHandler(ByVal sender As Object, ByVal e As EventArgs) Handles RadioButton1.CheckedChanged If (RadioButton1.Checked) Then selectedMode = InkOverlayEditingMode.Ink DoModeChange(InkOverlayEditingMode.Ink) End If End Sub 'Select mode radio button Sub SelectRadioClickedHandler(ByVal sender As Object, ByVal e As EventArgs) Handles RadioButton2.CheckedChanged If (RadioButton2.Checked) Then selectedMode = InkOverlayEditingMode.Select DoModeChange(InkOverlayEditingMode.Select) End If End Sub 'Delete mode radio button Sub DeleteRadioClickedHandler(ByVal sender As Object, ByVal e As EventArgs) Handles RadioButton3.CheckedChanged If (RadioButton3.Checked) Then selectedMode = InkOverlayEditingMode.Delete DoModeChange(InkOverlayEditingMode.Delete) End If End Sub 'Wire up delete mode buttons 'Delete entire stroke Sub StrokeRadioClickedHandler(ByVal sender As Object, ByVal e As EventArgs) Handles RadioButton4.CheckedChanged 'Can be called during Form construction, prior to myInkOverlay instantiation If (myInkOverlay Is Nothing) Then Return End If If (RadioButton4.Checked) Then myInkOverlay.EraserMode = InkOverlayEraserMode.StrokeErase End If End Sub 'Delete point(s) at pen tip only Sub PointRadioClickedHandler(ByVal sender As Object, ByVal e As EventArgs) Handles RadioButton5.CheckedChanged If (RadioButton5.Checked) Then myInkOverlay.EraserMode = InkOverlayEraserMode.PointErase End If End Sub Sub DoModeChange(ByVal NewMode As InkOverlayEditingMode) 'Can be called during Form construction, prior to myInkOverlay instantiation If (myInkOverlay Is Nothing) Then Return End If 'Switch the collection mode myInkOverlay.EditingMode = NewMode 'Switch the radio buttons to reflect new mode Select Case NewMode Case InkOverlayEditingMode.Ink RadioButton1.Checked = True RadioButton2.Checked = False RadioButton3.Checked = False Case InkOverlayEditingMode.Select RadioButton1.Checked = False RadioButton2.Checked = True RadioButton3.Checked = False Case InkOverlayEditingMode.Delete RadioButton1.Checked = False RadioButton2.Checked = False RadioButton3.Checked = True Case Else Throw New ArgumentOutOfRangeException() End Select End Sub End Class
         

      Visual Basic ServiceContractAttribute Class Mike McIntyre

      The recommended way to create a Windows Communication Foundation (WCF) contract is with an interface. Acontract specifies the collection and structure of messages required to access the operations the service offers.

      The ServiceContractAttribute class is used to indicate that an interface or a class defines a service contract in a Windows Communication Foundation (WCF) application.

      A class can support multiple contracts by deriving and implementing multiple interfaces decorated with the ServiceContract attribute.

      <ServiceContract> _ Interface IMyContract <OperationContract> _ Function MyMethod() As String End Interface <ServiceContract> _ Interface IMyOtherContract <OperationContract> _ Sub MyOtherMethod() End Interface Class MyService Implements IMyContract Implements IMyOtherContract Public Function MyMethod() As String Implements IMyContract.MyMethod End Function Public Sub MyOtherMethod() Implements IMyOtherContract.MyOtherMethod End Sub End Class

      Visual Basic 2012– Caller Information Mike McIntyre

      New in Visual Basic 2012 is the caller information feature. This feature enables you to obtain information about the caller of a method.

      By using Caller Info attributes, you can obtain information about the caller to a method. You can obtain file path of the source code, the line number in the source code, and the member name of the caller. This information is helpful for tracing, debugging, and creating diagnostic tools.

      To obtain this information, you use attributes that are applied to optional parameters, each of which has a default value. 

      For more information about using the Caller Information feature click:

             Caller Information (C# and Visual Basic)

      Sample Use

      ' Imports System.Runtime.CompilerServices ' Imports System.Diagnostics Private Sub DoProcessing() TraceMessage("Something happened.") End Sub Public Sub TraceMessage(message As String, <CallerMemberName> Optional memberName As String = Nothing, <CallerFilePath> Optional sourcefilePath As String = Nothing, <CallerLineNumber()> Optional sourceLineNumber As Integer = 0) Trace.WriteLine("message: " & message) Trace.WriteLine("member name: " & memberName) Trace.WriteLine("source file path: " & sourcefilePath) Trace.WriteLine("source line number: " & sourceLineNumber) End Sub ' Sample output: ' message: Something happened. ' member name: DoProcessing ' source file path: C:\Users\username\Documents\Visual Studio 2012\Projects\CallerInfoVB\CallerInfoVB\Form1.vb ' source line number: 15

      Visual Basic 2012–Iterators Mike McIntyre

      Iterators are used to perform custom iteration over collections such as lists or arrays.

      Iterators make it possible to use the iterator programming pattern. Wikipedia states: “In object-oriented programming, the iterator pattern is a design pattern in which an iterator is used to traverse a container and access the container's elements. The iterator pattern decouples algorithms from containers; in some cases, algorithms are necessarily container-specific and thus cannot be decoupled.”

      Iterators can be used to create a custom iteration over array or collection class.

      Iterators can increase performance because they allow you to asynchronously consume the elements of a large collection.

      Iterators can decrease memory use too.

      Learn more by clicking: What's New for Visual Basic in Visual Studio 2012

      image