Adopting Visual Studio Online (formerly TFS Service)

Brian Harry has written a post referencing this other post: “How Visual Studio Online won me over in under 90 minutes“. It happens that I also adopted Visual Studio Online less than I week ago and I am thrilled about it since then. In the past I used and investigated source code providers (Perforce, Subversion, TFS, …) installed locally but I was looking for some solution to the repository backup/restore “annoyance” (after a failed restore that I suffered long time ago). While I already played with TFS Service some months ago, it was not until the past Wednesday when I gave it a serious chance. I uploaded a solution of one of my projects that is part of a bigger source folder and after realizing that it was better to make some adjustments in the folder structure before uploading last Friday I uploaded all my Visual Studio solutions. Since then I am enjoying it a lot because of the following new scenarios:

– I have a backup on the cloud each time that I check-in some file (instead of a making a backup by hand from time to time).

– I can use more than one computer at home (I have a tiny MacBook Air 11″ and a huge iMac 27″) to develop without copying code through USB drives or having a central “server”.

– I can use any device (such as a tablet or smartphone) with an internet connection to view the source code of the files, whenever I want.

– I can see and create/update work items from any device (instead of using Excel or the tasks of an Outlook .pst file as before). Or rather than using a separate application such as Trello.

Now I am playing with gated check-ins, code analysis execution, automated tests, etc.

Visual Studio Online has several plans, one of them (Basic) completely free for up to 5 users:
http://www.visualstudio.com/products/visual-studio-online-user-plans-vs

And some videos to get started are:

Getting Started with Source Control with Visual Studio Online
http://channel9.msdn.com/Shows/Visual-Studio-Toolbox/Getting-Started-with-Source-Control-with-Visual-Studio-Online

Getting Started with Visual Studio Online
http://channel9.msdn.com/Events/Build/2014/2-575

Welcome to Visual Studio Online
http://channel9.msdn.com/Series/Visual-Studio-Online

