Reusing F# code libraries with Visual Studio
Posted by Brian on September 16, 2008
Continuing with the theme of a prior blog entry, I want to discuss two practical ways to reuse code across multiple applications.
Suppose I have some general-purpose utility code that I find to be reusable in a number of programs that I’m authoring. Rather than cut-and-pasting the code into various programs (which has all kinds of maintenance issues – if you are cut-and-pasting code within your projects, you are probably doing something wrong!), there are two common techniques in Visual Studio for reusing code.
Code library projects, and solutions with multiple projects
Perhaps the commonest way to reuse code is to put it in a library. An F# library project (File>New Project):
is a project that compiles down to a DLL (as you can see in the Output Window below):
So now I have a library that I can reference to access this functionality. I can reference this functionality from a different program by creating a solution with multiple projects. First, I create a new project for my app:
Next, I add an existing project to the solution:
and select the library project that I just created. Now my solution contains two projects:
Note that the project is "by reference" – Visual Studio hasn’t copied anything, the source code and the project file still have their same old location on disk, we are just referencing them from a different solution.
To make the library accessible to my application, I add a project reference by doing an ‘Add Reference’ on the app:
and selecting the ‘Projects’ tab to add a reference to the Library1 project:
I see the new reference appear in the solution explorer:
And now I can write code in my app that references code from the library, has working Intellisense, etc:
That’s a project-to-project reference, and it’s a common way to reuse code – I can reference Library1 from whatever other applications I write, in whatever language (e.g. I could just as well have referenced the F# library project from a new C# console application project) using this technique.
Including individual source code files by reference using ‘Add as Link’
Another way to reuse source code is to recompile the same code into different applications. I covered the mechanics of how to achieve this (‘Add as Link’) in a prior blog entry, check it out. I can create a new F# Application project in a new solution, and ‘Add as Link’ a source code file from the Library1 project, resulting in:
The little ‘arrow’ sub-glyph on the ‘Module1.fs’ icon shows that this is a linked file. As a linked file, no copying has been done – the source file still just lives in a single place on disk (under the Library1 folder), but that source file is going to get compiled into this project. As a result, again I can reference that code from other code in the current application:
This ‘code reuse’ strategy is probably used less often than project-to-project references. It has a number of disadvantages (functionality often cannot simply be ‘lifted out’ of a project on a per-file basis – often the code in the file references other files in the project, or has dependencies on references (‘add reference’) from the original project), but does have some potential advantages as well (the code is re-compiled directly into the referencing project, so with this strategy I just have a .EXE that contains everything, rather than a .EXE and a .DLL that the .EXE references).
So I’ve demonstrated a couple ways to reuse code in Visual Studio without resorting to cut-and-paste. Nothing too earth-shattering here, but I often find that people are blissfully ignorant of lots of useful Visual Studio features (I count myself in this group – until I started working on the F# Visual Studio integration, there were tons of VS features I knew nothing about, despite using VS for years), so I hope this helps demo the mechanics of some features and suggests how you will use them in practice.
Whereas recent blog entries have discussed some pragmatics regarding the physical aspects and tooling aspects of structuring your code (e.g. files and folders on disk, as well as VS projects and solutions), next time I hope to discuss how F# and functional programming affect the structure of actual source code that you write, compared to writing code with OO languages.