September 27th, 2011

Announcement: Namespace Global

There’s a new feature coming to VB, and already included in the Visual Studio 11 Developer Preview. The feature is called Namespace Global and it’ll make your life easier…

  • if you part of your code belongs in a different namespace from the rest of your project,
  • if you use code-generating tools, which need to choose which namespace they write into.

The MSDN reference on namespaces (including Namespace Global) is here: Namespaces in Visual Basic.

As an aside, I’d like to thank Shimmy Wietzhandler for requesting this feature in Microsoft Connect, and also the people who emailed or who wrote in with comments to Lucian Wischik’s VB language-design blog. It’s from user feedback like these that we decide which features to prioritize. For the future, we’ve launched the Visual Studio UserVoice site to gather together these kinds of feature requests.

Release note: the Visual Studio 11 Developer Preview doesn’t yet have full IDE support for the Namespace Global feature (e.g. NavigateTo doesn’t work). This in the works.

image001

 

Background

This feature is tied to the project’s Root Namespace, pictured above, which you find by double-clicking on “My Project” in the Solution Explorer. Every single class and namespace you write is implicitly placed inside that Root Namespace. Here’s an example class library I wrote:

    Public Class InsulinData
   
End
Class

    Public Class PatientID
   
End Class

    Namespace Utils
      
Public Class LinearRegressionSolver
      
End Class
   
End Namespace

The fully-qualified names of my classes are like these (note that you never actually need to write the prefix “Global” – I put it in here for completeness):

    Dim x As New Global.MedicalDeviceAnalysis.InsulinData
    Dim y As New Global.MedicalDeviceAnalysis.PatientID
    Dim z As New Global.MedicalDeviceAnalysis.Utils.LinearRegressionSolver

Most of the time, this is exactly what you want.

 

Problem

But in this particular case, I didn’t want “Utils.LinearRegressionSolver” to come under MedicalDeviceAnalysis – because it’s a general-purpose utility, and not specific to medical device analysis at all.

Fixing my code in VS2010 is awkward. I have to set MyProject > RootNamespace to nothing, and then go through my entire project manually putting every single class inside “Namespace MedicalDeviceAnalysis”.

 

 

Namespace Global

We have introduced a new way to “escape” your classes out of the project’s Root Namespace. It works like this:

    Namespace Global.Utils
       
Public Class LinearRegressionSolver
       
End Class
   
End Namespace

By writing “Namespace Global” explicitly, I get the classes where I want – regardless of the project’s Root Namespace:

    Dim x As New Global.MedicalDeviceAnalysis.InsulinData
    Dim y As New Global.MedicalDeviceAnalysis.PatientID
    Dim z As New Global.Utils.LinearRegressionSolver

 

Namespace Global: extension-method scenario

Here’s another scenario where Namespace Global will help. Let’s say that my MedicalDevice library has become quite large, composed of several class libraries and namespaces – for instance, one of the class libraries will have Root Namespace set to “MedicalDevice.Analysis”.

But I also established the convention that users merely need to “Imports MedicalDevice” to get all the extension methods. Here’s how:

Namespace Global.MedicalDevice
   
Public Module Extensions
       
<Extension>
       
Public Function AsPatientID(this As String) As MedicalDeviceAnalysis.PatientID
           
Return New MedicalDeviceAnalysis.PatientID(this)
       
End Function
   
End Module
End Namespace

We actually used this technique in the recent Async CTP. We wanted our extensions to be defined in the global namespace so that people could use them without having to import anything. (This design is generally frowned upon, but it made sense in this case). Again, we used the Namespace Global feature:

Namespace Global
    Public Module AsyncCtpExtensions
       
<Extension>
       
Public Function DownloadStringTaskAsync(this As WebClient) As Task(Of String)
           
‘ …
       
End Function
   
End Module
End Namespace

 

 

Namespace Global: codegen scenario

One important behind-the-scenes use of Namespace Global is for code-generation tools. Let’s say (for instance) that you wrote a T4 template which automatically spits out code, but it needs the code to go inside a particular namespace. The T4 template can’t make any assumptions about Root Namespace.

Now, using Namespace Global, the T4 template can chose precisely which namespace to use for its generated code.

 

Namespace Global: under the hood of VB-Core

We in the VB team used Namespace Global for a powerful new feature that came in VS2010 SP1 called “VB-Core”. The point of VB-Core is to embed a small part of Microsoft.VisualBasic.dll inside your own assembly, so you can produce a stand-alone executable that works even on platforms which lack the DLL such as the Micro Framework.

The VB compiler actually embeds that small part of Microsoft.VisualBasic as a “ghost” .vb source file which it implicitly adds to your project. The classes defined in that file must go inside the namespace Global.Microsoft.VisualBasic: they cannot be nested inside the project’s Root Namespace. I’m sure you can guess how the ghost file starts…

“Namespace Global.Microsoft.VisualBasic” & vbCrLf &
”  Namespace CompilerServices” & vbCrLf &
”    Friend Class Operators” & vbCrLf &
”      Public Shared Function CompareString(Left As String, Right As String, TextCompare As Boolean) As Integer” & vbCrLf &
”        If Left Is Right Then Return 0″ & vbCrLf &

 

 

Namespace Global: specification

In addition to the existing VS2010 namespace declarations, VB will allow two new forms of namespace declaration:

Namespace Global
Namespace Global.<NamespaceName>

These are both only allowed at top level in a source file (i.e. not nested inside any other Namespace declaration). The first form declares that its contents will go inside the global namespace. The second form declares a namespace within the global namespace, and puts its contents there.

Full details are at MSDN: Namespaces in Visual Basic.

Author

0 comments