Using Roslyn (The future of C# Build 2014 session)

I recommend to watch the following 1-hour recorded session of the past Build 2014 Developer Conference to learn about Roslyn (a.k.a the “compiler as service”):

The Future of C#
http://channel9.msdn.com/Events/Build/2014/2-577

The title is somewhat misleading, since the session is not so much about the future of C# (the language) but about the C# compiler, that is, Roslyn. It also covers VB.NET, by the way.  In that session Dustin Campbell shows demos about using Roslyn to do powerful things with the code in a (apparently) very easy manner.

One cool thing (for developers of Visual Studio extensions) is that the Visual Studio IDE will use only the same public API that is offered to extensions. That should guarantee that no longer happens what is happening so far: while VS has access to the compiler, your add-in or package has to use the code model (EnvDTE.Project.CodeModel, EnvDTE.ProjectItem.FileCodeModel), which is much less powerful and much more buggy.

It also seems that Roslyn will be very well documented, and furthermore being open source you can examine it, rather than using reverse-engineering.

Roslyn (.NET compilers as services) now open source

The greatest announcement for developers of Visual Studio extensions in the past days has been about Roslyn, the .NET compiler platform that will allow you to use the compilers as services, and that will be open source.

Even in closed form Roslyn would be great, because the current automation code model (EnvDTE.Project.CodeModel, EnvDTE.ProjectItem.FileCodeModel), apart from being entirely missing for some .NET languages such as F#:

  • It is very limited, either to get information or to emit code.
  • It has lots of bugs that I have reported on Microsoft Connect (see the “BUG” articles in the “Articles about the code model” section of my web site)
  • Microsoft decided not to improve it long time ago (and not to fix bugs, either).
  • Being native (not managed) can cause OutOfMemoryException due to memory fragmentation.

None of those things will happen with Roslyn for C# and VB.NET (other languages will have to wait, though), because they will be the compilers used by Visual Studio (starting with VS 2013 if you want) for those languages and Microsoft is changing Visual Studio to use only the public APIs of the parsers/compilers/etc. that will be available for Visual Studio extensions. So, any problem / limitation with the compilers and your extension is a problem for Visual Studio too.

And as if that was not enough, you can have the source code too!

Now, this raises some questions also for developer of Visual Studio extensions:

  • What to do with other languages apart from C# and .NET if your extension supports them (not the case of my MZ-Tools add-in)
  • Since Roslyn will be available for VS 2013 and higher, what to do if an extension has to support older versions (VS 2010, 2012 at least)…
  • What to do if you have a huge investment in the previous technologies (automation code model or your own parsers). For example, ReSharper has decided not to use Roslyn

And of course, the next thing that would most benefit developers of Visual Studio extensions is to open the Visual Studio assemblies. I don’t mean to “open source” but simply “reference source” (like the .NET Framework Reference Source) and “step source” (like .NET Framework Step Source) would be huge. Since opening the .NET compilers has taken years for Microsoft, I guess that we will have to wait, but I hope…

Debugging .NET Framework now working

Apart from the new .NET Reference Source experience, another thing that Microsoft has improved (well, has made actually work) is the Debugging .NET Framework feature of Visual Studio, which until recently was basically broken. Now, that feature doesn’t break with changes in the .NET Framework binaries due to security patches or hotfixes. Although Microsoft’s post mentions that it works with Microsoft .NET 4.5.1, it actually works with Microsoft .NET 4.0 and Microsoft .NET 4.5, at least if you have Microsoft .NET 4.5.1 installed (since 4.5 and 4.5.1 are in-place .NET Framework updates sharing the same CLR 4.0).

It definitely doesn’t work with .NET Framework 2.0, which, alas, is what I am still using in my MZ-Tools add-in (to support Visual Studio 2005/2008). But I guess that I can switch temporarily to .NET Framework 4.0 when I need to debug some .NET Framework assembly (just yesterday I needed to).

Of course, you can’t debug Visual Studio assemblies with that feature because their symbols are not available, but you can do it with .NET Reflector, as I explained in my article and in their blog as a guest post.

The new .NET Reference Source experience

In the last weeks Microsoft has made a series of announcements that will benefit a lot to .NET developers. The first one is the new .NET Reference Source experience. While the http://referencesource.microsoft.com/ site has existed for a while, now it provides new tools to navigate the code like you are used to in Visual Studio (Go To Definition, Find References, etc.). This means that for some scenarios (navigating the code of the .NET Framework assemblies) you don’t need tools such as Reflector .NET or JustDecompile. Of course these tools are still required in many other scenarios, since, for example, the source code of Visual Studio assemblies is not available.

The .NET Reference Source provides also these benefits:

  • You can download the code in a .zip file for off-line browsing.
  • You don’t need a Windows computer to browse the code. A tablet or even a smartphone will work.
  • You have the comments of the source code. Not just the headers, which are
    useless, but the ones inside the methods explaining why some things are
    done in some way (how a bug was fixed, etc.).

For example, last night I used my iPad to browse a couple of things that I was intrigued about:

Years ago I reported a bug in LadyBug (before Microsoft Connect) in the System.Drawing.Color.Equals method. The bug report is no longer available but I remembered that it was related to a comparison of two names that always returned true because the name variable was the same. And yesterday I found it is still there:

public override bool Equals(object obj) {
   if (obj is Color) {
      Color right = (Color)obj;
      if (value == right.value && state == right.state && knownColor == right.knownColor) {
         if (name == right.name) {
            return true;
         }
         if (name == (object) null || right.name == (object) null) {
            return false;
         }
         return name.Equals(name);
      }
   }
   return false;
}

The second one is a tough problem that I was dealing with lately involving COM Reflection (not .NET Reflection). The problem is, given a COM object, how to know its class name (not its interface name). I knew that VB.NET (like VB6 before) has a handy Information.TypeName() method in the Microsoft.VisualBasic assembly, which always seems to return a class name instead of an interface name. Browsing its implementation, I realized that the TypeNameOfCOMObject and LegacyTypeNameOfCOMObject methods are cheating cleaning up the type name:

   Friend Function LegacyTypeNameOfCOMObject(ByVal VarName As Object, ByVal bThrowException As Boolean) As String

      Dim Result As String = COMObjectName

      Try
         Call (New SecurityPermission(SecurityPermissionFlag.UnmanagedCode)).Demand()
      Catch ex As StackOverflowException
         Throw ex
      Catch ex As OutOfMemoryException
         Throw ex
      Catch ex As System.Threading.ThreadAbortException
         Throw ex
      Catch e As Exception
         If bThrowException Then
            Throw e
         Else
            GoTo CleanupTypeName
         End If
      End Try

      Dim pTypeInfo As UnsafeNativeMethods.ITypeInfo = Nothing
      Dim hr As Integer
      Dim ClassName As String = Nothing
      Dim DocString As String = Nothing
      Dim HelpContext As Integer
      Dim HelpFile As String = Nothing

      Dim pDispatch As UnsafeNativeMethods.IDispatch = TryCast(VarName, UnsafeNativeMethods.IDispatch)

      If pDispatch IsNot Nothing Then
         hr = pDispatch.GetTypeInfo(0, UnsafeNativeMethods.LCID_US_ENGLISH, pTypeInfo)
         If hr >= 0 Then
            hr = pTypeInfo.GetDocumentation(-1, ClassName, DocString, HelpContext, HelpFile)
            If hr >= 0 Then
               Result = ClassName
            End If
         End If
      End If

CleanupTypeName:

      If Result.Chars(0) = "_"c Then
         Result = Result.Substring(1)
      End If

      Return Result

   End Function

That is, if the name starts with “_” (which likely means it is an interface), the class name that implements that interface is the same name without that character, which can be true sometimes but definitely not most of the time.