Extending the My Namespace in Visual Basic
My namespace in Visual Basic exposes properties and methods that enable you to easily take advantage of the power of the .NET Framework. The
My namespace simplifies common programming problems, often reducing a difficult task to a single line of code. Additionally, the
My namespace is fully extensible so that you can customize the behavior of
My and add new services to its hierarchy to adapt to specific application needs. This topic discusses both how to customize existing members of the
My namespace and how to add your own custom classes to the
Customizing Existing My Namespace Members
My namespace in Visual Basic exposes frequently used information about your application, your computer, and more. For a complete list of the objects in the
My namespace, see My Reference. You may have to customize existing members of the
My namespace so that they better match the needs of your application. Any property of an object in the
My namespace that is not read-only can be set to a custom value.
For example, assume that you frequently use the
My.User object to access the current security context for the user running your application. However, your company uses a custom user object to expose additional information and capabilities for users within the company. In this scenario, you can replace the default value of the
My.User.CurrentPrincipal property with an instance of your own custom principal object, as shown in the following example.
My.User.CurrentPrincipal = CustomPrincipal
CurrentPrincipal property on the
My.User object changes the identity under which the application runs. The
My.User object, in turn, returns information about the newly specified user.
Adding Members to My Objects
The types returned from
My.Computer are defined as
Partial classes. Therefore, you can extend the
My.Computer objects by creating a
Partial class named
MyComputer. The class cannot be a
Private class. If you specify the class as part of the
My namespace, you can add properties and methods that will be included with the
For example, the following example adds a property named
DnsServerIPAddresses to the
Imports System.Net.NetworkInformation Namespace My Partial Class MyComputer Friend ReadOnly Property DnsServerIPAddresses() As IPAddressCollection Get Dim dnsAddressList As IPAddressCollection = Nothing For Each adapter In System.Net.NetworkInformation. NetworkInterface.GetAllNetworkInterfaces() Dim adapterProperties = adapter.GetIPProperties() Dim dnsServers As IPAddressCollection = adapterProperties.DnsAddresses If dnsAddressList Is Nothing Then dnsAddressList = dnsServers Else dnsAddressList.Union(dnsServers) End If Next adapter Return dnsAddressList End Get End Property End Class End Namespace
Adding Custom Objects to the My Namespace
My namespace provides solutions for many common programming tasks, you may encounter tasks that the
My namespace does not address. For example, your application might access custom directory services for user data, or your application might use assemblies that are not installed by default with Visual Basic. You can extend the
My namespace to include custom solutions to common tasks that are specific to your environment. The
My namespace can easily be extended to add new members to meet growing application needs. Additionally, you can deploy your
My namespace extensions to other developers as a Visual Basic template.
Adding Members to the My Namespace
My is a namespace like any other namespace, you can add top-level properties to it by just adding a module and specifying a
My. Annotate the module with the
HideModuleName attribute as shown in the following example. The
HideModuleName attribute ensures that IntelliSense will not display the module name when it displays the members of the
Namespace My <HideModuleName()> Module MyCustomModule End Module End Namespace
To add members to the
My namespace, add properties as needed to the module. For each property added to the
My namespace, add a private field of type
ThreadSafeObjectProvider(Of T), where the type is the type returned by your custom property. This field is used to create thread-safe object instances to be returned by the property by calling the
GetInstance method. As a result, each thread that is accessing the extended property receives its own instance of the returned type. The following example adds a property named
SampleExtension that is of type
SampleExtension to the
Namespace My <HideModuleName()> Module MyCustomExtensions Private _extension As New ThreadSafeObjectProvider(Of SampleExtension) Friend ReadOnly Property SampleExtension() As SampleExtension Get Return _extension.GetInstance() End Get End Property End Module End Namespace
Adding Events to Custom My Objects
You can use the
My.Application object to expose events for your custom
My objects by extending the
MyApplication partial class in the
My namespace. For Windows-based projects, you can double-click the My Project node in for your project in Solution Explorer. In the Visual Basic Project Designer, click the
Application tab and then click the
View Application Events button. A new file that is named ApplicationEvents.vb will be created. It contains the following code for extending the
Namespace My Partial Friend Class MyApplication End Class End Namespace
You can add event handlers for your custom
My objects by adding custom event handlers to the
MyApplication class. Custom events enable you to add code that will execute when an event handler is added, removed, or the event is raised. Note that the
AddHandler code for a custom event runs only if code is added by a user to handle the event. For example, consider that the
SampleExtension object from the previous section has a
Load event that you want to add a custom event handler for. The following code example shows a custom event handler named
SampleExtensionLoad that will be invoked when the
My.SampleExtension.Load event occurs. When code is added to handle the new
My.SampleExtensionLoad event, the
AddHandler part of this custom event code is executed. The
MyApplication_SampleExtensionLoad method is included in the code example to show an example of an event handler that handles the
My.SampleExtensionLoad event. Note that the
SampleExtensionLoad event will be available when you select the My Application Events option in the left drop-down list above the Code Editor when you are editing the ApplicationEvents.vb file.
Namespace My Partial Friend Class MyApplication ' Custom event handler for Load event. Private _sampleExtensionHandlers As EventHandler Public Custom Event SampleExtensionLoad As EventHandler AddHandler(ByVal value As EventHandler) ' Warning: This code is not thread-safe. Do not call ' this code from multiple concurrent threads. If _sampleExtensionHandlers Is Nothing Then AddHandler My.SampleExtension.Load, AddressOf OnSampleExtensionLoad End If _sampleExtensionHandlers = System.Delegate.Combine(_sampleExtensionHandlers, value) End AddHandler RemoveHandler(ByVal value As EventHandler) _sampleExtensionHandlers = System.Delegate.Remove(_sampleExtensionHandlers, value) End RemoveHandler RaiseEvent(ByVal sender As Object, ByVal e As EventArgs) If _sampleExtensionHandlers IsNot Nothing Then _sampleExtensionHandlers.Invoke(sender, e) End If End RaiseEvent End Event ' Method called by custom event handler to raise user-defined ' event handlers. <Global.System.ComponentModel.EditorBrowsable( Global.System.ComponentModel.EditorBrowsableState.Advanced)> Protected Overridable Sub OnSampleExtensionLoad( ByVal sender As Object, ByVal e As EventArgs) RaiseEvent SampleExtensionLoad(sender, e) End Sub ' Event handler to call My.SampleExtensionLoad event. Private Sub MyApplication_SampleExtensionLoad( ByVal sender As Object, ByVal e As System.EventArgs ) Handles Me.SampleExtensionLoad End Sub End Class End Namespace
When you develop extensions to the
My namespace, use the following guidelines to help minimize the maintenance costs of your extension components.
Include only the extension logic. The logic included in the
Mynamespace extension should include only the code that is needed to expose the required functionality in the
Mynamespace. Because your extension will reside in user projects as source code, updating the extension component incurs a high maintenance cost and should be avoided if possible.
Minimize project assumptions. When you create your extensions of the
Mynamespace, do not assume a set of references, project-level imports, or specific compiler settings (for example,
Option Strictoff). Instead, minimize dependencies and fully qualify all type references by using the
Globalkeyword. Also, ensure that the extension compiles with
Option Stricton to minimize errors in the extension.
Isolate the extension code. Placing the code in a single file makes your extension easily deployable as a Visual Studio item template. For more information, see "Packaging and Deploying Extensions" later in this topic. Placing all the
Mynamespace extension code in a single file or a separate folder in a project will also help users locate the
Designing Class Libraries for My
As is the case with most object models, some design patterns work well in the
My namespace and others do not. When designing an extension to the
My namespace, consider the following principles:
Stateless methods. Methods in the
Mynamespace should provide a complete solution to a specific task. Ensure that the parameter values that are passed to the method provide all the input required to complete the particular task. Avoid creating methods that rely on prior state, such as open connections to resources.
Global instances. The only state that is maintained in the
Mynamespace is global to the project. For example,
My.Application.Infoencapsulates state that is shared throughout the application.
Simple parameter types. Keep things simple by avoiding complex parameter types. Instead, create methods that either take no parameter input or that take simple input types such as strings, primitive types, and so on.
Factory methods. Some types are necessarily difficult to instantiate. Providing factory methods as extensions to the
Mynamespace enables you to more easily discover and consume types that fall into this category. An example of a factory method that works well is
My.Computer.FileSystem.OpenTextFileReader. There are several stream types available in the .NET Framework. By specifying text files specifically, the
OpenTextFileReaderhelps the user understand which stream to use.
These guidelines do not preclude general design principles for class libraries. Rather, they are recommendations that are optimized for developers who are using Visual Basic and the
My namespace. For general design principles for creating class libraries, see Framework Design Guidelines.
Packaging and Deploying Extensions
You can include
My namespace extensions in a Visual Studio project template, or you can package your extensions and deploy them as a Visual Studio item template. When you package your
My namespace extensions as a Visual Studio item template, you can take advantage of additional capabilities provided by Visual Basic. These capabilities enable you to include an extension when a project references a particular assembly, or enable users to explicitly add your
My namespace extension by using the My Extensions page of the Visual Basic Project Designer.
For details about how to deploy
My namespace extensions, see Packaging and Deploying Custom My Extensions.