a post-build event command that will zip this project into a project template (this
example uses 7-zip, available at www.7-zip.org, but any command-line zip utility will
work). We will make a call to the 7-zip executable, which will zip the contents of the
ExtendedProjectTemplateExample folder (recursively, but excluding the bin and obj folders) into
ExtendedProjectTemplateExample.zip, and place it into the WizardClassLibrary folder. Note
that you may need to change the path as per the location of your zip utility. Put the following
command (on one line) as a post-build event:
"C:\Program Files\7-Zip\7z.exe" a -tzip ..\..\..\WizardClassLibrary\
ExtendedProjectTemplateExample.zip ..\..\*.* -r -x!bin -x!obj
You have now completed the individual projects required to create the project template
(ExtendedProjectTemplateExample), added a wizard to modify the project as it is created
(WizardClassLibrary), and built an installer to deploy your template to other machines. One last
step is to correct the solution dependency list to ensure that the ExtendedProjectTemplateExample
is rebuilt (and hence the template zip file re-created) prior to the installer being built. Because there
fiGure 15-14
308 .
chaPter 15 projecT And iTem TemplATeS
is no direct dependency between the Installer project
and the ExtendedProjectTemplateExample,
you need to open the solution properties and
indicate that there is a dependency, as illustrated in
Figure 15-15.
Your solution is now complete and can be used
to install the ExtendedProjectTemplateExample
and associated IWizard implementation. Once the
solution is installed, you can create a new project
from the ExtendedProjectTemplateExample you have
just created.
starter kits
A Starter Kit is essentially the same as a template but differs somewhat in terms of intent. Whereas
project templates create the basic shell of an application, Starter Kits create an entire sample
application with documentation on how to customize it. Starter Kits will appear in the New Project
window in the same way project templates do. Starter Kits can give you a big head start on a project
(if you can find one focused toward your project type), and you can create your own to share with
others in the same way that you created the project template previously.
online teMPlates
Visual Studio 2010 integrates nicely with the online Visual Studio Gallery (http://www
.visualstudiogallery.com) enabling you to search for templates created by other developers that
they uploaded to the gallery for other developers to download and use. You can browse the gallery
and install selected templates from within Visual Studio in two ways: via the Open Project window
and from the Extension Manager.
When you open the New Project window in Visual Studio you are looking at the templates installed
on your machine; however, you can browse and search the templates available online by selecting
Online Templates from the sidebar. Visual Studio will then allow you to browse the templates
online. When you select a template it will be downloaded and installed on your machine, and a new
project will be created using it.
Visual Studio 2010 introduces a new feature called the Extension Manager (as shown in Figure 15-16),
which you can get to from Tools . Extension Manager. The Extension Manager integrates the online
Visual Studio Gallery (http://www.visualstudiogallery.com) right into Visual Studio itself. It also
allows you to browse the Visual Studio Gallery and download and install templates, as well as controls
and tools.
fiGure 15-15
summary .
309
fiGure 15-16
suMMary
This chapter provided an overview of how to create both item and project templates with Visual
Studio 2010. Existing projects or items can be exported into templates that you can deploy to your
colleagues. Alternatively, you can build a template manually and add a user interface using the
IWizard interface. From what you learned in this chapter, you should be able to build a template
solution that can create a project template, build and integrate a wizard interface, and finally build
an installer for your template.
16
language-specific features
what’s in this chaPter?
.
Choosing the right language for the job
.
Working with the new C# and VB language features
.
Understanding and getting started with Visual F#
The .NET language ecosystem is alive and well. With literally hundreds of languages targeting
the .NET Framework (you can find a fairly complete list at www.dotnetpowered.com/
languages.aspx), .NET developers have a huge language arsenal at their disposal. Because
the .NET Framework was designed with language interoperability in mind, these languages
are also able to talk to each other, allowing for a creative cross-pollination of languages across
a cross-section of programming problems. You’re literally able to choose the right language
tool for the job.
This chapter explores some of the latest language paradigms within the ecosystem, each with
particular features and flavors that make solving those tough programming problems just a
little bit easier. After a tour of some of the programming language paradigms, you learn about
some of the new language features introduced in Visual Studio 2010, including one of the
newest additions to Microsoft’s supported language list: a functional programming language
called F#.
hittinG a nail with the riGht haMMer
We need to be flexible and diverse programmers. The programming landscape requires
elegance, efficiency, and longevity. Gone are the days of picking one language and platform
and executing like crazy to meet the requirements of our problem domain. Different nails
sometimes require different hammers.
312 .
chaPter 16 lAnguAge-SpeciFic FeATureS
Given that hundreds of languages are available on the .NET platform, what makes them different
from each other? Truth be told, most are small evolutions of each other, and are not particularly
useful in an enterprise environment. However, it is easy to class these languages into a range of
programming paradigms.
Programming languages can be classified in various ways, but I like to take a broad-strokes
approach, putting languages into four broad categories: imperative, declarative, dynamic, and
functional. This section takes a quick look at these categories and what languages fit within them.
imperative
Your classic all-rounder — imperative languages describe how, rather than what. Imperative
languages were designed from the get-go to raise the level of abstraction of machine code. It’s
said that when Grace Hopper invented the first-ever compiler, the A-0 system, her machine code
programming colleagues complained that she would put them out of a job.
It includes languages where language statements primarily manipulate program state. Object-oriented
languages are classic state manipulators through their focus on creating and changing objects. The
C and C++ languages fit nicely in the imperative bucket, as do our favorites VB and C#.
They’re great at describing real-world scenarios through the world of the type system and
objects. They are strict — meaning the compiler does a lot of safety checking for you. Safety
checking (or type soundness) means you can’t easily change a Cow type to a Sheep type — so,
for example, if you declare that you need a Cow type in the signature of your method, the
compiler will make sure that you don’t hand that method a Sheep instead. They usually have fantastic
reuse mechanisms too — code written with polymorphism in mind can easily be abstracted away
so that other code paths, from within the same module through to entirely different projects, can
leverage the code that was written. They also benefit from being the most popular. They’re clearly a
good choice if you need a team of people working on a problem.
declarative
Declarative languages describe what, rather than how (in contrast to imperative, which describes
the how through program statements that manipulate state). Your classic well-known declarative
language is HTML. It describes the layout of a page: what font, text, and decoration are required,
and where images should be shown. Parts of another classic, SQL, are declarative — it describes what
it wants from a relational database. A recent example of a declarative language is XAML (eXtensible
Application Markup Language), which leads a long list of XML-based declarative languages.
Declarative languages are great for describing and transforming data, and as such, we’ve invoked
them from our imperative languages to retrieve and manipulate data for years.
dynamic
The dynamic category includes all languages that exhibit “dynamic” features such as late-bound
binding and invocation, REPL (Read Eval Print Loops), duck typing (non-strict typing, that is, if an
object looks like a duck and walks like a duck it must be a duck), and more.
Dynamic languages typically delay as much compilation behavior as they possibly can to run time.
Whereas your typical C# method invocation “Console.WriteLine()” would be statically checked
Hitting a nail with the right Hammer .
313
and linked to at compile time, a dynamic language would delay all this to run time. Instead, it
looks up the “WriteLine()” method on the “Console” type while the program is actually running,
and if it finds it, invokes it at run time. If it does not find the method or the type, the language may
expose features for the programmer to hook up a “failure method,” so that the programmer can
catch these failures and programmatically “try something else.”
Other features include extending objects, classes, and interfaces at run time (meaning modifying
the type system on the fly); dynamic scoping (for example, a variable defined in the global scope
can be accessed by private or nested methods); and more.
Compilation methods like this have interesting side effects. If your types don’t need to be fully
defined up front (because the type system is so flexible), you can write code that will consume
strict interfaces (like COM, or other .NET assemblies, for example) and make that code highly
resilient to failure and versioning of that interface. In the C# world, if an interface you’re consuming
from an external assembly changes, you typically need a recompile (and a fix-up of your internal
code) to get it up and running again. From a dynamic language, you could hook the “method
missing” mechanism of the language, and when a particular interface has changed simply do some
“reflective” lookup on that interface and decide if you can invoke anything else. This means you can
write fantastic glue code that glues together interfaces that may not be versioned dependently.
Dynamic languages are great at rapid prototyping. Not having to define your types up front
(something you would do straightaway in C#) allows you concentrate on code to solve problems,
rather than on the type constraints of the implementation. The REPL (Read Eval Print Loop) allows
you to write prototypes line-by-line and immediately see the changes reflected in the program
instead of wasting time doing a compile-run-debug cycle.
If you’re interested in taking a look at dynamic languages on the .NET platform, you’re in
luck. Microsoft has released IronPython (www.codeplex.com/IronPython), which is a Python
implementation for the .NET Framework. The Python language is a classic example of a dynamic
language, and is wildly popular in the scientific computing, systems administration, and general
programming space. If Python doesn’t tickle your fancy, you can also download and try out
IronRuby (www.ironruby.net/), which is an implementation of the Ruby language for the .NET
Framework. Ruby is a dynamic language that’s popular in the web space, and though it’s still
relatively young, it has a huge popular following.
functional
The functional category focuses on languages that treat computation like mathematical
functions. They try really hard to avoid state manipulation, instead concentrating on the results
of functions as the building blocks for solving problems. If you’ve done any calculus before, the
theory behind functional programming might look familiar.
Because functional programming typically doesn’t manipulate state, the surface area of side effects
generated in a program is much smaller. This means it is fantastic for implementing parallel and
concurrent algorithms. The holy grail of highly concurrent systems is the avoidance of overlapping
“unintended” state manipulation. Dead-locks, race conditions, and broken invariants are classic
manifestations of not synchronizing your state manipulation code. Concurrent programming and
synchronization through threads, shared memory, and locks is incredibly hard, so why not avoid
it altogether? Because functional programming encourages the programmer to write stateless
314 .
chaPter 16 lAnguAge-SpeciFic FeATureS
algorithms, the compiler can then reason about automatic parallelism of the code. This means you
can exploit the power of multi-core processors without the heavy lifting of managing threads, locks,
and shared memory.
Functional programs are terse. There’s usually less code required to arrive at a solution than with its
imperative cousin. Less code typically means fewer bugs and less surface area to test.
what’s it all Mean?
These categories are broad by design: languages may include features that are common to one or
more of these categories. The categories should be used as a way to relate the language features that
exist in them to the particular problems that they are good at solving.
Languages like C# and VB.NET are now leveraging features from their dynamic and functional
counterparts. LINQ (Language Integrated Query) is a great example of a borrowed paradigm.
Consider the following C# 3.0 LINQ query:
var query =
from c in customers
where c.CompanyName == "Microsoft"
select new { c.ID, c.CompanyName };
This has a few borrowed features. The var keyword says “infer the type of the query specified,”