Escolar Documentos
Profissional Documentos
Cultura Documentos
If you not an MSDN Program subscriber and would like to apply for
your own digital version, 12 issues for $25.00 please apply here:
https://cmp-sub.halldata.com/mfdigital
Basic Instincts
Stay Error Free With Error
Corrections Dustin Campbell page 21
Test Run
Request-Response Testing
With F# James McCaffrey page 72
Wicked Code
USABILITY IN PRACTICE: Usability Testing Taking Silverlight Deep Zoom
Dr. Charles B. Kreitzberg & Ambrose Little
To The Next Level
INSIDE WINDOWS 7: Introducing The Taskbar APIs Jeff Prosise page 90
Yochay Kiriaty & Sasha Goldshtein
Foundations
TESTABLE MVC: Unit Testing ASP.NET MVC Securing The .NET Service Bus
Justin Etheredge Juval Lowy page 99
Copyright 1996-2009 Infragistics, Inc. All rights reserved. Infragistics, the Infragistics logo and NetAdvantage are registered trademarks of Infragistics, Inc. All other trademarks or registered trademarks are the respective property of their owners.
Instantly Search
Terabytes of Text
N dozens of indexed, JULY 2009 VOLUME 24 NUMBER 7
unindexed,
LUCINDA ROWLEY Director
fielded data and
EDITORIAL: mmeditor@microsoft.com
full-text search HOWARD DIERKING Editor-in-Chief
options (including
WEB SITE
Unicode support MICHAEL RICHTER Webmaster
for hundreds
CONTRIBUTING EDITORS Don Box, Keith Brown, Dino Esposito, Juval Lowy,
of international Dr. James McCaffrey, Fritz Onion, John Papa, Ted Pattison, Charles Petzold,
languages) Jeff Prosise, Jeffrey Richter, John Robbins, Aaron Skonnard, Stephen Toub
MSDN Magazine (ISSN # 1528-4859) is published monthly by TechWeb, a division of United Business
Media LLC., 600 Community Drive, Manhasset, NY 11030 516-562-5000. Periodicals Postage Paid
N file parsers / at Manhasset, NY and at additional mailing offices. Back issue rates: U.S. $10. All others: $12. Basic
one-year subscription rates: U.S. $45. Canada and Mexico $55. Registered for GST as TechWeb, a
converters for division of United Business Media LLC., GST No. R13288078, Customer No. 2116057 Canada Post:
Publications Mail Agreement #40612608. Canada Returns to be sent to Bleuchip International, P.O.
hit-highlighted Box 25542, London, ON N6C 6B2. All other foreign orders $70, must be prepaid in U.S. dollars drawn
on a U.S. bank. Circulation Department, MSDN Magazine, P.O. Box 1081, Skokie, IL 60076-8081, fax
display of all 847-763-9583. Subscribers may call from 8:00 AM to 4:00 PM CST M-F. In the U.S. and Canada 888-
847-6188; all others 847-763-9606. U.K. subscribers may call Jill Sutcliffe at Parkway Gordon 01-49-
1875-386. Manuscript submissions and all other correspondence should be sent to MSDN Magazine,
popular file 6th Floor, 1290 Avenue of the Americas, New York, NY 10104. Copyright © 2009 Microsoft Corporation.
All rights reserved; reproduction in part or in whole without permission is prohibited.
types
h Spider
Desktop wit
POSTMASTER: Send address changes to MSDN Magazine, P.O. Box 1081, Skokie, IL 60076-8081
static and Network wit customer service inquiries via the Web at http://msdn.microsoft.com/msdnmag/service.
CD/DVDs
dynamic web Publish for PUBLISHER:
data; highlights
hits while Web with S
pider
New Jill Thiry jthiry@techweb.com
N “For combing through large amounts of data,” TechWeb, a division of United Business Media LLC.–The Global Leader in Business Technology Media
Tony L. Uphoff CEO
dtSearch “leads the market” Bob Evans SVP and Content Director
Eric Faurot SVP, Live Events Group
– Network Computing Joseph Braue SVP, Light Reading Communications Group
John Siefert VP and Publisher, InformationWeek and TechWeb Network
N dtSearch “covers all data sources ... powerful Scott Vaughan VP, Marketing Services
John Ecke VP, Financial Technology Group
Web-based engines” – eWEEK Jill Thiry Publisher, MSDN Magazine and TechNet Magazine
John Dennehy General Manager
Fritz Nelson Executive Producer, TechWeb TV
N dtSearch “searches at blazing speeds” Scott Popowitz Senior Group Director, Audience Development
– Computer Reseller News Test Center Beth Rivera Senior Human Resources Manager
1-800-IT-FINDS • www.dtsearch.com
4 msdn magazine Printed in the USA
Your best source for
software development tools!
®
LEADTOOLS Document dtSearch Engine for Win & .NET VMware vSphere Essentials
Imaging v 16.5: Add dtSearch‘s “blazing speeds” New VMware Solutions for Small Businesses
by LEAD Technologies (CRN Test Center) searching and New VMware vSphere Essentials Editions combine the
file format support 64-bit high availability, performance and reliability of
LEADTOOLS Document Imaging has every Version!
component you need to develop powerful • dozens of full-text and fielded our enterprise class solutions with packaging ideal
image-enabled business applications including data search options for smaller IT environments and a price starting
specialized bi-tonal image display and • file parsers/converters for hit-highlighted at less than $1,000 for a complete solution.
processing, document clean up, high-speed display of all popular file types • VMware vSphere Essentials provides an New
scanning, advanced compression (CCITT • Spider supports dynamic and static web data; all-in-one solution for small offices to virtualize Release!
New G3/G4, JBIG2, MRC, ABC) and more. highlights hits with links, images, etc. intact three physical servers for consolidating and
Re lea se! managing applications to reduce hardware and
• Multi-threaded OCR/ICR/OMR/ • API supports .NET, C++, Java, SQL and more;
MICR/Barcodes (1D/2D) 3 Server Pack operating costs with a low up front investment. VMware
new .NET Spider API
• Forms recognition/processing Paradise # vSphere
• VMware vSphere Essentials Plus adds
Paradise # • PDF and PDF/A “Bottom line: dtSearch manages a terabyte of D29 02101A08 Essentials
high application availability and data protection
L05 03201A01 • Annotation (Image Mark-up)
• C/C++, .NET, WPF - Win32/64, WCF, WF
text in a single index and returns results in
less than a second.” —InfoWorld
$
2,375. 99 for a complete server consolidation, manage-
ment and business continuity solution
CALLI
$
2,007. 99
programmers.com/lead programmers.com/dtsearch for the small office IT environment. programmers.com/vmware
800-445-7899 programmersparadise.com
Prices subject to change. Not responsible for typographical errors.
EDITOR’S NOTE
Viva la Evolution!
In this issue of MSDN Magazine, CTP of Indigo. I’m not suggesting that such an article should
we will take a more focused look at the state be outright pulled down—there may be value in the conceptual
of Web development. This is actually a pretty explanations. However, there should absolutely be more attention
relevant topic for me at the moment, as I’ve been given to lifetime management policy.
in and out of meetings over the past month in So why am I bringing up issues of content management? For
which we’ve been trying to define and come to one, it’s a domain that I’m pretty familiar with. More important,
consensus around what MSDN (not just the however, I think it highlights where the problems are now shifting
magazine) should be and how it should evolve. on the Web. For example, we’ve solved the problem of publishing
As such, I want to give you my perspective as a content publisher and we have decent a solution for finding content. The next major
on how the problem domain of the Web has evolved and how Web evolution is in composing experiences that bring together lots
applications are going to need to evolve to solve them. of disparate elements into a single context. This means thinking
It’s interesting to see how far the pendulum has swung in terms about how to break apart various application and content silos
of the fundamental problems related to content and the Web. Not such that a combination of content and application services can
too long ago, the major challenge was making content available. be put together into any context, as decided by the user—in short,
Evolution happened quickly, however—and handwritten HTML this means thinking of everything as a mashup. For me, it means
was replaced by WYSIWYG editors, and then the whole edit- that if my intent—my context—is to read an article about WCF,
ing environment was supplanted entirely by blogs and wikis. I shouldn’t have to stop what I’m doing so that I can navigate to a
The problem of publishing effectively disappeared. Anyone with different Web application if I have a question to post, only to later
an idea and an Internet connection could publish content for all rely on the back button to return to the article. I should be able to
to consume. construct a single context consisting of a content item and a forums
Before the novelty of this newly democratized world of content application service.
could sink in, the core problem shifted from making content Getting to this next step is going to require some work, in both
available to finding the right content. Enter the rise of search refactoring to break application silos into services and learning to
engines. Now, I’ve got no problem with search—I use it as a regu- think of Web applications as compositions. I’m therefore excited
lar part of doing business. For example, have you ever submitted to see articles like Shawn Wildermuth’s article on composite
an article idea and received a response similar to, “There’s already Silverlight applications (Page ) and Aaron Skonnard’s article on
a sufficient amount of coverage on this topic?” You can blame REST and the ASP.NET MVC framework (Page ). Finally, for
your search engine for that. For all of its eff ectiveness in finding more on refactoring Web applications, check James Kovacs’ series
content, however, I think that search has effectively enabled folks on brownfield development, aptly titled “Extreme
in the content business to gloss over some more fundamental ASP.NET Makeover,” at msdn.microsoft.com/magazine.
problems in our approach to publishing and managing content Viva la evolution!
on the Web—particularly with respect to information architecture.
As I look over all of the content that can be found today on MSDN,
I am overwhelmed at both the sheer volume of content and the lack THANKS TO THE FOLLOWING MICROSOFT TECHNICAL EXPERTS FOR THEIR HELP WITH
THIS ISSUE: Adrian Bateman, Sam Bent, Laurent Bugnion, Matt Ellis, Mike Fourie,
of cohesion among the various content elements. I’m also both- Steve Fox, Don Funk, Alex Gorev, Aaron Hallberg, Luke Hoban, Robert Horvick,
ered by the fact that I can search for MSDN Magazine articles on John Hrvatin, Bret Humphrey, Katy King, Brian Kretzler, Bertrand LeRoy, Dan
WCF and be presented with an article that was based on an early Moseley, Stephen Powell, and Delian Tchoparinov.
Visit us at msdn.microsoft.com/magazine. Questions, comments, or suggestions for MSDN Magazine? Send them to the editor: mmeditor@microsoft.com.
8 msdn magazine
FOCUS ON YOUR CODE.
AND LET CRYSTAL REPORTS
HANDLE THE REPORTING.
NEW ROYALTY-FREE
RUNTIME NOW AVAILABLE.
WWW.SAP.COM/CRYSTAL
REPORTS/DEV
OR CONTACT US AT 1-888-
333-6007.
Copyright © 2008 Business Objects SA. All rights reserved. Business Objects and the Business Objects logo and Crystal Reports are
trademarks or registered trademarks of Business Objects SA or its affiliated companies in the United States and/or other countries.
Business Objects is an SAP company. SAP is a registered trademark of SAP AG in Germany and in other countries.
EVOLVE YOUR CODE.
Parallelism breakthrough.
Analyze, compile, debug, check, and tune your code for multicore
with Intel® Parallel Studio. Designed for today’s serial apps and
tomorrow’s parallel innovators.
Get free eval software: www.intel.com/software/products/eval
© 2009-2010, Intel Corporation. All rights reserved. Intel and the Intel logo are trademarks of Intel Corporation in the U.S. and other countries. *Other names and brands may be claimed as the property of others.
SCOTT MITCHELL TOOLBOX
Building Tuple
The upcoming . release of Microsoft .NET Framework introduces With the tuple type, we’ve been able to remove the cast opera-
a new type called System.Tuple. System.Tuple is a fixed-size col- tors from our code, giving us better error checking at compile time.
lection of heterogeneously typed data. Like an array, a tuple has a When constructing and using elements from the tuple, the compiler
fixed size that can’t be changed once it has been created. Unlike an will ensure our types are correct.
array, each element in a tuple may be a different type, and a tuple As this example shows, it’s obvious that a tuple is a useful type
is able to guarantee strong typing for each element. Consider try- to have in the Microsoft .NET Framework. At first, it might seem
ing to use an array to store a string and integer value together, as like a very easy enhancement. However, we’ll discuss some of the
in the following: interesting design challenges that the team faced while designing
static void Main(string[] args) { System.Tuple. We’ll also explore more about what we added to the
object[] t = new object[2];
t[0] = "Hello"; Microsoft .NET Framework and why these additions were made.
t[1] = 4;
easier.
and four-element tuples as value types, with the rest being reference
types. However, during a design meeting that included represen-
tatives from other languages it was decided that this “split” design
that took a tuple as an argument, you would be unable to use the would be confusing, due to the slightly different semantics between
normal C# syntax for a tuple or pass an existing C# tuple. Instead, the two types. Consistency in behavior and design was determined
you would be forced to convert your C# tuple to an F# tuple, and to be of higher priority than potential performance increases. Based
then call the method. It’s our hope that by providing a common on this input, we changed the design so that all tuples are reference
tuple type, we’ll make interoperability between managed languages types, although we asked the F# team to do some performance in-
with tuples that much easier. vestigation to see if it experienced a speedup when using a value
type for some sizes of tuples. It had a good way to test this, since its
Using Tuple from C# compiler, written in F#, was a good example of a large program that
While some languages like F# have special syntax for tuples, you used tuples in a variety of scenarios. In the end, the F# team found
can use the new common tuple type from any language. Revisiting that it did not get a performance improvement when some tuples
the first example, we can see that while useful, tuples can be overly were value types instead of reference types. This made us feel better
verbose in languages without syntax for a tuple: about our decision to use reference types for tuple.
class Program {
static void Main(string[] args) {
Tuple<string, int> t = new Tuple<string, int>("Hello", 4);
Tuples of Arbitrary Length
PrintStringAndInt(t.Item1, t.Item2); Theoretically, a tuple can contain as many elements as needed,
} but we were able to create only a finite number of classes to
static void PrintStringAndInt(string s, int i) { represent tuples. This raised two major questions: how many generic
Console.WriteLine("{0} {1}", s, i); parameters should the largest tuple have, and how should the larger
}
} tuples be encoded? Deciding on how many generic parameters to
Using the var keyword from C# ., we can remove the type have in the largest tuple ended up being somewhat arbitrary. Since
signature on the tuple variable, which allows for somewhat more Microsoft .NET Framework introduces new versions of the Action
readable code. and Func delegates that take up to eight generic parameters, we
var t = new Tuple<string, int>("Hello", 4); chose to have System.Tuple work the same way. One nice feature
We’ve also added some factory methods to a static Tuple class of this design is that there’s a correspondence between these two
which makes it easier to build tuples in a language that supports types. We could add an Apply method to each tuple that takes a
type inference, like C#. correspondingly sized Action or Func of the same type and pass
var t = Tuple.Create("Hello", 4); each element from the tuple as an argument to the delegate. While
Don’t be fooled by the apparent lack of types here. The type of t we ultimately didn’t add this in order to keep the surface area of
is still Tuple<string, int> and the compiler won’t allow you to treat the type clean, it’s something that could be added in a later release
the elements as different types. or with extension methods. There is certainly a nice symmetry in
Now that we’ve seen how the tuple type works, we can take a look the number of generic parameters that belong to Tuple, Action,
at the design behind the type itself. and Func. An aside: After System.Tuple was finished being de-
signed, the owners of Action and Func created more instances of
Reference or Value Type? each type; they went up to generic parameters. Ultimately, we
At first glance, there isn’t much to the tuple type, and it seems like decided not to follow suit: the decision on sizing was somewhat
something that could be designed and implemented over a long arbitrary to begin with, and we didn’t feel the time we would spend
weekend. However, looks are often deceiving, and there were some adding eight more tuple types would be worth it.
16 msdn magazine CLR Inside Out
Once we answered our first question, we still had to figure out a In F#, equality over tuples and arrays is structural. This means
way to represent tuples with more than eight elements. We decid- that two arrays or tuples are equal if all their elements are the
ed that the last element of an eight-element tuple would be called same. This differs from C#. By default, the contents of arrays and
“Rest” and we would require it to be a tuple. The elements of this tuples don’t matter for equality. It is the location in memory that
tuple would be the eighth, ninth, and so on, elements of the overall is important.
tuple. Therefore, users who wanted an eight-element tuple would Since this idea of structural equality and comparison is already
create two instances of the tuple classes. The first would be the part of the F# specification, the F# team had already come up
eight-element tuple, which would contain the first seven items of with a partial solution to the problem. However, it applied only
the tuple, and the second would be a one-element tuple that held to the types that the team created. Since it also needed structural
the last tuple. In C#, it might look like this:
Properties
For languages that provide syntax for interacting with tuples, solve structural equality and
comparison problems.
the names of the properties used to access each element aren’t
very interesting, since they are shielded from the developer. This
is a very important question for languages like C#, where you have
to interact with the type directly. We started with the idea of using equality over arrays, the compiler generated special code to test if
Item, Item, and so on as the property names for the elements, but it was doing equality comparison on an array. If so, it would do a
we received some interesting feedback from our framework design structural comparison instead of just calling the Equals method on
reviewers. They said that while these property names make sense Array. The design team iterated on a few different designs on how
when someone thinks about them at first glance, it gives the feeling to solve these sorts of structural equality and comparison prob-
that the type was auto-generated, instead of designed. They sug- lems. It settled on creating a few interfaces that structural types
gested that we name the properties First, Second, and so on, which needed to implement.
felt more accessible. Ultimately, we rejected this feedback for a few
reasons: first, we liked the experience of being able to change the IStructualEquatable and IStructuralComparable
element you access by changing one character of the property name; IStructualEquatable and IStructuralComparable interfaces pro-
second, we felt that the English names were difficult to use (typing vide a way for a type to opt in to structural equality or comparison.
Fourth or Sixth is more work than Item or Item) and would lead They also provide a way for a comparer to be used for each element
to a very weird IntelliSense experience, since property names would in the object. Using these interfaces, as well as a specially defined
be alphabetized instead of showing up in numerical order. comparer, we can have deep equality over tuples and arrays when
it is required, but we don’t have to force the semantics on all users
Interfaces Implemented of the type. The design is deceptively simple:
System.Tuple implements very few interfaces and no generic public interface IStructuralComparable {
interfaces. The F# team was very concerned about tuple being a Int32 CompareTo(Object other, IComparer comparer);
}
very lightweight type, because it uses so many different generic
instantiations of the type across its product. If Tuple were to public interface IStructuralEquatable {
Boolean Equals(Object other, IEqualityComparer comparer);
implement a large number of generic interfaces, they felt it would Int32 GetHashCode(IEqualityComparer comparer);
have an impact on their working set and NGen image size. In light of }
this argument, we were unable to find compelling reasons for Tuple These interfaces work by separating the act of iterating over ele-
to implement interfaces like IEquatable<T> and IComparable<T>, ments in the structural type, for which the implementer of the in-
even though it overrides Equals and implements IComparable. terface is responsible, from the actual comparison, for which the
caller is responsible. Comparers can decide if they want to pro-
Structural Equality, Comparison, and Equivalence vide a deep structural equality (by recursively calling the IStruc-
The most interesting challenge we faced when designing Tuple tualEquatable or IStructualComparable methods, if the elements
was to figure out how to support the following: implement them), a shallow one (by not doing so), or something
• structural equality completely different. Both Tuple and Array now implement both
• structural comparison of these interfaces explicitly.
•partial equivalence relations
We did as much design work around these concepts as we did Partial Equivalence Relations
for Tuple itself. Structural equality and comparison relate to what Tuple also needed to support the semantics of partial equivalence
Equals means for a type like Tuple that simply holds other data. relations. An example of a partial equivalence relation in the Microsoft
msdnmagazine.com July 2009 17
.NET Framework is the relationship between NaN and other floating- Worth the Effort
point numbers. For example: NaN<NaN is false, but the same holds Though it took a great deal more design iteration than anyone
for NaN>NaN and NaN == NaN and NaN != NaN. This is due to expected, we were able to create a tuple type that we feel is flexible
NaN being fundamentally incomparable, since it does not represent enough for use in a variety of languages, regardless of syntactic
any number. While we are able to encode this sort of relationship support for tuples. At the same time, we’ve created interfaces that
with operators, the same does not hold for the CompareTo method help describe the important concepts of structural equality and
on IComparable. This is because there is no value that CompareTo comparison, which have value in the Microsoft .NET Framework
can return that signals the two values are incomparable. outside of tuple itself.
F# requires that the structural equality on tuples also works with Over the past few months, the F# team has updated its compiler
partial equivalence relationships. Therefore in F#, [NaN, NaN] == to use System.Tuple as the underlying type for all F# tuples. This
[NaN, NaN] is false, but so is [NaN, NaN] != [NaN, NaN]. ensures that we can start building toward a common tuple type
Our first tentative solution was to have overloaded operators on across the Microsoft .NET ecosystem. In addition to this exciting
Tuple. This worked by using operators on the underlying types, if development, tuple was demoed at this year’s Professional Devel-
they existed, and by falling back to Equals or CompareTo, if they opers Conference as a new feature for Microsoft .NET Framework
did not. A second option was to create a new interface like ICom- and received much applause from the crowd. Watching the video
parable but with a different return type so that it could signal cases and seeing how excited developers are to start using tuples has made
where things were not comparable. Ultimately, we decided that we all the time spent on this deceptively simple feature all the more
would hold off on building something like this until we saw more worthwhile.
examples of partial equivalence being needed across the Microsoft
.NET Framework. Instead, we recommended that F# implement
this sort of logic in the IComparer and IEqualityComparer methods
MATT ELLIS is a Software Design Engineer on the Base Class Libraries team
that they passed into the IStructrual variants of CompareTo and responsible for diagnostics, isolated storage, and other little features like Tuple.
Equals methods by detecting these cases and having some sort of When he’s not thinking about frameworks or programming language design, he
out-of-band signaling mechanism when it encountered NaNs. spends his time with his wife Victoria and their two dogs, Nibbler and Snoopy.
9780321562319
9780321508799 9780321564160 9780672330223
AVA I L A B L E N O W I N P R I N T, E B O O K , A N D S A FA R I B O O K S O N L I N E
One of the most useful features of the Microsoft Visual Basic editing the editor, a small red bar is added to the squiggle underline that
experience in Microsoft Visual Studio is background compilation. indicates that a smart tag is available at that location, as shown in
You’re probably already familiar with this feature, as it is similar Figure 1.
in spirit to the spelling and grammar checker found in Microsoft If you hover the mouse over the smart tag indicator, the collapsed
Word. As you type code, the Visual Basic compiler runs in the back- smart tag will appear along with a tooltip description. This is
ground. When you type an error, it is underlined with a squiggle pictured in Figure 2.
in the editor and added to the Error List window. In Figure 3, clicking on the smart tag expands the error
Prior to Visual Studio , the only guidance for fixing errors correction UI with the options that are available for this particular
came primarily from the error messages themselves. When possible, code error.
the Visual Basic Compiler generates error messages that are intended The error correction UI makes it easy to fix errors quickly and
to explain not only what the error is, but also how to fix it. accurately. The preview windows clearly show what changes will
Let’s look at an example. Suppose that you
have the following Visual Basic code:
Module Module1
Sub Main()
Dim i As Integer = "1"c
End Sub
End Module
The code above produces a compiler error
because it isn’t clear which conversion from
Char to Integer is expected. Should the com- Figure 2 Collapsed Smart Tag
piler insert a conversion to produce the ASCII
value of “”c, or should it insert a conversion that produces the
numerical value of “”c? The compiler has no option but to generate
this error message:
“‘Char’ values cannot be converted to ‘Integer’. Use ‘Microsoft.
VisualBasic.AscW’ to interpret a character as a Unicode value or
‘Microsoft.VisualBasic.Val’ to interpret it as a digit.”
While the preceding error message goes to great lengths to
explain how the problem can be fixed, it requires more coding on
your part to actually fix it.
Console.Write(f(42.0)
Figure 5 Error Correction for Inserting Parenthesis Figure 6 Error Corrections for a Read-only Property with a Setter
22 msdn magazine Basic Instincts
the following code, which contains a spelling mistake:
Class Class1
End Class
Class Class2
End Class
Module Module1
Sub Main()
Dim c As New Clss
End Sub
End Module
The code above mistakenly attempts to instantiate a type named
Clss, but none exists. In this situation, two error corrections are
available, one to change Clss to Class and another to change Clss
Figure 7 Error Correction to Convert an Integer to a String to Class, as shown in Figure 8.
Currently, the spell checker is fairly simple and works only for
. Press Enter to apply. type names. However, this is an area that the Visual Basic team
As you can see, not only do error corrections help you write the would like to improve in a future release.
correct code, they can be a big time saver!
Importing Namespaces
Using the Right Type Conversions After shipping Visual Studio , the Visual Basic team received
By default, Visual Basic leaves strict typing off. This allows you to several requests for additional error corrections. Chief among these
take advantage of the Visual Basic compiler’s support for implicit was an error correction for automatically adding Imports statements.
data type conversions and late binding: It can be pretty irritating to start using a type and realize that you’ve
Module Module1 forgotten to import its namespace. For example, suppose you were
Sub Main() using the System.IO.File class to open and read a file from disk:
Dim s As String = 42
End Sub Module Module1
End Module Sub Main()
Given the code above, the compiler will properly insert a type
conversion from Integer to String.
However, if you use strict typing, Visual Basic error correc-
tions will be available to help you insert the same type conversion
that the compiler would have, if strict typing were off. Figure 7
shows the error correction for the code above when strict typing
is enabled.
Module Module1
Sub Main()
Dim fileName = Path.Combine("C:\Temp", "Sizes.txt")
Using f = File.OpenRead(fileName)
Dim r As New Rectangle
End Using
End Sub
End Module
Like before, the namespace hasn’t been imported yet, so you
use the error correction UI pictured in Figure 10 to import it for
you. However, this time there’s a problem. The System.Windows.
Figure 12 Generate Class
Shapes namespace also includes a type named Path, so importing
the namespace would change the meaning of your code.
Conclusion
Error corrections are an essential part of the Visual Basic coding
experience. Not only do they help you immediately spot and fix
errors, but you can use them to write code more efficiently. This
article only scratches the surface of the hundreds of suggestions
offered by Visual Basic. And with Visual Studio , there is an
error correction for most coding errors.
Don’t forget to use Ctrl+.!
DUSTIN CAMPBELL is the Microsoft Visual Basic IDE Program Manager on the
Microsoft Visual Studio Languages Team. He works primarily on the editor and
debugger product features. As a programming language nut, he also contributes
to other languages in Visual Studio, such as C# and F#. Before joining Microsoft,
Dustin helped to develop the award-winning CodeRush and Refactor! tools at
Developer Express Inc. Dustin’s favorite color is blue.
msdnmagazine.com July 2009 25
CUTTING EDGE DINO ESPOSITO
SELLER
BESTVERSION
NEW TX Text Control .NET and .NET Server from $494.10
Word processing components for Visual Studio .NET.
• Add professional word processing to your applications
• Royalty-free Windows Forms text box
• True WYSIWYG, nested tables, text frames, headers and footers, images, bullets,
structured numbered lists, zoom, dialog boxes, section breaks, page columns
• Load, save and edit DOCX, DOC, PDF, PDF/A, RTF, HTML, TXT and XML
US Headquarters
ComponentSource
European Headquarters
ComponentSource
Asia / Pacific Headquarters
ComponentSource Sales Hotline - US & Canada:
(888) 850-9911
650 Claremore Prof Way 30 Greyfriars Road 3F Kojimachi Square Bldg
Suite 100 Reading 3-3 Kojimachi Chiyoda-ku
Woodstock Berkshire Tokyo
GA 30188-5188 RG1 1PE Japan
USA United Kingdom 102-0083 www.componentsource.com
based on a monolithic runtime environment that can be extended, by invoking a method on a controller class. No postbacks are ever
to some extent, but it is not a pluggable and flexible system. It’s required to service a user request. No viewstate is ever required to
nearly impossible to test an ASP.NET application without spinning persist the state of the page. No arraysof black-box server controls
up the whole runtime. exist to produce the HTML for the browser.
To achieve statefulness, the last known state of each server page With ASP.NET MVC, you rediscover the good old taste of the
is stored within the client page as a hidden field—the viewstate. Web—stateless behavior, full control over every single bit of HTML,
Though viewstate has too often been held up as an example of what’s total script and CSS freedom.
wrong with Web Forms, it is not the monster it’s made out to be. In The HTML served to the browser is generated by a separate, and
fact, using a viewstate-like structure in classic ASP was a cutting- replaceable, engine. There’s no dependency on ASPX physical server
edge solution. From an ASP perspective, simulation of statefulness files. ASPX files may still be part of your project, but they now serve
(that is, postback, viewstate, controls) was a great achievement, and as plain HTML templates, along with their code-behind classes.
the same was also said at first about how Web Forms isolated itself The default view engine is based on the Web Forms rendering
from HTML and JavaScript details. engine, but you can use other pluggable engines such as nVelocity
For modern Web pages, abstraction from HTML is a serious issue or XSLT. (For more details, have a look at the MVCContrib Web
as it hinders accessibility, browser compatibility, and integration with site at mvccontrib.codeplex.com.)
popular JavaScript frameworks like jQuery, Dojo, and PrototypeJS. The The runtime environment is largely the same as in ASP.NET Web
postback model that defaults each page to post to itself, makes it harder Forms, but the request cycle is simpler and more direct. An essen-
for search engines to rank ASP.NET pages high. Search engines and tial part of the Web Forms model, the page lifecycle, is no longer
spiders work better with links with parameters, better if rationalized necessary in ASP.NET MVC. It should be noted, though, that the
to human-readable strings. The postback model goes in the opposite default view engine in ASP.NET MVC is still based on the Web
direction. Also, an excessively large viewstate is problematic because Forms rendering engine. This is the trick that allows you to use
the keyword the rank is based on may be located past the viewstate, master pages and some server controls in ASP.NET MVC views.
and therefore far from the top of the document. Some engines recog- As long as the view engine is based on Web Forms, the view is an
nize a lower rank in this case. ASPX file with a regular code-behind class where you can handle
classic events such as Init, Load, PreRender, plus control-specific
Benefits of ASP.NET MVC events such as RowDataBound for a GridView control. If you switch
Some of the recognized issues with the Web Forms model can be fixed off the default view engine, you no longer need Page_Loador other
within ASP.NET .. You can disable or control the size of the viewstate. events of the standard page lifecycle. Figure 1 compares the run-
(Even though very few developers seem to have noticed, the size of the time stack for Web Forms and ASP.NET MVC.
viewstate decreased significantly in the transition from ASP.NET . to It should be noted that the “Page lifecycle” boxes in Figure 1 have
ASP.NET . when Microsoft introduced a much more efficient seri- been collapsed for readability and include several additional events
alization algorithm. In ASP.NET ., you should also expect improve- each. Anyway, the run-time stack of ASP.NET MVC is simpler and
ments in the way in which viewstate can be disabled and controlled.) the difference is due to the lack of a page lifecycle. However, this
You can use an ad hoc HTTP module to do URL rewriting or, better makes it problematic to maintain the state of visual elements across
yet, you can use the newest Web routing API from ASP.NET . SP. In page requests. State can be stored into Session or Cache, but this
ASP.NET ., you can minutely control the ID of elements, including decision is left to the developer.
scoped elements. Likewise, in ASP.NET . the integration of external
JavaScript frameworks will be simpler and more effective. Finally, the
history management API in ASP.NET . SP made AJAX and postback
work together while producing a search-engine-friendly page.
In many aspects, the Web Forms model in ASP.NET . is a
better environment that tackles some of the aforementioned flaws.
So what’s the point of ASP.NET MVC?
You’ll find a good introduction to ASP.NET MVC in the March
issue MSDN Magazine (msdn.microsoft.com/en-us/magazine/
cc337884.aspx), where Chris Tavares explains the basics of ASP.NET
development without Web Forms. In summary, ASP.NET MVC is
a completely new framework for building ASP.NET applications,
designed from the ground up with SoC and testability in mind.
When you write an ASP.NET MVC application, you think in terms
of controllers and views. You make your decisions about how to
pass data to the view and how to expose your middle tier to the
controllers. The controller chooses which view to display based
on the requested URL and pertinent data. Each request is resolved Figure 1 The Run-Time Stack at a Glance
30 msdn magazine Cutting Edge
Web was still to come. Adapting MVC to the Web moved it toward
the model in Figure 2, which is also known as Model. In general,
when you talk or read about MVC be aware that there are quite a
few slightly different flavors of it within the literature.
Drawbacks of ASP.NET MVC
So ASP.NET MVC brings to the table a clean design with a neat
separation of concerns, a leaner run-time stack, full control over
HTML, an unparalleled level of extensibility, and a working environ-
ment that enables, not penalizes, test-driven development (TDD).
Is ASP.NET MVC, therefore, a paradise for Web developers?
Just like with Web Forms, what some perceive as a clear strength
of ASP.NET MVC, others may see as a weakness. For example, full
control over HTML, JavaScript, and CSS, ASP.NET MVC means
that you enter the Web elements manually. Much of this pain can be
Figure 2 The Sequence Diagram of an ASP.NET MVC Request mitigated, however, with some of the more recent JavaScript libraries
and even different view engine. In general, though, there’s no sort of
Figure 2 illustrates the sequence of an ASP.NET MVC component model to help you with the generation of HTML, as there
request. is in the Web Forms approach. Currently, HTML helpers and user
The MVC acronym stands for Model-View-Controller. However, controls are the only tools you can leverage to write HTML more
you should note that the pattern depicted in Figure 2 doesn’t exactly quickly. As a result, , some ASP.NET developers may see ASP.NET
match the classic formulation of the MVC pattern. In particular, in MVC as taking a step backward in terms of usability and produc-
the original MVC paper, Model and View are tied together through tivity. Another point to be made, regarding the impact of ASP.NET
an Observer relationship. The MVC pattern, though, is deliberately MVC on everyday development, is that it requires some upfront fa-
loosely defined and, even more importantly, was devised when the miliarity with the MVC pattern. You need to know how controllers
WSS 3.0 and Visit SoftwareFX.com for free trial versions, interactive
MOSS 2007 demos and more information about our latest products.
32 msdn magazine Cutting Edge
SharePoint is a trademark or a registered trademark of Microsoft Corporation. DataParts is a registered trademark of Software FX, Inc. Other names are trademarks or registered trademarks of their respective owners.
and views work together in the ASP.NET implementation. In other Correctly, Microsoft has not positioned ASP.NET MVC as a
words, ASP.NET MVC is not something you can easily learn by ex- replacement for ASP.NET Web Forms. Web Forms is definitely a
perimenting. In my experience, this may be the source of decreased pattern that works for Web applications. At the same time, Ruby-
productivity for the average Web Forms developer. on-Rails has proved that MVC can also be a successful pattern for
Web applications; and ASP.NET MVC confirms this.
The Right Perspective In the end, Web Forms and ASP.NET MVC have pros, cons, and
As an architect or developer, it is essential that you understand structural differences that affect various levels. Generalizing, I’d say
the structural differences between the frameworks so that you can that Web Forms embraces the RAD philosophy whereas ASP.NET
make a thoughtful decision. All in all, ASP.NET Web Forms and MVC is TDD-oriented. Further, Web Forms goes toward an abstrac-
ASP.NET MVC are functionally equivalent in the sense that a skilled tion of the Web that simulates a stateful environment, while ASP.NET
team can successfully use either to build any Web solution. MVC leverages the natural statelessness of the Web and guides you
The skills, education, and attitude of the team, though, are the towards building applications that are loosely coupled and inherently
key points to bear in mind. As you may have figured out yourself, testable, search-engine friendly, and with full control of HTML.
most of the features presented as a plus for either framework may
also be seen as a minus, and vice versa. Full control over HTML, What’s the Perfect Model for ASP.NET?
for example, may be a lifesaver to one person but a nightmare to After using Web Forms for years, I recognize a number of its
another. Personally, I was shocked the first time I saw the content drawbacks, and ASP.NET MVC addresses them quite well: test-
of a nontrivial view page in ASP.NET MVC. But when I showed ability, HTML control, and separation of concerns. But though I
the same page to a customer whose application was still using a see ASP.NET MVC as an equally valid option at this time, I don’t
significant number of ASP pages, well, he was relieved. If you have believe it to be the silver bullet for every Web application. In my
accessibility as a strict requirement, you probably want to take full opinion, ASP.NET MVC today lacks some level of abstraction
control over the HTML being displayed. And this is not entirely for creating standard pieces of HTML. HTML helpers are just an
possible with Web Forms. On the other hand, if you’re building a interesting attempt to speed up HTML creation. I hope to see in the
heavy data-driven application, you’ll welcome the set of data-bound near future a new generation of MVC-specific server controls, as
controls and statefulness offered by Web Forms. easy and quick to learn and use as Web Forms server controls, but
Your first experience with Silverlight was probably some- these for Windows Presentation Foundation (WPF) applications,
thing small: a video player, a simple charting application, or even a and Prism has been updated to support Silverlight as well. The
menu. These types of applications are simple and straightforward Prism package is a mix of framework and guidance for building
to design, and segmenting them into rigorous layers with separate applications. The framework, called the Component Application
responsibilities is overkill. Library (CAL), enables the following:
Problems surface, however, when you try to apply a tightly coupled • Application modularity: Build applications from partitioned
style to large applications. As the number of moving parts grows, components.
the simple style of application development falls apart. Part of the • UI composition: Allows loosely coupled components to form
remedy is layering (see my article “Model-View-ViewModel In user interfaces without discrete knowledge of the rest of the
Silverlight Apps” at msdn.microsoft.com/en-us/magazine/dd458800.aspx), application.
but a tightly coupled architecture is just one of a number of prob- • Service location: Separate horizontal services (for example,
lems that need to be solved in large Silverlight projects. logging and authentication) from vertical services (business
In this article, I show you how to build an application using the logic) to promote clean layering of an application.
composition techniques of the Composite Application Library The CAL is written with these same design principles in mind,
from the Prism project. The example I develop is a simple editor and for application developers it is a buffet-style framework—take
of database data. what you need and leave the rest. Figure 1 shows the basic layout
of the CAL in relation to your own application.
Why Prism? The CAL supports these services to aid you in composing your
As requirements change and a project matures, it is helpful if you application from smaller parts. This means the CAL handles which
can change parts of the application without having these changes pieces are loaded (and when) as well as providing base function-
cascade throughout the system. Modularizing an application ality. You can decide which of these capabilities help you do your
allows you to build application components separately (and loosely job and which might get in the way.
coupled) and to change whole parts of your application without
affecting the rest of the code.
Also, you might not want to load all the pieces of your application This article discusses:
at once. Imagine a customer management application in which users • Silverlight 2
log on and can then manage their prospect pipeline as well as check e- • Application composition
mail from any of their prospects. If a user checks e-mail several times • Dependency injection
a day but manages the pipeline only every day or two, why load the
Technologies discussed:
code to manage the pipeline until it is needed? It would be great if an
application supported on-demand loading of parts of the application, Silverlight 2, Prism
a situation that can be addressed by modularizing the application. Code download available at:
The patterns & practices team at Microsoft created a project called code.msdn.microsoft.com/mag200907Prism
Prism (or CompositeWPF) that is meant to address problems like
July 2009 35
Get the richest set of controls in one great suite. Studio Enterprise 2009
will amaze you with enhanced performance and presentation.
ComponentOne Sales
1.800.858.2739 or 1.412.681.4343
Reduce the size of XAP
files by up to 70%
TRY IT FREE ONLINE @
labs.componentone.com
Grids • Char ting • Repor ting • Scheduling • Menus and Toolbars • Ribbon • Data Input • Editors • PDF
WinForms • WPF • ASP.NET • Silverlight • iPhone • Mobile • ActiveX
© 1987-2009 ComponentOne. All rights reserved. iPhone and iPod are trademarks of Apple Inc. Guitar Hero is a registered trademark of
Activision Publishing, Inc. All other product and brand names are trademarks and/or registered trademarks of their respective holders.
But why is this important? For one thing, modularizing your
code should make it easier to test. Being able to swap out a project’s
dependencies enables cleaner testing so that only the code to be
tested can be the source of a test failing, instead of code some-
where in the nested chain of dependencies. Here’s a concrete
example. Imagine you have a component that other developers
use to look up addresses for particular companies. Your com-
ponent depends on a data access component that retrieves the
data for you. When you test your component, you start by test-
Figure 1 Composite Application Library ing it against the database, and some of the tests fail. But because
the schema and builds of the database are constantly changing,
My example in this article uses as much of the CAL as possible. you don’t know whether your tests are failing because of your
It is a shell application that uses the CAL to load several modules own code or the data access code. With your component’s hard
at run time, place views in regions (as shown in Figure 2), and sup- dependency on the data access component, testing the applica-
port services. But before we get to that code, you need to under- tion becomes unreliable and causes churn while you track down
stand some basic concepts about dependency injection (also called failures in your code or in other’s code.
Inversion of Control, or IoC). Many of the CAL’s features rely on Your component might look something like this:
dependency injection, so understanding the basics will help you public class AddressComponent
develop the architecture of your Silverlight project with Prism. {
DataAccessComponent data = new DataAccessComponent();
Figure 5 Registering Types Once initialized, this module is responsible for the logging
implementation for the application. But how does this module
public class Bootstrapper : UnityBootstrapper get loaded?
{
protected override void ConfigureContainer() When using the CAL to compose an application, you need
{ to create a ModuleCatalog that contains all the modules for the
Container.RegisterType<IShellProvider, Shell>();
base.ConfigureContainer(); application. You create this catalog by overriding the bootstrapper’s
} GetModuleCatalog call. In Silverlight, you can populate this catalog
protected override DependencyObject CreateShell() with code or with XAML.
{ With code, you create a new instance of the ModuleCatalog class
// Get the provider for the shell
IShellProvider shellProvider = Container.Resolve<IShellProvider>(); and populate it with the modules. For example, look at this:
protected override IModuleCatalog GetModuleCatalog()
// Tell the provider to create the shell {
UIElement theShell = shellProvider.CreateShell(); var logModule = new ModuleInfo()
{
// Assign the shell to the root visual of our App ModuleName = "ServerLogger",
App.Current.RootVisual = theShell; ModuleType =
"ServerLogger.ServerLoggerModule, ServerLogger, Version = 1.0.0.0"
// Return the Shell };
return theShell;
} var catalog = new ModuleCatalog();
catalog.AddModule(logModule);
protected override IModuleCatalog GetModuleCatalog()
{ return catalog;
... }
} Here, I simply add a single module called ServerLogger, the type
}
defined in the ModuleInfo’s ModuleType property. In addition, you
msdnmagazine.com July 2009 41
can specify dependencies between modules. Because some modules Figure 6 A Sample Catalog.xaml File
might depend on others, using dependencies helps the catalog <m:ModuleCatalog
know the order in which to bring in the dependencies. Using the xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
ModuleInfo.DependsOn property, you can specify which named xmlns:sys="clr-namespace:System;assembly=mscorlib"
modules are required to load another module. xmlns:m="clr-namespace:Microsoft.Practices.Composite.Modularity;
assembly=Microsoft.Practices.Composite">
You can load the catalog directly from a XAML file, as shown <m:ModuleInfoGroup InitializationMode="WhenAvailable">
here: <m:ModuleInfo ModuleName="GameEditor.Client.Data"
ModuleType="GameEditor.Client.Data.GameEditorDataModule,
protected override IModuleCatalog GetModuleCatalog()
GameEditor.Client.Data, Version=1.0.0.0"/>
{
<m:ModuleInfo ModuleName="GameEditor.GameList"
var catalog = ModuleCatalog.CreateFromXaml(new Uri("catalog.xaml",
ModuleType="GameEditor.GameList.GameListModule,
UriKind.Relative));
GameEditor.GameList, Version=1.0.0.0"
return catalog;
InitializationMode="WhenAvailable">
}
<m:ModuleInfo.DependsOn>
The XAML file contains the same type information you can cre- <sys:String>GameEditor.Client.Data</sys:String>
</m:ModuleInfo.DependsOn>
ate with code. The benefit of using XAML is that you can change it </m:ModuleInfo>
on the fly. (Imagine retrieving the XAML file from a server or from </m:ModuleInfoGroup>
</m:ModuleCatalog>
another location based on which user logged on.) An example of
a catalog.xaml file is shown in Figure 6.
In this XAML catalog, the group includes two modules and the
For Silverlight applications, this is a way to compose your
second module depends on the first. You could use a specific XAML
applications from multiple .xap files, which allows you to version
catalog based on roles or permissions, as you could with code.
different sections of your composed application separately.
Once the catalog is loaded by the bootstrapper, it attempts to
When creating Silverlight modules to be housed in a .xap file,
create instances of the module classes and allow them to initialize
you create a Silverlight Application (not a Silverlight Library).
themselves. In the code examples here, the types have to be refer-
Then you reference all the module projects you want to put in
enced by the application (therefore, already loaded into memory)
the .xap file. You need to remove the app.xaml and page.xaml
for this catalog to work.
files because this .xap file will not be loaded and run like a typi-
This is where this facility becomes indispensible to Silverlight.
cal .xap file. The .xap file is just a container (could be a .zip file,
Although the unit of work is the assembly, you can specify a .xap
it doesn’t matter). Also, if you are referencing projects that are
file that contains the module or modules. To do this, you specify
already referenced in the main project, you can change those
a Ref value in ModuleInfo. The Ref value is a path to the .xap file
references to Copy Local=false in the properties because you
that contains the module:
don’t need the assemblies in the .xap file (the main application
protected override IModuleCatalog GetModuleCatalog()
{ has already loaded them, so the catalog will not try to load them
var logModule = new ModuleInfo() a second time.)
{
ModuleName = "ServerLogger", But loading a huge application with multiple calls across
ModuleType = the wire does not seem like it would help performance. That is
"ServerLogger.ServerLoggerModule, ServerLogger, Version= 1.0.0.0",
Ref = "ServerLogger.xap" where the ModuleInfo’s InitializationMode property comes into
}; play. InitializationMode supports two modes: WhenAvailable,
var catalog = new ModuleCatalog(); in which the .xap file is loaded asynchronously and then initial-
catalog.AddModule(logModule);
ized (this is the default behavior), and OnDemand, in which
return catalog; the .xap is loaded when explicitly requested. Since the module
}
catalog does not know the types in the modules until initial-
When you specify a .xap file, the bootstrapper knows that the ization, resolving types that are initialized with OnDemand
assembly is not available and goes out to the server and retrieves will fail.
the .xap file asynchronously. Once the .xap file is loaded, Prism On-demand support for modules and groups allows you to
loads the assembly and creates the module type and initializes load certain functionality in a large application as needed. Startup
the module. time is accelerated, and other required code can be loaded as users
For .xap files that contain multiple modules, you can create a interact with an application. This is a great feature to use when you
ModuleGroup that contains a set of ModuleInfo objects and set have authorization to separate parts of an application. Users who
the Ref of the ModuleGroup to load all those modules from a need only a few parts of the application do not have to download
single .xap file: code they’ll never use.
var modGroup = new ModuleInfoGroup();
modGroup.Ref = "MyMods.xap"; To load a module on demand, you need access to an IModule-
modGroup.Add(logModule); Manager interface. Most often, you request this in the construc-
modGroup.Add(dataModule);
modGroup.Add(viewModule); tor of the class that needs to load a module on demand. Then you
var catalog = new ModuleCatalog();
use IModuleManager to load the module by calling LoadModule,
catalog.AddGroup(modGroup); as shown in Figure 7.
42 msdn magazine Silverlight
Willie the Wintellectual
memory leaks?
poor performance
& scalability?
unexplained
crashes?
after a game is selected so that other controls that want to change When SaveCommand is executed, it calls the Save method on our
their context as the user selects a game can subscribe to that event. ViewModel. The CanSave method is then called to make sure the com-
Our event class looks like the following: mand is valid. This allows the DelegateCommand to disable the UI if
public class GameSelectedEvent : CompositePresentationEvent<Game> necessary. As the state of the view changes, you can call the Delegate-
{
}
Command.RaiseCanExecuteChanged method to force a new inspec-
Once the event is defined, the event aggregator can publish the event tion of the CanSave method to enable or disable the UI as necessary.
by calling its GetEvent method. This retrieves the singleton event that To bind this to XAML, use the Click.Command attached prop-
is going to be aggregated. The first one who calls this method cre- erty that is in the Microsoft.Practices.Composite.Presentation.
ates the singleton. From the event, you can call the Publish method Commands namespace. Then bind the value of the command to
to create the event. Publishing the event is like firing an event. You be the command you have in your ViewModel, like so:
do not need to publish the event until it needs to send information. <Button Content="Save"
cmd:Click.Command="{Binding SaveCommand}"
For example, when a game is selected in the GameList, our example Style="{StaticResource ourButton}"
publishes the selected game using the new event: Grid.Column="1" />
// Fire Selection Changed with Global Event Now when the Click event is fired, our command is executed. If
theEventAggregator.GetEvent<GameSelectedEvent>().Publish(o as Game);
you want, you can specify a command parameter to be sent to the
In other parts of your composed application, you can subscribe command so you can reuse it.
to the event to be called after the event is published. The Subscribe As you might be wondering, the only command that exists
method of the event allows you to specify the method to be called in the CAL is the Click event for a button (or any other selec-
when the event is published, an option that allows you to request tor). But the classes you can use to write your own commands
threading semantics for calling the event (for example, the UI are fairly straightforward. The sample code includes a command
thread is commonly used), and whether to have the aggregator for SelectionChanged on a ListBox/ComboBox. This command
hold a reference to the passed in information so that it is not sub- is called the SelectorCommandBehavior and derives from the
ject to garbage collection: CommandBehaviorBase<T> class. Looking at the custom com-
// Register for the aggregated event
aggregator.GetEvent<GameSelectedEvent>().Subscribe(SetGame, mand behavior implementation will provide you with a starting
ThreadOption.UIThread, place to write your own command behaviors.
false);
As a subscriber, you can also specify filters that are called only in spe- Wrapping Up
cific situations. Imagine an event that returns the state of an application There are definite pain points when developing large Silverlight
and a filter that is called only during certain data states. applications. By building your applications with loose coupling
The event aggregator allows you to have communication between and modularity, you gain benefits and can be agile in responding
your modules without causing tight coupling. If you subscribe to to change. The Prism project from Microsoft provides the tools and
an event that is never published or publish an event that is never guidance to allow that agility to come to the surface of your proj-
subscribed, your code will never fail. ect. While Prism is not a one-size-fits-all approach, the modularity
of the CAL means you can use what fits in your specific scenarios
Delegate Commands and leave the rest.
In Silverlight (unlike WPF), a true commanding infrastructure
does not exist. This forces the use of code-behind in views to
accomplish tasks that would be accomplished more readily directly
SHAWN WILDEMUTH is a Microsoft MVP (C#) and the founder of Wildermuth
in XAML using the commanding infrastructure. Until Silverlight Consulting Services. He is the author of several books and numerous articles. In
supports this facility, the CAL supports a class that helps solve this addition, Shawn currently runs the Silverlight Tour, teaching Silverlight around
problem: the DelegateCommand. the country. He can be contacted at shawn@wildermuthconsulting.com.
msdnmagazine.com July 2009 45
R E S Tf u l X H T M L
Building XHTML-
Based RESTful Services
with ASP.NET MVC
Aaron Skonnard
A RESTful service is a web of resources that programs When a user clicks on an <a> element in the rendered page, the
can navigate. When designing a RESTful service, you have to think browser knows to issue an HTTP GET request for the target resource
carefully about how your web will work. This means designing and render the response. When a browser encounters a <form>
resource representations with links that facilitate navigation, de- element, it knows how to render the form description into a user
scribing service input somehow, and considering how consumers interface that the user can fill out and submit using either a GET or
will navigate around your service at run time. Getting these things POST request. When the user presses a submit button, the browser
right is often overlooked, but they’re central to realizing the full encodes the data and sends it using the specified request. These two
potential REST has to offer. features are largely responsible for the success of the Web.
Today, humans navigate sites using Web browsers that know how Using links in conjunction with the universal HTTP interface
to render HTML and other popular content types. HTML provides makes it possible to redirect requests to new locations over time
the syntax and semantics for establishing links between resources and change certain aspects of security on the fly without changing
(<a> element) and for describing and submitting application input the client code. A standard approach for forms means that you can
(<form> and <input> elements). add or remove input properties and change default values, again
without changing the client code. Both features are very useful for
building applications that evolve over time.
This article discusses: Your RESTful services should also somehow provide these two
• REST features through whatever resource representation you decide to
• XHTML use. For example, if you’re designing a custom XML dialect for your
• ASP.NET MVC service, you should probably come up with your own elements
for establishing links and describing service input that will guide
Technologies discussed:
consumers through your web. Or you can simply use XHTML.
REST, XHTML, ASP.NET Most developers don’t immediately consider XHTML as an
Code download available at: option for “services,” but that’s actually one of the ways it was intend-
msdn.microsoft.com/mag200907REST
ed to be used. XHTML documents are by definition well-formed
XML, which allows for automated processing using standard XML
48 msdn magazine
APIs. And since XHTML is also HTML, it comes with <a>, <form>, probably find that XLinq provides the most natural programming
and <input> elements for modeling link navigation and service model for consuming XHTML programmatically. In addition, you
input as I described earlier. The only thing that’s a little strange at can go one step further by enhancing XLinq with some helpful
first is how you model user-defined data structures—however, you XHTML-focused extension methods that make the programming
can model classes and fields with <div> and <span> elements and model even easier.
collections of entities with <ol> and <li> elements. I’ll walk through Throughout this article, I’ll use a set of XLinq extension methods
how to do this in more detail later in the article. that I’ve included in the downloadable sample code. These exten-
To summarize, there are several reasons to consider XHTML sions give you a good idea of what’s possible. The following code
as the default representation for your RESTful services. First, you shows how to consume the bookmark XHTML shown previously
can leverage the syntax and semantics for important elements like using XLinq and some of these extensions:
<a>, <form>, and <input> instead of inventing your own. Second, var bookmarkDetails = bookmarkDoc.Body().Struct("bookmark");
Console.WriteLine(bookmarkDetails["bookmark-id"].Value);
you’ll end up with services that feel a lot like sites because they’ll Console.WriteLine(bookmarkDetails["bookmark-url"].Value);
be browsable by both users and applications. The XHTML is still Console.WriteLine(bookmarkDetails["bookmark-title"].Value);
interpreted by a human—it’s just a programmer during development Now, if you want to improve how this bookmark renders in
instead of a user at runtime. This simplifies things throughout the a browser, you can add a Cascading Stylesheet (CSS) to control
development process and makes it easier for consumers to learn browser-specific rendering details or add some additional UI
how your service works. And finally, you can leverage standard Web elements and text that don’t compromise the consumer’s ability to
development frameworks to build your RESTful services. extract the data of interest. For example, the following XHTML
ASP.NET MVC is one such framework that provides an inherently will be easier for humans to process, but you can still use the
RESTful model for building XHTML-based services. This article previous .NET code sample to process the information without
walks through some XHTML design concepts and then shows you any modification:
how to build a complete XHTML-based RESTful service that you <h1>Bookmark Details: 3</h1>
<div class="bookmark">
can download from the MSDN Magazine site. BookmarkID: <span class="bookmark-id">25</span><br />
Title: <span class="bookmark-title">Aaron's Blog</span><br />