14.4. Your Turn

While the My namespace is already loaded with numerous productivity shortcuts, it has been put together with the average Visual Basic developer in mind. There are always going to be cases where you go looking for a shortcut that just isn't there. In these cases it's possible to extend the namespace in a couple of different ways.

14.4.1. Methods and Properties

The simplest way to extend the My namespace is to add your own methods or properties. These can be stand-alone, or they can belong to one of the existing My namespace classes. For example, the following function, which extracts name-value pairs from a string into a dictionary, is a stand-alone function and will appear at the top level of the My namespace.

Namespace My
    <HideModuleName()> _
    Module StringHelpers
        Friend Function ParseString(ByVal stringToParse As String, _
                                     ByVal pairSeparator As Char, _
                                     ByVal valueSeparator As Char) _
                                                  As Dictionary(Of String, String)
            Dim dict As New Dictionary(Of String, String)
            Dim nameValues = From pair In stringToParse.Split(pairSeparator), _
                                   values In pair.Split(valueSeparator) _
                             Select New With {.Name = values(0), _
                                              .Value = values(1)}
            For Each nv In nameValues
                dict.Item(nv.Name) = nv.Value
            Next
            Return dict
        End Function

   End Module
End Namespace

Figure 14-3 illustrates that the StringHelpers module is completely hidden when you're accessing this function.

Figure 14.3. Figure 14-3

As both My.Application and My.Computer return an instance of a generated partial class, you can extend them by adding properties and methods. To do so, you need to create the partial classes MyApplication and MyComputer in which to place your new functionality. As the following snippet shows, you can even maintain state, as My.Computer will return a single instance (per thread) of the MyComputer class.

Namespace My
    Partial Class MyComputer
        Private mCounter As Integer = 0
        Friend Property VeryAccessibleCounter() As Integer
            Get
                Return mCounter
            End Get
            Set(ByVal value As Integer)
                mCounter = value
            End Set
        End Property
    End Class
End Namespace

14.4.2. Extending the Hierarchy

So far, you have seen how you can add methods and properties to existing points in the My namespace. You'll be pleased to know that you can go further by creating your own classes that can be exposed as part of the My namespace. In the following example we have the MyStringHelper class (following the naming pattern used by the framework), which is exposed via the StringHelper property in the module.

Namespace My
    <HideModuleName()> _
    Module StringHelpers
        Private mHelper As New ThreadSafeObjectProvider(Of MyStringHelper)
        Friend ReadOnly Property StringHelper() As MyStringHelper
            Get
                Return mHelper.GetInstance()
            End Get
        End Property
    End Module

    <System.ComponentModel.EditorBrowsable(System.ComponentModel
.EditorBrowsableState.Never)> _
    Friend NotInheritable Class MyStringHelper

Friend Function ParseString(ByVal stringToParse As String, _
                                     ByVal pairSeparator As Char, _
                                     ByVal valueSeparator As Char) _
                                                   As Dictionary(Of String, String)
            Dim dict As New Dictionary(Of String, String)
            Dim nameValues = From pair In stringToParse.Split(pairSeparator), _
                                   values In pair.Split(valueSeparator) _
                             Select New With {.Name = values(0), _
                                              .Value = values(1)}
            For Each nv In nameValues
                dict.Item(nv.Name) = nv.Value
            Next
            mParseCount += 1
            Return dict
        End Function

        Private mParseCount As Integer = 0
        Friend ReadOnly Property ParseCount() As Integer
            Get
                Return mParseCount
            End Get
        End Property
    End Class
End Namespace

Unlike in the previous case, where we extended the MyComputer class, here we have had to use the EditorBrowsable attribute to ensure that the MyStringHelper class doesn't appear via IntelliSense. Figure 14-4 illustrates how My.StringHelper would appear within Visual Studio 2008.

Figure 14.4. Figure 14-4

As with My.Computer, our addition to the My namespace is thread-safe, as we used the single-instance backing pattern with the ThreadSafeObjectProvider(of T) class. Like regular classes, your additions to the My namespace can raise events that you can consume in your application. If you wish to expose your event via My.Application (like the Startup and Shutdown events), you can either declare the event within the MyApplication partial class or use a custom event to reroute the event from your class through the MyApplication class.

14.4.3. Packaging and Deploying

Now that you have personalized the My namespace, you may wish either to share it with colleagues or make it available for other projects that you are working on. To do this you need to package what you have written using the Export Template feature of Visual Studio 2008. With some minor tweaks, this package will then be recognized by Visual Studio as an extension to the My namespace, allowing it to be added to other projects.

You can export your code with the Export Template Wizard, accessible via the Export Template item on the File menu. This wizard will guide you through the steps necessary in order to export your code as an Item template with any assembly references your code may require. Since you need to modify the template before importing it back into Visual Studio 2008, it is recommended that you uncheck the "Automatically import the template into Visual Studio" option on the final page of the wizard.

The compressed file created by this wizard contains your code file, an icon file, and a .vstemplate file that defines the structure of the template. To identify this template as an extension of the My namespace, you need to modify the .vstemplate file to include a CustomDataSignature element. As you can't modify the .vstemplate within the compressed file, you will need to either copy it out, modify it and replace the original file, or expand the whole compressed file. The last choice will make the next step, that of adding a new file to the compressed file, easier.

<VSTemplate Version="2.0.0"
xmlns="http://schemas.microsoft.com/developer/vstemplate/2005" Type="Item">
    <TemplateData>
        <DefaultName>My String Helper.vb</DefaultName>
        <Name>My String Helper</Name>
        <Description>&lt;No description available&gt;</Description>
        <ProjectType>VisualBasic</ProjectType>
        <SortOrder>10</SortOrder>
        <Icon>__TemplateIcon.ico</Icon>
       <CustomDataSignature>Microsoft.VisualBasic.MyExtension</CustomDataSignature>
    </TemplateData>
    <TemplateContent>
        <References />
        <ProjectItem SubType="Code" TargetFileName="$fileinputname$.vb"
              ReplaceParameters="true">StringHelperMyExtension.vb</ProjectItem>
    </TemplateContent>
</VSTemplate>

This snippet illustrates the new CustomDataSignature element in the .vstemplate file, which Visual Studio 2008 uses as a key to look for an additional .CustomData file. In order to complete the template you need to create a .CustomData file (the name of the file is actually irrelevant) that contains a single XML element.

<VBMyExtensionTemplate
    ID="Custom.My.Extension"
    Version="1.0.0.0"
    AssemblyFullName="System.Configuration"
/>

The Id and Version attributes are used to uniquely identify the extension so that it is not added to a project more than once. The AssemblyFullName attribute is optional and indicates that when an assembly is added to a project that has this name, this template should be invoked to extend the My namespace.

Once you have created this file you need to recompress all the files that make up the template. This file should then be added to the DocumentsVisual Studio 2008TemplatesItemTemplatesVisual Basic folder, which will import the template into Visual Studio 2008 the next time it is started. You can now add your extension to the My namespace to any project by clicking the "Add extension . . ." button on the My Extensions tab of the Project Properties dialog, as shown in Figure 14-5.

Figure 14.5. Figure 14-5

As mentioned earlier, you can set up your extension to be automatically added when an assembly with a specific name is added to a project. In the example the assembly was System.Configuration, and Figure 14-6 illustrates adding it to a project. Accepting this dialog will make the extension we just created available within this project.

Figure 14.6. Figure 14-6

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.15.137.75