扩展 Visual Basic 中的 My 命名空间

Visual Basic 中的 My 命名空间公开了一些属性和方法,您可以利用这些属性和方法来轻松使用 .NET Framework 强大功能。My 命名空间可以简化常见编程问题,它通常可将一个困难的任务简化为一行代码。此外,My 命名空间可完全扩展,使您可以自定义 My 的行为,并可向其层次结构添加新服务,从而满足特定应用程序需求。本主题将讨论如何自定义 My 命名空间的现有成员,以及如何将自己的自定义类添加到 My 命名空间中。

主题内容

  • 自定义现有 My 命名空间成员

  • 向 My 对象添加成员

  • 向 My 命名空间添加自定义对象

  • 向 My 命名空间添加成员

  • 向自定义 My 对象添加事件

  • 设计准则

  • 为 My 设计类库

  • 打包和部署扩展

自定义现有 My 命名空间成员

Visual Basic 中的 My 命名空间公开了有关应用程序、计算机等的常用信息。有关 My 命名空间中对象的完整列表,请参见 My 引用 (Visual Basic)。您可能需要自定义 My 命名空间的现有成员,以使它们能更好地满足您应用程序的需求。My 命名空间中的对象的任何属性,只要不是只读,则就可设置为自定义值。

例如,假定您经常使用 My.User 对象来访问运行您应用程序的用户的当前安全上下文。但是,您公司使用自定义用户对象来公开公司内部用户的其他信息和功能。在这种情况下,您可以将 My.User.CurrentPrincipal 属性的默认值替换为您自己的自定义主体对象的实例,如下面的示例中所示。

My.User.CurrentPrincipal = CustomPrincipal

设置 My.User 对象的 CurrentPrincipal 属性,更改应用程序运行时所用的标识。然后,My.User 对象就会返回新指定用户的相关信息。

向 My 对象添加成员

从 My.Application 和 My.Computer 返回的类型定义为 Partial 类。因此,您可以通过创建名称为 MyApplication 或 MyComputerPartial 的类来扩展 My.Application 和 My.Computer 对象。该类不能为 Private 类。如果将该类指定为 My 命名空间的部分,则可添加将要包括到 My.Application 或 My.Computer 对象的属性和方法。

例如,下面的示例将名称为 DnsServerIPAddresses 的属性添加到了 My.Computer 对象。

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

向 My 命名空间添加自定义对象

虽然 My 命名空间提供了许多常见编程任务的解决方案,但是您还可能会遇到 My 命名空间未提供其解决方案的任务。例如,您的应用程序可能需要访问自定义目录服务以获取用户数据,或者需要使用默认情况下不与 Visual Basic 一起安装的程序集。如果出现这种情况,您就可扩展 My 命名空间,以将自定义解决方案包含到特定于您环境的常规任务中。My 命名空间扩展方便,可轻松添加新成员,从而满足不断增长的应用程序需求。此外,您还可以将 My 命名空间扩展作为 Visual Basic 模板,部署到其他开发人员的开发环境中。

Bb531245.collapse_all(zh-cn,VS.110).gif向 My 命名空间添加成员

由于 My 是一个命名空间,与其他所有命名空间类似;因此,您只需添加模块并指定 My 的 Namespace,就可向其中添加顶级属性。使用 HideModuleName 特性可以批注模块,如下面的示例中所示。HideModuleName 特性可确保 IntelliSense 显示 My 命名空间的成员时不显示模块名称。

Namespace My
  <HideModuleName()> 
  Module MyCustomModule

  End Module
End Namespace

若要向 My 命名空间添加成员,则请根据需要向模块添加属性。对于添加到 My 命名空间的每个属性,请添加类型为 ThreadSafeObjectProvider(Of T) 的私有字段;其中,类型是您的自定义属性所返回的类型。此字段用于创建线程安全对象实例,您的自定义属性将通过调用 GetInstance 方法来返回该实例。这样,访问扩展属性的每个线程就可接收其自己的返回类型的实例。下面的示例将类型为 SampleExtension、名称为 SampleExtension 的属性添加到了 My 命名空间:

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

向自定义 My 对象添加事件

您可以使用 My.Application 对象,通过扩展 My 命名空间中的 MyApplication 分部类来公开您的自定义 My 对象的事件。对于基于 Windows 的项目,您可以在解决方案资源管理器中,双击项目的**“我的项目”节点。在 Visual Basic“项目设计器”**中,单击 Application 选项卡,然后单击 View Application Events 按钮。然后,将会创建一个名称为 ApplicationEvents.vb 的新文件。该文件中包含下面的用于扩展 MyApplication 类的代码。

Namespace My
  Partial Friend Class MyApplication
  End Class
