Tuesday, March 22, 2011

Compiling Visual Basic, C# & F# Code Into A Single DLL Using msbuild

Recently I had a requirement in which a C# file had to be included in a VB.Net project. I knew I couldn't add the file directly to the project, so I cut over the C# file to VB.Net. At first this seemed pretty obvious since Visual Studio maps every project to a programming language and uses an appropriate compiler to compile the files in the project.

But giving it a deeper thought, I felt something didn't fit the picture. Every project, rather every file that we compile using the .NET Framework generates Common Intermediate Language which is used by the Common Language Runtime. It is because of this CIL that we have language interoperability in .NET. So theoretically speaking, code written in different languages should be able to exist in a single assembly.

Though I couldn't find a way to directly add a C# file into a VB.Net project, I found a way to create a DLL from compiled VB.Net and C# code through a concept of the .NET framework called Multi Module Assemblies.

In .NET, the minimum unit of deployment is an assembly; Dynamic Link Libraries (DLLs), Executables (.exe), etc. are all assemblies. An assembly can contain multiple files like resource files, the manifest, etc. It can contain files of another type called netmodules. A netmodule is a unit of compilation. It cannot be deployed directly but can be linked into an assembly. netmodules written in different .NET languages can be linked into a single assembly.

Unfortunately Visual Studio wasn't built for Multi Module Assemblies, hence there's no way to create a netmodule from a project in Visual Studio. However msbuild allows us to create a netmodule from the projects. There are typically three changes that have to be done to the .proj files (.fsproj, .vbproj, .csproj, etc.) for msbuild to generate a netmodule -

  1. Changing the OutputType to Module. Visual Studio doesn't recognize this output type, so even when you change this in the .proj files, Visual Studio won't be able to show it in the Project Properties
  2. Exclude the AssemblyInfo file from the project. netmodules aren't supposed to have an application manifest. If they do, the linker won't be able to resolve which application manifest should be used when we are building an assembly from multiple netmodules
  3. If one netmodule is dependent on another netmodule, a reference to the dependent module should be specified using the AddModules XML node in the .proj file. Similar to DLLs, netmodules cannot be circularly referenced

Once the .proj file has been modified, the project can be built using msbuild. If the project is a part of a solution, building the solution will create a netmodule for this project - msbuild solution_path

Once the netmodules are created using msbuild, a DLL can be created from them using the Assembly Linker of the .NET framework - al /t:library /out:"path_to_dll" path_to_netmodules

With this we have a DLL which contains all the netmodules bundled into one. To understand this better, let's consider an example - I have three projects, one in F#, VB.Net and in C# under a solution called MultiLanguage.

The .fsproj, .vbproj and .csproj have to be changed as mentioned above. From the netmodules obtained from msbuild, the DLL can be created using the assembly linker.

The sample solution and the build script can be downloaded from here. I automated the .proj changes using Microsoft's Build Engine API. You can give it a try here; it takes the .sln file as an input and modifies all the projects in the solution to generated netmodules.

Sunday, March 13, 2011

Windows Phone 7 - Hello World!

Ever since Nokia announced its partnership with Microsoft and made Windows Phone 7 its primary smartphone operating system, I anxiously wanted to give it a spin. So in this post, I am going to start by setting up a development environment for Windows Phone 7 followed by a simple Hello World example.

Windows Phone 7 is primarily a successor of the Windows Mobile Platform (the last one in the line being Windows Mobile 6.5). It's a major revamp in Microsoft's Mobile strategy in terms of its application development model.

Windows Phone 7 no longer supports unmanaged code (Win32 and C++ are gone). It is purely built on Managed Code covering Silverlight, XNA and the .NET Framework (Programming Languages include C# and VB.Net). Here's a nice article on Windows Phone 7 application development model - http://blogs.msdn.com/b/abhinaba/archive/2010/03/13/windows-phone-7-series-programming-model.aspx.

To get started with Windows Phone 7 development, download the Windows Phone Developer Tools RTW (Release To Web). It includes the following tools -

  1. Visual Studio 2010 Express for Windows Phone
  2. Windows Phone Emulator Resources
  3. Silverlight 4 Tools for Visual Studio
  4. XNA Game Studio 4.0
  5. Microsoft Expression Blend for Windows Phone

If you are already using a higher version of Visual Studio or Expression Studio, this toolkit will install extensions to the existing IDEs. The release is also available as an .iso image. Though the Windows Phone 7 toolkit comes equipped with Expression Blend, for most of the basic applications the design mode of Visual Studio should be sufficient.

To get a hands-on experience with Windows Phone 7, let's take a simple application which accepts a username and greets him/her in the next page. The best part of Windows Phone 7 development is that it is pretty much in the lines of other Visual Studio project types we are familiar with like the Windows Forms Applications, WPF Applications and ASP.Net Applications where in the UI can be created easily using the designer and the business logic is maintained in a code beside event driven model in another .cs or .vb file depending on the programming language.

As already mentioned, Windows Phone 7 is built on Silverlight and thereby every screen has a corresponding XAML (eXtensible Markup Language) page, each having its own code file. Movement between these XAML pages is made possible through an instance of a NavigationService class for every page.

There are three important methods provided by NavigationService - Navigate, GoForward and GoBack. Navigate takes a Uri instance specifying the URI location and loads the XAML page specified.

NavigationService.Navigate(new Uri("/NamePage.xaml", UriKind.Relative));

GoBack and GoForward loads the previous and next pages respectively.

NavigationService.GoBack();
NavigationService..GoForward();

Parameters can be passed across XAML pages by appending them to the URL and retrieving them using the QueryString property of the NavigationContext object. This concept of Windows Phone 7 was very surprising. Since Mobile Applications are very similar to Windows Applications, passing parameters through URLs like Web Applications looked a bit off-track.

NavigationService.Navigate(new Uri("/NamePage.xaml?name=" + name, UriKind.Relative));
string name = NavigationContext.QueryString["name"];

Download the example code here.