End Namespace

您可以通过将自定义事件处理程序添加到 MyApplication 类,来为您的自定义 My 对象添加事件处理程序。您可以利用自定义事件,来添加当添加、移除事件处理程序或引发事件时要执行的代码。注意,仅当用户为了处理事件而添加了代码时,自定义事件的 AddHandler 代码才会运行。例如,请考虑上一节中的 SampleExtension 对象,该对象具有一个 Load 事件,且您要为该对象添加自定义事件处理程序。下面的代码示例演示了名称为 SampleExtensionLoad 的自定义事件处理程序,当发生 My.SampleExtension.Load 事件时,将会调用该自定义事件处理程序。当为了处理新的 My.SampleExtensionLoad 事件而添加代码时,将执行此自定义事件代码的 AddHandler 部分。代码示例中包含有 MyApplication_SampleExtensionLoad 方法,目的是给出一个处理 My.SampleExtensionLoad 事件的事件处理程序的示例。注意,在编辑 ApplicationEvents.vb 文件时,如果选中位于“代码编辑器”上方的下拉列表中的**“我的应用程序事件”**选项,则 SampleExtensionLoad 事件将可用。

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

设计准则

开发 My 命名空间的扩展时,请遵循下面的准则,以帮助您将您的扩展组件的维护成本降到最低。

  • **只包含扩展逻辑。**My 命名空间扩展中包含的逻辑应只包括公开 My 命名空间中所需功能时要用到的代码。由于您的扩展将作为源代码驻留在用户项目中,更新扩展组件将带来高昂的维护成本,因此如果可能,请避免更新扩展组件。

  • **最大限度地减少项目假设。**创建 My 命名空间的扩展时,请不要假定一组引用、项目级导入或特定编译器设置(例如,将 Option Strict 设置为 off)。相反,要最小化依赖项,并使用 Global 关键字完全限定所有类型引用。同时,还要确保编译扩展时,Option Strict 为 on,从而将扩展中的错误降到最少。

  • **隔离扩展代码。**将代码置于单个文件中,可使您的扩展轻松部署为 Visual Studio 项模板。有关更多信息,请参见本主题后面的“打包和部署扩展”。将所有 My 命名空间扩展代码置于项目中的单个文件或文件夹中,还将有助于用户查找 My 命名空间扩展。

为 My 设计类库

对于多数对象模型,某些设计模式在 My 命名空间中运转正常,但其他设计模式则不然。设计 My 命名空间的扩展时,请考虑下面的原则:

  • **无状态方法。**My 命名空间中的方法应提供特定任务的完整解决方案。请确保传递给方法的参数值要提供完成特定任务所需的所有输入。避免创建依赖于先前状态的方法,例如到资源的打开连接。

  • **全局实例。**只有 My 命名空间中维护的状态对于项目是全局性的。例如,My.Application.Info 可封装整个应用程序中共享的状态。

  • **简单参数类型。**为简单起见,请避免使用复杂的参数类型。请创建不带参数输入或带简单的参数输入类型(如字符串、基元类型等)的方法。

  • **工厂方法。**在某些类型的实例化过程中,会遇到不可避免的困难。将工厂方法作为 My 命名空间的扩展提供,这样您就可更容易地发现并使用此类类型。My.Computer.FileSystem.OpenTextFileReader 便是一个非常有效的工厂方法示例。.NET Framework 中有多种流类型。通过明确指定文本文件,OpenTextFileReader 可帮助用户理解要使用哪个流。

这些准则并不排除类库的常规设计原则。相反,它们只是一些建议,专门针对使用 Visual Basic 和 My 命名空间的开发者进行了优化。有关创建类库的常规设计原则的信息,请参见Design Guidelines for Developing Class Libraries

打包和部署扩展

您可将 My 命名空间扩展包含在 Visual Studio 项目模板中,或者将您的扩展打包并部署为 Visual Studio 项模板。您在将 My 命名空间扩展打包为 Visual Studio 项模板时,可以利用 Visual Basic 提供的其他功能。您可以利用这些功能,在项目引用特定程序集时包含扩展;用户可以利用这些功能,通过使用 Visual Basic 项目设计器的**“My 扩展”**页,显式添加您的 My 命名空间扩展。

有关如何部署 My 命名空间扩展的详细信息,请参见打包和部署自定义 My 扩展 (Visual Basic)

请参见

参考

“项目设计器”->“My 扩展”页 (Visual Basic)

“项目设计器” ->“应用程序”页 (Visual Basic)

分部 (Visual Basic)

概念

打包和部署自定义 My 扩展 (Visual Basic)

扩展 Visual Basic 应用程序模型

自定义 My 中可用的对象 (Visual Basic)