You are on page 1of 76

@CODEMagazine RavenDB, MongoDB, SQL Server 2012, ASP.

NET MVC 4, CODE Framework

MAR
APR
2012 An EPS Company
codemag.com - THE LEADING INDEPENDENT DEVELOPER MAGAZINE - CODE COMPONENT DEVELOPER ® MAGAZINE

Solve the
Data Puzzle!

US $ 5.95 Can $ 8.95 Sponsored by:


TABLE OF CONTENTS

Features
8 SharePoint Applied: ServiceBus and 62 Smashing the Myth:
SharePoint 2010 Why You Must Learn F#--Even If You
Sahil explains integrating the AppFabric ServiceBus with SharePoint 2010
Aren’t Writing Rocket Science Apps
and Office 365. To the cloud and beyond! If you work with .NET Framework, you’ve encountered F#. Aaron shows
Sahil Malik you why it’s for everyone, not just elite scientific research labs.
Aaron Erickson
14 Working with Windows Phone User Interfaces,
Part 2 68 ASP MVC 4 Highlights, Part 1
Programming for the Windows Phone is easy for anyone with Silverlight John goes out on the road with mobility support and ASP.NET MVC 4.
programming experience. Paul focuses on using some of the built-in There are new templates, a new way to generate code, and enhanced
applications with Launcher and Chooser in this second installment. support for async methods.
Paul D. Sheriff John V. Petersen

18 Getting Started with RavenDB


Not all relational databases are equal and RavenDB might be just the
tool you need to simplify your data storage needs. In this overview, Oren
Columns
shows basic CRUD operations, design theory, and how indexes work. 66 Post Mortem: Xiine for iOS
Oren Eini
Milton takes an Android application and converts it to the iOS platform.
Milton Abe
26 The Baker’s Dozen Doubleheader: 26 New
Features in SQL Server 2012 (Part 1 of 2) 74 Managed Coder: On Abstraction
Kevin looks at 13 new T-SQL and database engine features in SQL Server Ted Neward
2012. He’s pretty excited about all the new features!
Kevin S. Goff

43 CODE Framework: Building Services and SOA


Business Layers
Departments
6 Editorial
Markus creates some simple services and Service Oriented Architecture
(SOA) to speed us on our way into productive feature sets. He gives 73 Code Compilers
pointers on creating contracts, implementation, hosting for development,
calling services, and production deployment. 13 Advertisers Index
Markus Egger

58 Introducing huMONGOus Database


Mike discusses 10Gen’s new open source-distributed document-oriented
database, called MongoDB. He tells you when it’s great and when you
might need another tool.
Mike Benner

Sponsored by:

US subscriptions are US $29.99 for one year. Subscriptions outside the US pay US $44.99. Payments should be made in US dollars drawn on a US bank. American Express,
MasterCard, Visa, and Discover credit cards are accepted. Bill me o ption is available only for US subscriptions. Back issues are available. For subscription information, send
e-mail to subscriptions@code-magazine.com or contact customer service at 832-717-4445 ext 10.
Subscribe online at codemag.com
CoDe Component Developer Magazine (ISSN # 1547-5166) is published bimonthly by EPS Software Corporation, 6605 Cypresswood Drive., Suite 300, Spring, TX 77379 U.S.A.
POSTMASTER: Send address changes to CoDe Component Developer Magazine, 6605 Cypresswood Drive., Suite 300, Spring, TX 77379 U.S.A..

4 Table of Contents codemag.com


EDITORIAL

So Many Choices
Once again we find ourselves at a massive crossroads. A new preview of Windows 8 will be avail-
able to the public by the time you read this editorial, SQL Server 2012 is in the final stages
before a gold disk is stamped, and ASP.NET MVC is getting closer to shipment. Rumors are

that we’ll see a new version of Visual Studio Native/Non-Native Mobile tures in SQL Server 2012 as well as highlighting
within a year. And this just the Windows eco- Development two NoSQL databases: Raven DB and MongoDB.
system. CODE Magazine will explore this topic more in
the coming year.
Apple is continuing its march forward with new One of the biggest choices for developers to-
versions of OSX, iOS and their mobile phones day is the choice between developing native vs.
and tablets. Android is a force to reckon with non-native (i.e., browser-based) applications. Making Good Choices Going Forward
as Google ships new versions of the Android OS Do you pick Objective-C, Java or C#/XAML for
and many, many new hardware vendors support building mobile applications? Or do you choose My time is up for this editorial. I hope I have
it. These choices are not limited to just develop- to use HTML5, CSS and JavaScript? For most ap- opened your eyes into three areas where you
ment platforms. The world of data is on fire, too. plications I recommend leaning towards HTML5/ need to assess your choices carefully. As CODE
Oracle and Microsoft continue to push the tradi- CSS. The reason for this choice is simple to me: Magazine writers gather content and write more
tional boundaries of relational database develop- cost and reach. The power and speed of JavaS- about these choices that developers need to
ment while new ways of looking at data are upon cript accompanied by the flexibility and power make, I hope you’ll contact me and let me know
us with tools like MongoDB, RavenDB, Redis and of HTML5/CSS has never been greater. The real what trends you’d like to see us explore.
Apache Cassandra. proof is how many applications have gone from
native tools to HTML5/CSS. For me there are two
As a software developer, which of these affects that come to mind. The first one is the Amazon Rod Paddock
you? All of them. As software developers we have Kindle reader. Last year Apple and Amazon had
never been faced with such a rich and at the same a bit of a tiff when it came to in-app purchases
time perilous set of choices. And yes, I mean per- of books. Amazon took a first step around this
ilous because each and every one of these choices problem by rewriting their Kindle Reader using
comes with its associated costs. Choosing the HTML5/CSS and JavaScript. Another cool devel-
wrong platform can be costly in the form of time opment was the conversion of a game called Cut
and treasure. Allow me to prognosticate on some the Rope from native to IE 9. Cut the Rope is a
of these choices. much-loved game in the mobile gaming space.
The development team that created Cut the Rope
converted their application from Objective-C to
JavaScript and Windows 8 HTML5/CSS. This is quite an accomplishment as
this game has a cool set of user interactions that
Windows 8 is a radical step for Microsoft and you I was simply amazed they were able to convert
as a developer need to be careful when making to HTML5/CSS. If you want to learn more about
choices for this platform. As a developer, one how they converted the app to HTML5/CSS,
of the biggest things you must avoid is choos- check out this article: http://www.cuttherope.
ing JavaScript for your development language ie/dev/
for desktop applications. Visual Studio 11 Beta
(likely to be called Visual Studio 2012) provides
you multiple languages choices, including Visual Data, Data Everywhere and a Whole Lot
Basic, C# and C++. The newest member of this to Drink
family is JavaScript. In my opinion, you will make
a bad decision if you choose JavaScript for devel- The data space has been very active lately. For
oping applications on the Windows 8 platform. some companies, industry-standard relational
Why choose JavaScript when the three majors are databases have been replaced with NoSQL da-
light years beyond JavaScript in power and ro- tabases. There are key value stores, document
bustness? The ENTIRE POINT of using JavaScript databases, relational databases, column stores
for development is REACH, plain and simple. Ja- and in-memory databases. Applications like
vaScript is a universal language available across Facebook, Netflix, Twitter and Farmville have
all platforms: Windows, OSX and Linux. The Ja- required developers to think about data in
vaScript extensions found in Windows 8 are for very different ways. As companies explore this
just Windows and no more. Portability goes right change in data sores, development teams need
out the window. If you are developing for the to start thinking outside of the box of rows and
Windows platform, stay away from the JavaScript columns. With this in mind, this issue of CODE
tools. Magazine is exploring new and interesting fea-

6 Editorial codemag.com
ONLI
ON
ONLINE
LINE
LINE Q
QUICK
UICK
UICK IID
D 00
000
1203021
0

SharePoint Applied: Azure


ServiceBus and SharePoint 2010
The cloud means many things. It means Facebook, LinkedIn, Twitter, Google, Bing and – oh yes – Windows Azure!
Windows Azure, as you know, is Microsoft’s cloud operating system. It consists of many parts, but at a high level you can
say it includes Compute (web and worker roles, plus storage), SQL Azure and AppFabric. AppFabric, in turn, consists of

AppFabric Access Control, ServiceBus, and Cache. This ar- AppFabric ServiceBus queues are exactly what the name im-
ticle concerns ServiceBus, and its integration with Share- plies: first in first out. But it is important to understand that
Point 2010 and Office 365. AppFabric ServiceBus queues are not the same as Azure stor-
age queues. AppFabric ServiceBus queues can be roughly
What is Azure Service Bus (also known as Azure AppFabric thought of as MSMQ for the cloud. It gives you a reliable,
Service Bus)? durable storage mechanism with a listener and a sender. In
fact, you can have many listeners and many senders on a
“All applications will move to the cloud.” Isn’t that the queue. This enables some really interesting scenarios that
mantra these days? AppFabric ServiceBus queues can solve. For instance:
Sahil Malik
www.winsmarts.com No, they won’t! Developers have spent more than 30 years • Queues can perform load leveling – if your input traf-
Sahil Malik is a Microsoft MVP, writing software. Things are not moving to the cloud over- fic is unpredictable in nature, a queue acts as a shock
INETA speaker, a .NET author, night. In fact, some applications will perhaps never move absorber, and effectively queues up requests to be
consultant and trainer. to the cloud. There are many reasons for that, and some processed until the listener(s) catch up to the load.
that technology alone won’t be able to solve. Organiza- • You can use AppFabric ServiceBus queues as a load
Sahil loves interacting with fel- tions are nervous about putting their sensitive data in the balancing mechanism; many listeners can listen
low geeks in real time. His talks cloud due to lack of confidence or legal reasons. Perhaps on a queue. Very similar to MSMQ, AppFabric Ser-
and trainings are full of humor the applications that the data depends on are not cloud viceBus queues also have transactional session-full
and practical nuggets. You can ready yet. Or maybe the extra latency that the cloud in- message semantics, thereby ensuring that a mes-
find more about his trainings troduces is not ideal for a certain category of applications. sage isn’t dequeued until it is properly processed.
at http://www.winsmarts.com/ • Queues can offer decoupling – the sender and re-
training.aspx. But there is certainly an undeniable advantage that the ceiver do not have to be online at the same time.
cloud offers for certain kinds of applications. Just look at • Queues offer the equivalent of transactions for dis-
your smartphone. The apps on it depend on services in tributed systems, where semantics such as peek/
the cloud. Wouldn’t it be nice if your smartphone could lock and de-duplication offer you graceful recovery
securely pull information from on-premises applications scenarios when various components of a distributed
without offering a million security prompts or VPN issues? system might fail unpredictably.
Most smartphones that do support conventional VPN
break the VPN connection as soon as the screen turns off As amazing as AppFabric ServiceBus queues are, some-
and the phone goes into battery save mode. Traditional thing even more amazing than queues are topics. Topics
solutions are not the solution here. are just like queues, except they have a concept of rich
messages laden with metadata on which you can create
This is where AppFabric ServiceBus helps. It allows you subscriptions. You can think of subscriptions as virtual
to bridge on-premises applications with cloud applica- queues. A listener creates a subscription using a SQL-92
tions, cloud applications with on-premises applications, syntax. This allows for newer interesting scenarios such
and cloud applications with other cloud applications, as a logging subscription, fanning out messages to vari-
or on-premises applications with other on-premises ap- ous listeners, etc.
plications (perhaps on someone else’s premises) easily,
securely, without any major firewall reconfigurations. What makes me really excited about Azure, in general,
It does so by making outbound TCP or HTTP calls to a is that almost everything is exposed over a REST-based
namespace hosted in Azure. API. This truly makes Azure extremely programmable from
every single platform, including JavaScript.
Perhaps the best part about AppFabric is the rather in-
tuitive way you can use it. If you have used WCF, you While AppFabric ServiceBus is a pretty big topic in itself,
may be familiar with netTcpBinding and webHttpBind- in this article, I will demonstrate its integration with
ing. Well, AppFabric contains netTcpRelayBinding and SharePoint using webHttpRelayBinding.
webHttpRelayBinding that are rough equivalents of what
you are used to in WCF, except they work with an interme-
diary broker – which is your Azure AppFabric ServiceBus Creating an AppFabric ServiceBus REST
namespace. In addition, AppFabric ServiceBus also pro- Application
vides you with programming paradigms such as queues
and topics that go above and beyond the simple WCF pro- Developers can use ServiceBus in many ways. One of the
gramming model. most straightforward ways is to simply use it as a WCF

8 SharePoint Applied: Azure ServiceBus and SharePoint 2010 codemag.com


Figure 1: The Service Bus, Access Figure 2: Creating an AppFabric namespace
Control & Caching link
for Access Control and Cache as well – but in this article I
will talk only about Service Bus (Figure 2).

It will take a few minutes for your namespace to get pro-


visioned. Meanwhile, go get yourself a coffee or two. Once
provisioned, it should look like Figure 3.

Now, with the namespace selected as shown above, click


on the “Default Key” section on the right-hand side in
the Azure Management Portal. This will show you your
owner and key name. Note these down as you will need
them shortly.

Creating the REST Application

ServiceBus relay bindings require https. You could set this


up in IIS, but for development purposes, it is way easier
Figure 3: Your newly created service. In this article, I will demonstrate how to use a to do so in a console application serving as a host. When
namespace. special binding called webHttpRelayBinding to expose we use Visual Studio to develop web applications, we use
an on-premise REST API binding over the Service Bus. a tiny little Web server hosted in the system tray. This Web
The end effect of this exercise will be that you can run a server, named Cassini, is extremely convenient. Cassini,
simple service on your desktop and without configuring unfortunately cannot do HTTPS. So, we’ll use a .NET 4.0
the firewall or your router, you will be able to expose a console application.
REST-based service to the world. I am not joking; this is
the magic of Service Bus. Therefore, create a .NET 4.0 console application called
AppFabricREST and add the following references to it:
In order to achieve this, there are two things you need
to do: • C:\Program Files\Windows Azure AppFabric SDK\
V1.5\Assemblies\NET4.0\Microsoft.ServiceBus.dll
• Create a Service Bus namespace • System.ServiceModel
• Create a WCF service and client that will communi- • System.ServiceModel.Web
cate over this namespace.
Now, in this project, add two classes – HelloWorld.cs and
Creating the Service Bus Namespace IHelloWorld.cs. As you might have guessed, one of these
is the contract and the other is the implementation. List-
In order to create yourself a Service Bus namespace, you ing 1 shows the code for both classes.
will need an Azure subscription. You can sign up for a
free trial and set yourself a zero dollar spending limit, Note from Listing 1 that this is the same old WCF you love
so there is really no reason to not try it. Once you have and use. Nothing new here. The same WebGet attribute,
such a subscription set up for yourself, go to https://win- the same serialization formats. The magic next happens
dows.azure.com and login using your credentials. In the in the Program.cs and the App.config. Next, we need to
management portal, click “Service Bus, Access Control & write the code in Program.cs to host this service. We will
Caching” as shown in Figure 1. use a special class part of WCF called WebServiceHost. You
can use this class to host http-based services easily in
When you are inside the Service Bus, Access Control & console applications. Again this is pure WCF, nothing spe-
Caching area, click New on the toolbar and create yourself cific to AppFabric yet. You can see the code for Program.
a namespace. You can go ahead and create a namespace cs in Listing 2.

10 SharePoint Applied: Azure ServiceBus and SharePoint 2010 codemag.com


Well I lied. There is one minor difference between a plain issues using a cross-domain policy file on your Azure web
WCF application and Listing 2, and that is the Service- role, you will not be able to affect Office 365.
BusEnvironment.CreateServiceUri line. That is what reg-
isters your service URL in your serviceNamespace. Also, Office 365 needs a purely client-side solution in pure Ja-
note that we are using https since transport-level security vaScript. Thankfully there is help. You can use the devel-
is required. ServiceBus also supports message-level secu- oper version of Yahoo Pipes, referred to as YQL or Yahoo
rity if that is what you desire. Using REST APIs you can use Query Language, to integrate with Service Bus using pure
OAUTH, and using socket-oriented communication you
can use numerous other message-level security protocols.
Listing 1: IHelloWorld and HelloWorld
Next, to finish up the application, edit the App.Config of [ServiceContract(Name = "HelloContract", Namespace =
the AppFabricREST application to look like Listing 3. "http://www.winsmarts.com")]
public interface IHelloWorld
As you can see from this App.config, I am using a special {
binding called webHttpRelayBinding. For simplicity sake, [OperationContract, WebGet(UriTemplate =
I am not using any kind of security, but note that you "Hello/{who}", ResponseFormat=WebMessageFormat.Json)]
could have forwarded client identities as well. Also, there List<string> Hello(string who);
is the owner and key – you need to add the owner and key }
you noted down earlier in the article. With this web.config public class HelloWorld : IHelloWorld
in place, go ahead and run your service. You will see the {
service running as shown in Figure 4. public List<string> Hello(string who)
{
Console.WriteLine(who);
Now, call your mom, and ask her to visit this URL. Note
that your namespace may be different. You will be de-
return new List<string>()
lighted to see that your Mom can see an output as shown {
in Figure 5 over the Internet. "Hello " + who,
"is it me you're looking for",
No firewall configurations at all! Incredible! Isn’t it? Now "I can see it in your eyes",
if your mom can see your service running, I would bet we "I can see it in your smile"
can make SharePoint see it as well. };
}
}
Integrating Service Bus with SharePoint
2010 and Office 365 Listing 2: Hosting your application
I threw in Office 365 for a good measure because Office static void Main(string[] args)
365 custom code puts an additional restriction on us – {
all the code has to be a sandbox solution. This may feel Console.Write("Your Service Namespace: ");
restrictive, but do not underestimate the power of pure string serviceNamespace = Console.ReadLine();
client-side code. I will demonstrate how you can integrate
the above REST call using pure JavaScript code. Uri address = ServiceBusEnvironment.CreateServiceUri("https",
serviceNamespace, "HelloWorld");
Calling REST URLs using JavaScript is incredibly easy us-
WebServiceHost host = new WebServiceHost(typeof(HelloWorld), address);
ing jQuery. You can use a simple method such as $.get
host.Open();
or $.getJSON or $.ajax. Unfortunately that won’t work,
at least not in such a straightforward manner. This is be-
Console.WriteLine("Copy the following address into a browser to see the image: ");
cause, technically speaking, the call to your Service Bus Console.WriteLine(address + "Hello/Sahil");
URL will be a cross-domain call. Not only cross domain, Console.WriteLine();
but you are probably transitioning from http to https, or Console.WriteLine("Press [Enter] to exit");
one https to another https. This will cause an ugly warn- Console.ReadLine();
ing on the client side, even if you are using an older ver-
sion of jQuery or hands-down Ajax code without using host.Close();
jQuery. You can read more about cross-domain calls and }
jQuery at http://blah.winsmarts.com/2012-1-jQuery_
and_Crossdomain.aspx.

There are, however, mechanisms you can use to write


cross-domain jQuery calls. But they generally require a
server-side handler or a cross-domain policy, etc. One
mechanism to do so is to write a server-side handler in
Azure. That, unfortunately, is also not a great solution be-
cause even though you may be able to solve cross-domain
Figure 4: Your REST service running on Service Bus.

Figure 5: Output of your REST API service.

codemag.com SharePoint Applied: Azure ServiceBus and SharePoint 2010 11


Listing 3: The App.config for the service
<?xml version="1.0"?> </behavior>
<configuration> </endpointBehaviors>
<system.serviceModel> <serviceBehaviors>
<bindings> <behavior name="default">
<webHttpRelayBinding> <serviceDebug httpHelpPageEnabled="false"
<binding name="default"> httpsHelpPageEnabled="false"/>
<security relayClientAuthenticationType="None"/> </behavior>
</binding> </serviceBehaviors>
</webHttpRelayBinding> </behaviors>
</bindings>
<extensions>
<services> <behaviorExtensions>
<service name="AppFabricREST.HelloWorld" <add name="transportClientEndpointBehavior"
behaviorConfiguration="default"> type="Microsoft.ServiceBus.
<endpoint name="RelayEndpoint" Configuration.TransportClientEndpointBehaviorElement,
contract="AppFabricREST.IHelloWorld" Microsoft.ServiceBus, Version=1.5.0.0,
binding="webHttpRelayBinding" Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
bindingConfiguration="default" </behaviorExtensions>
behaviorConfiguration="sharedSecretClientCredentials" <bindingExtensions>
address=""/> <add name="webHttpRelayBinding"
</service> type="Microsoft.ServiceBus.Configuration.
</services> WebHttpRelayBindingCollectionElement,
Microsoft.ServiceBus, Version=1.5.0.0,
<behaviors> Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<endpointBehaviors> </bindingExtensions>
<behavior name="sharedSecretClientCredentials"> </extensions>
<transportClientEndpointBehavior> </system.serviceModel>
<tokenProvider>
<sharedSecret <system.web>
issuerName="insert owner here" <compilation debug="true" targetFramework="4.0" />
issuerSecret="insert owner key here"/> </system.web>
</tokenProvider> </configuration>
</transportClientEndpointBehavior>

Listing 4: IHelloWorld and HelloWorld


jQuery.ajax = (function (_ajax) { };
var protocol = location.protocol, if (!o.success && o.complete) {
hostname = location.hostname, o.success = o.complete;
exRegex = RegExp(protocol + '//' + hostname), delete o.complete;
YQL = 'http' + (/^https/.test(protocol) ? }
's' : '') + '://query.yahooapis.com/v1/
public/yql?callback=?', o.success = (function (_success) {
query = 'select * from html where url="{URL}" and xpath="*"'; return function (data) {
if (_success) {
function isExternal(url) { _success.call(this, {
return !exRegex.test(url) && /:\/\//.test(url); responseText:
} data.results[0]
.replace(/<script[^>]+
return function (o) { ?\/>|<script(.|\s)*?\/script>/gi, '')
var url = o.url; }, 'success');
if (/get/i.test(o.type) && }
!/json/i.test(o.dataType) && };
isExternal(url)) { })(o.success);
o.url = YQL; }
o.dataType = 'json'; return _ajax.apply(this, arguments);
};
o.data = { })(jQuery.ajax);
q: query.replace(
'{URL}', function InitializeWebPart() {
url + (o.data ? $.get('https://winsmarts.servicebus.windows.net/
(/\?/.test(url) ? '&' : '?') HelloWorld/Hello/Sahil', function (data) {
+ jQuery.param(o.data) $("#results").html(data.responseText);
: '') });
), }
format: 'xml'

12 SharePoint Applied: Azure ServiceBus and SharePoint 2010 codemag.com


JavaScript code. You can see this using the script shown
in Listing 4.

As you can see from Listing 4, I have piggybacked on


YQLs ability to make a query to my Service Bus URL. This,
in turns, negotiates all firewall issues and is able to call
my service and present the information in an Office 365
page purely using JavaScript. You may also note that once
I get the results, I am putting those results in a div called
results, the output of which can be seen in Figure 6.

Summary
Figure 6: Your service being consumed in SharePoint.
Azure AppFabric ServiceBus is an invaluable arrow in your
quiver. Do you have users who wish they could easily ac-
cess on-premise data on their iPhones or other mobile also available on a REST-based API. You can also inte-
platforms? Do you have endless meetings with security- grate them with sandbox solutions using the approach I
minded IT infrastructure people who just don’t care about demonstrated.
your deadlines? Do you have an existing rich investment
in WCF that you wished was available across the Internet In later articles I will continue to push the boundaries
to other applications you care about? ServiceBus is your of what is possible with technologies that are available
friend. today.

In this article, I introduced you to the basic concepts of Until then, Happy SharePointing and Jolly Azuring!
Service Bus. Service Bus, like anything else, is a topic you
can go much deeper into, which I strongly encourage you Sahil Malik
to try. I briefly mentioned queues and topics, which are

ADVERTISERS INDEX
Advertisers Index
Android Developers Conference GOLD SPONSOR - Digital Escrow Services
www.andevcon.com 21
CODE Consulting / Mobile Apps
www.codemag.com/mobileapps 29 www.tower48.com 75
CODE Framework
www.codemag.com/framework 76
GOLD SPONSOR - Art Assets
CODE Magazine
www.codemag.com/magazine 47
CODE Training
www.codemag.com/training 35
DevTeach Developers Conference www.xamalot.com 57
www.devteach.com 15
dtSearch
Bronze Sponsor Advertising Sales:
www.dtSearch.com 61 Tammy Ferguson
832-717-4445 ext 26
National Collegiate Cyber Defense Competition tammy@code-magazine.com
www.nationalccdc.org 55
www.telerik.com 5, 7, 9
State of .NET
www.StateOfDotNet.com 25
SXSW Interactive 2012
www.sxsw.com 69
Tech Conferences Inc.
www.devconnections.com 2
Team Companion
www.teamcompanion.com 41
This listing is provided as a courtesy to our readers and advertisers.
Xiine The publisher assumes no responsibility for errors
www.xiine.com 51 or omissions.

codemag.com SharePoint Applied: Azure ServiceBus and SharePoint 2010 13


ONLINE QUICK ID 1203031

Working with Windows Phone User


Interfaces, Part 2
In Part 1 of this article you learned how to work with orientation changes on the Windows Phone and how to create
horizontally scrolling pages using Panorama and Pivot pages. In Part 2 you’ll see how to interact with some of the built-in
applications on the phone through the use of the Launcher and Chooser applications. In addition, you will learn to create

a common task bar for your Windows Phone using the Ap- • MarketplaceSearchTask
plication Bar. This article assumes that you have Visual • MediaPlayerLauncher
Studio 2010 and the Windows Phone tools installed along • PhoneCallTask
with it. You must download and install the Windows Phone • SearchTask
tools separately to use them with Visual Studio 2010. You • SmsComposeTask
may also download the free Visual Studio 2010 Express for • WebBrowserTask
Windows Phone developer environment.
One important thing to keep in
Paul D. Sheriff Launchers mind when using either the Launcher
PSheriff@pdsa.com or Chooser APIs is that calling these
(714) 734-9792 The Windows Phone does not support multi-tasking (yet); applications could cause your
Paul D. Sheriff is the President however, you can interact with many of the built-in applica-
tions on the phone from within your application. You can in-
application to be “tombstoned.”
of PDSA, Inc. (www.pdsa.com)
and a Microsoft Partner in teract with the built-in applications on the phone in two ways:
Southern California. Paul acts as passing in data, or get back data. A Launcher type of applica- To use any of the Launcher task classes, you first need to
the Microsoft Regional Director tion lets you pass data from your application into the built-in add a using statement at the top of your Page class.
for Southern California assisting phone application. In a Chooser type of application you will
the local Microsoft offices with use a built-in phone application to select some data that is using Microsoft.Phone.Tasks;
several of their events each stored on your phone and return that data to your application.
year and being an evangelist for Next, you create a field in your Page class with a variable
them. Paul has authored literally Using a Launcher that will point to the specific Launcher you wish to use.
hundreds of books, webcasts,
videos and articles on .NET, WPF, When you use the Launcher API on the Windows Phone, SavePhoneNumberTask _Task;
Silverlight, Windows Phone and your application calls one of the built-in applications. The
SQL Server. Check out Paul’s new
user will complete a task, and then control will return to Now create an instance of the class in the constructor for
code generator called Haystack
your application. No data will be returned from a Launcher your page and hook up the Completed event.
at www.CodeHaystack.com.
application; however, your application may pass in some
data to the Launcher. As an example of using a Launcher, public LauncherPage()
you might ask a user to input a phone number, and then {
you pass that phone number to the SavePhoneNumberTask InitializeComponent();
as shown in Figure 1. If the user saves that phone number,
a return result of OK will be returned, but no other data. _Task = new SavePhoneNumberTask();
_Task.Completed += new
One important thing to keep in mind when using either the EventHandler<TaskEventArgs>(_Task_Completed);
Launcher or Chooser API is that calling these applications }
could cause your application to be “tombstoned.” It will be
your responsibility to restore any data that you want after You must create the instance of the task and hook up the
your application is reactivated from the tombstoned state. Completed event handler in the constructor because your
The Windows application will be tombstoned once it calls the Launcher
Built-In Launchers application. Upon reactivating your application, the con-
Phone does not structor will be called again and the completed event needs
support multi-tasking Windows Phone contains several built-in applications to be hooked back up so the Launcher can call the event.
(yet); however, you that your C# or Visual Basic code can launch by instan-
can interact with tiating an instance of the appropriate class. You can find In Figure 1 the user is asked to put a phone number into a
all of the Launcher classes in the Microsoft.Phone.Tasks text box named “txtPhone” on this page. When you click on
many of the built-in namespace. The list below contains the Launcher classes the Save Phone Number button the Click event will fire. At
applications on the you can use on the Windows Phone. this point you take the value from the txtPhone.Text prop-
phone from within erty and set the PhoneNumber property on the SavePhone-
your application. • EmailComposeTask NumberTask object. Now you call the Show() method of the
• MarketplaceDetailTask task object and the Launcher application will run and receive
• MarketplaceHubTask the phone number from your application. Once the new ap-
• MarketplaceReviewTask plication is running, your application will be tombstoned.

14 Working with Windows Phone User Interfaces, Part 2 codemag.com


private void Button_Click(object sender, PhoneNumberChooserTask task = null;
RoutedEventArgs e)
{ Now create an instance of the Chooser class in the con-
// Pass phone number into contacts structor for your page and hook up the Completed event.
_Task.PhoneNumber = txtPhone.Text;
// Display contact info app public ChooserPage()
// This WILL tombstone your app {
_Task.Show(); InitializeComponent();
}
// Need to create this here as your app could
In the Completed event you will want to check the // be tombstoned
e.TaskResult to see if the user accomplished the task. For // Need to rehook the event for this Chooser app
example, when saving a phone number, if they do not ac- task = new PhoneNumberChooserTask();
tually click the save button after adding the new phone task.Completed += new
number/contact, then the result will not come back as EventHandler<PhoneNumberResult>(task_Completed);
OK. Each Launcher may report different results depending }
on what each one is supposed to do. In the Completed
event procedure below you will simply display a message You must create the instance of the task and hook up
box telling the user that the phone number was saved. the Completed event handler in the constructor because
your application could be tombstoned once it calls the
void _Task_Completed(object sender, TaskEventArgs e) Chooser application. Upon reactivating your application,
Figure 1: Enter a Phone Number { the constructor will be called again and the Completed
and then call the SavePhone- if (e.TaskResult == TaskResult.OK) event needs to be hooked back up so the Chooser can
NumberTask Launcher.
MessageBox.Show("Phone Number Saved"); call the event.
}
NOTE: Not all Choosers are tombstoned. Some are just
temporarily deactivated. However, you should program
Choosers defensively and always assume that your application will
be tombstoned.
Just like a Launcher, a Chooser class also calls one of the
built-in applications on the Windows Phone. However, a In the sample application shown in Figure 2 you will click on
Chooser will return data from the application and allow a button to invoke the PhoneNumberChooserTask using the
your application to retrieve that data. The specific Choos- Show() method. On the emulator there is a set of contacts
er that you will use in this article will be the PhoneNum- that you will be able to select from so you can try this out
berChooserTask shown in Figure 2. even if you don’t have a real Windows Phone. Once you select
a phone number from your contact list you will be returned
Overview of Choosers to your application. To make the call to the Phone Number
Chooser call the Show() method of the task object in the
The PhoneNumberChooserTask will make a call to the Peo- button Click event procedure as shown in the code below.
ple on your Windows Phone, allow you to select a contact,
and it will then return the phone number from the contact private void Button_Click(object sender,
chosen. The data returned is specific to the task that you RoutedEventArgs e)
call. For a phone number, you will get a string that con- {
tains the phone number. For a photo Chooser you would // Show Phone Number Chooser
get back an IO stream that contains the image. You could // NOTE: This particular task does NOT necessarily
then turn this into an image to display in your applica- // tombstone your app.
Figure 2: Call the PhoneNumber- tion. The list below is the collection of Launcher classes task.Show();
ChooserTask to return a phone you can use on the Windows Phone. }
number to your application.
• CameraCaptureTask In the Completed event you will want to check the
• EmailAddressChooserTask e.TaskResult to see if the user actually selected a phone
• PhoneNumberChooserTask number from the Chooser. If the user goes to the Choos-
• PhotoChooserTask er, but immediately clicks on the Back button, then the
• SaveEmailAddressTask e.TaskResult will NOT be equal to OK. If the user clicks on
• SavePhoneNumberTask one of the contacts, then the Chooser application will im-
mediately end and the phone number will be returned. In
The class names are pretty self-explanatory so you just this case, the e.TaskResult will be set to OK and you can
need to figure out where you want to get the data that access the e.PhoneNumber property to place the phone
you need for your application. To use any of the Chooser number into the textbox in your application.
task classes, you will first need to add a using statement
at the top of your Page class. void task_Completed(object sender, PhoneNumberResult e)
{
using Microsoft.Phone.Tasks; // See if task completed
if (e.TaskResult == TaskResult.OK)
Create a field in your Page class with a variable that will txtPhone.Text = e.PhoneNumber; // Get number
point to the specific Chooser you wish to use. }

16 Working with Windows Phone User Interfaces, Part 2 codemag.com


Application Bar for this image. Now on one of your pages, scroll to the bottom
and uncomment the application bar XAML. For this sample
Another UI feature that you might use is the Application you can eliminate one of the ApplicationBarIconButton con-
Bar. The Application Bar provides a place for you to put the trols and one of the ApplicationBarMenuItem controls. In the
common tasks for a particular page. You are only allowed ApplicationBarIconButton control that is left, modify the Text
one to four icons on the Application Bar. For example, you property to Add Product. Modify the IconUri property to /Im-
might have start, stop, pause and play icons below a page ages/appbar.check.rest.png. In the ApplicationBarMenuItem
that displays videos. Optionally, you can have a set of menu control, set the Text property to Add Product. Also, add a Click
items that will appear below the icons when the user se- event procedure and connect both the IconButton and Menu-
lects the ellipsis on the Application Bar (Figure 3). Item controls to the same Click event procedure. Your XAML
should now look like the following:
The Application Bar
<phone:PhoneApplicationPage.ApplicationBar>
provides a place for you <shell:ApplicationBar IsVisible="True"
to put the common IsMenuEnabled="True">
tasks for a page. <shell:ApplicationBarIconButton
x:Name="icoAdd" Text="Add Product"
Windows Phone puts the Application Bar on the bottom edge IconUri="/Images/appbar.check.rest.png"
of the page when your phone is positioned in portrait mode. Click="ApplicationBarIconButton_Click"/>
When you turn your phone sideways (landscape mode) the <shell:ApplicationBar.MenuItems>
Application Bar will be either on the right or left of the page <shell:ApplicationBarMenuItem
depending on whether you turn your phone right or left. The Text="Add Product" Figure 3: The Application Bar
Application Bar will always take up the complete length or Click="ApplicationBarIconButton_Click"/>
consists of icons and a menu area.
height of the page. In addition, the height of the Applica- </shell:ApplicationBar.MenuItems>
tion Bar is fixed and cannot be changed. The Application </shell:ApplicationBar>
Bar is not a Silverlight control and thus does not support </phone:PhoneApplicationPage.ApplicationBar>
data binding on any of its properties. If you need items on
the Application Bar to change such as the Text or IsEnabled The Click event procedure you created can respond to Sample Code
property, you will need to write C# or Visual Basic code. both the icon and the menu item Click event. If you wish
to determine which one was pressed, just check the type You can download the complete
If you choose to use menus in combination with the Appli- of the sender argument. However, most often you will sample code at my website http://
cation Bar, an ellipsis will appears to the right (or below) perform the same action if the icon and the menu item www.pdsa.com/downloads. Choose
the icons. Tapping on this ellipsis will display the menus are both doing the same thing. Tips & Tricks, then “Working with
below the icons. If you select a menu or you tap outside Windows Phone User Interfaces-
of the Application Bar area, then the menus will disappear private void ApplicationBarIconButton_Click(object Part 2” from the drop-down.
from view. Menu text should be no more than 20 charac- sender, EventArgs e)
ters, though I find about 16 characters or less works best. {
if(sender is
Creating Application Bar Icons Microsoft.Phone.Shell.ApplicationBarIconButton)
tbMessage.Text = "Icon Clicked";
When you add a Portrait or Landscape page, at the very else if(sender is
bottom of the page you’ll see a commented-out section Microsoft.Phone.Shell.ApplicationBarMenuItem)
that is ready for you to un-comment and add your own tbMessage.Text = "Menu Clicked";
icons. When using Pivot or Panorama pages, an Applica- }
tion Bar is not available for you to use. You will need to
find or create your own Application Bar icons. You will
find icons located under C:\[Program Files]\Microsoft Summary
SDKs\Windows Phone\v7.x\Icons\ (where v7.x refers to
the version number of the phone SDK you have installed). While Windows Phone does not yet offer multi-tasking,
this does not mean that you cannot interact with other
To create your own set of images to use in the Applica- applications on the phone. If you wish to interact with
tion Bar, you must make them a certain way. First, they contacts or photos on the phone, you may launch those
need to be 48x48 pixels and the image portion needs to applications and either pass data to them or retrieve data
be 26x26 centered within the image. You need to use a from those applications. You will find quite an extensive
transparent background for the entire image. The image list of classes that you can use under the Microsoft.Phone.
portion should be all white or all black depending on Tasks namespace which will help you with this interac-
whether you are targeting a light or dark theme on the tion. When you need a set of tasks for a user to perform
phone. Do not draw the circle you see around each Appli- on one or many of your pages, the Application Bar is an
cation Bar icon; the Application Bar will do that for you. excellent way to present a common user interface to your
user. You may use from one to four icons and a set of
Create an Application Bar menus as well within this Application Bar. All Windows
Phone applications use the Application Bar consistently
Drag the set of icons under the C:\[Program Files]\Microsoft so your user will be familiar with its operation.
SDKs\Windows Phone\v7.x\Icons\light folder and drop them
into an \Images folder in your project. Locate the appbar. Paul D. Sheriff
check.rest.png and set the Build Action property on Content

codemag.com Working with Windows Phone User Interfaces, Part 2 17


ONLINE QUICK ID 1203041

Getting Started with RavenDB


You might have heard some things about NoSQL; how Google and Facebook are using non-relational databases to
handle their load. And in most cases, this is where it stopped. NoSQL came about because scaling relational databases
is somewhere between extremely hard to impossible. In 2007, I started getting interested in NoSQL and NoSQL

databases. I did it because it was interesting, and like Hello RavenDB


most developers, I am somewhat addicted to the notion of
faster and bigger. But something really strange happened Before I get into the theory and design guidelines behind
along the way. Instead of focusing on those things that RavenDB, I think it is best to start off by showing how
can make an application grow to a 100,000,000 users, I RavenDB works from the developer perspective.
started noticing the problems in most NoSQL solutions.
I will assume that you are using Visual Studio 2010 and
In particular, most of them were so focused on scaling you have NuGet installed. If you don’t, you can install it
or performance that little or no thought was given for from http://nuget.org/. If you need to download Rav-
Oren Eini (Ayende Rahien) things like developer productivity. That bothered me enDB, head up to http://ravendb.net and click on the
ayende@ayende.com because I could see that there are many advantages to download menu.
+972 52 548 6969 NoSQL databases that I would have loved to use, if only
http://ayende.com/blog
it wasn’t so hard to perform many of the day-to-day op- We’ll start with creating a simple console application
Twitter: @ayende erations. project, and then install the RavenDB package. In the
Package Manager Console, execute:
Oren Eini has over 15 years We have grown used to equating a database with a re-
of experience in the develop- lational database, and SQL has become one of the basic Install-Package RavenDB
ment world with a strong focus building blocks of software development. That is actually
on the Microsoft and .NET quite interesting, because in a sense, relational databas- You can also right-click the References node on the proj-
ecosystem. And he has been
es actually make it quite hard to work with them. ect and select Manage NuGet References and then search
a Microsoft MVP since 2007.
for and install the RavenDB package.
Oren’s main focus is on archi-
tecture and best practices that
The first problem most of us encounter is the impedance
promote quality software and mismatch between object-oriented modeling and rela- Along with the RavenDB package, the server is installed.
zero-friction development. tional modeling. In a relational database, you are limited You can go to PROJECT_DIR\packages\RavenDB.1.0.573\
to tables, columns and rows. In your objects, you typi- server and then execute:
An internationally known cally have properties, collections and associations. We
presenter, Oren has spoken at can map between the two, that is what object-relational Raven.Server.exe
conferences such as DevTeach, mappers are all about, but it is neither trivial nor easy.
JAOO, QCon, Oredev, NDC, Yow! You should now be able to go to http://localhost:8080
and Progressive.NET. The next issue that usually trips people up is that rela- and open the RavenDB Management Studio. Your browser
tional databases are actually optimized to work in exactly should look like Figure 1.
Oren is the author of the book the opposite way that we usually work with it. Relational
DSLs in Boo: Domain Specific databases are optimized to reduce the cost of writes at The RavenDB API
Languages in .NET, published
the expense of reads. In the vast majority of cases, the
by Manning (http://manning.
number of reads far outstrips the number of writes, but This is pretty much all the setup that we are going to
com/rahien/).
relational databases don’t work like that. It is easy to need, so lets start doing some work with it. We start by
Oren Eini is the founder of Hi- update things in a relational database because you need creating and initializing the DocumentStore:
bernating Rhinos LTD, a Israeli- to update a single row on a single table. But in order to
based company, which produces read meaningful data back, you often have to join across var documentStore = new DocumentStore
RavenDB, NHibernate Profiler multiple tables. {
and Entity Framework Profiler. Url = "http://localhost:8080"
The reason for this is quite obvious, if you cast your mind };
about 30 years into the past. At the time, the amount documentStore.Initialize();
of space it would take to hold a single album’s worth
of songs would cost about as much as the annual sal- The DocumentStore is the entry point into RavenDB. You
ary for a software developer. It made perfect sense to do typically have only one of them per application, as a sin-
anything possible to reduce the amount of data stored. gleton. The DocumentStore contains the RavenDB cache,
Besides which, it was just fine to have the user wait for optimization settings, conventions and much more.
the machine; the machine was (by far) the more expen-
sive of the two. If you are familiar with NHibernate, the DocumentStore
is very similar to the SessionFactory. And while it is the
RavenDB came out of a set of realizations. Relational da- entry point, it isn’t the main object through which you
tabases aren’t necessarily the start and end of all of our interact with RavenDB; this is what we have the IDocu-
data storage needs, that most NoSQL solutions paid little mentSession for:
if any attention to developer productivity and that there
really was no reason to limit usage of NoSQL to high- using(var session = documentStore.OpenSession())
scale projects. {

18 Getting Started with RavenDB codemag.com


// Using the session
}

The session is a transient object, usually alive for a single


operation or a web request. Like the NHibernate’s Ses-
sion or an Entity Framework’s DataContext, the RavenDB’s
Document Session is a Unit of Work. It keeps tracks of all
the loaded entities and will save them to the database
when you call SaveChanges.

Let’s just do something. For the rest of this article I will


use a restaurant-themed example. The first thing that we
are going to work with is the menu. You’ll start by defining
some classes to hold the menu:

public class Menu {


public string Id { get; set; }
public string Name { get; set; }
public List<Course> Courses { get; set; }
}
Figure 1: The RavenDB Management Studio.
public class Course {
public string Name { get; set; }
public decimal Cost { get; set; } Safe by Default
public List<string> Allergenics { get; set; }
RavenDB was intentionally
}
designed to be Safe by Default.
That is, after looking at the most
I snipped the default constructors that initializes the lists common errors that developers
to empty lists, but those are our model classes. We’ll dis- have run into when using
cuss their structure more in just a bit, but for now, let’s Figure 2: The newly created Menu document and
the Hilo document. relational databases, RavenDB
start working with them! includes specific measures to
prevent them.
session.Store(new Menu {
{ "Name": "Breakfast Menu", For example, if you don’t specify
Name = "Breakfast Menu", "Courses": [ how many items you want to
Courses = { { load in a query, RavenDB will not
new Course { "Name": "Waffle", attempt to give you all of the
Name = "Waffle", "Cost": 2.3, potential matches (which can be
Cost = 2.3m "Allergenics": [] thousands or millions), but would
}, },
add a limit on its own. Going to
the database often is usually an
new Course { {
indication of a problem in your
Name = "Cereal", "Name": "Cereal",
code (calling the database in a
Cost = 1.3m, "Cost": 1.3,
loop, usually) which has severe
Allergenics = { "Peanuts" } "Allergenics": ["Peanuts"] impact on the performance and
}, } stability of your application.
} ] RavenDB can detect and stop such
}); } actions.

What does this code do? It creates a new Menu instance with I hope that by now your curiosity is piqued. We just saved In general, RavenDB internal
two Courses and then stores them in the session. When you a fairly complex object graph into our database, and it governors ensure that your
store an object in the session, you are merely asking the ses- saved cleanly and into a single document. Think about the application will stay up, perform
sion to remember to save that instance later on, when you call implications of this for a moment. Consider what would well and not fall over after a few
SaveChanges. Until SaveChanges is called, nothing is actually happen if we were trying to work with a relational data- months in production.
going to happen. This allows RavenDB to optimize writes to base here.
RavenDB to the smallest possible number of requests.
We would have needed to define a schema (requiring four
Now you call SaveChanges: tables to store the information), find a way to tie it to our
source control history and deploy it.
session.SaveChanges();
When loading a menu, we would need to query four ta-
And you can now go to RavenDB Management Studio and bles to show a simple menu. Whereas with RavenDB, we
see the newly saved document. In fact, if you’ll look at can load it all in a single command, as you can see here:
Figure 2, you can see that there are now two of them.
using (var session = documentStore.OpenSession())
For now, we will ignore the Hilo document; I will discuss it {
in more detail later on. Let’s focus on the Menu document. var menu = session.Load<Menu>("menus/1");
Double-click it to see its content: Console.WriteLine(menu.Name);

codemag.com Getting Started with RavenDB 19


foreach (var course in menu.Courses) Course is actually part of a Menu. And this topic leads us
{ from the RavenDB API to actual modeling with RavenDB.
Console.WriteLine("\t{0} - {1}",
course.Name, course.Cost);
Console.WriteLine("\t\t{0}", Modeling with RavenDB
string.Join(",", course.Allergenics));
} By far, the most significant challenge that most people
} have when moving to RavenDB is modeling. Relational
modeling techniques have been deeply embedded in us
Here you can see another interesting benefit of using Rav- from early in our careers. And in many cases, relational
enDB. If you tried writing the same code using a relational modeling techniques are exactly the wrong ones for Rav-
database, it would suffer from the SELECT N+1 problem. For enDB and the problem at hand.
every Course in the Menu, you would issue a separate query.
Because RavenDB stores the document as a single entity, With a relational database, we are used to splitting the
you don’t have to deal with that, and you can efficiently data into many tables, into normalizing everything and
load the entire entity in just one request to the server. into shaping the data using queries on the way out.

Querying with RavenDB With RavenDB, we move the burden from the read side
(which happens a lot) to the write side (which happens far
Now that we have some information in the database, less often). We are also dealing with entities that are far
it is time for us to get that data out. We have already bigger than standard entities in relational databases. Be-
seen that we can load entities using their ids (session. cause we can store complex object graphs inside RavenDB
Load<Menu>(“menus/1”); ). But how about when we easily, we no longer need to split an entity into multiple
want to query based on the values of the entity, and not physical representations because the data store demands it.
just its id? Let’s see how we can do that:
If you are familiar with Domain Driven Design, all entities
var menus = in RavenDB are Root Aggregate, and all other values are
from menu in session.Query<Menu>() actually Value Objects.
where menu.Name.StartsWith("Breakfast")
select menu; Let’s go back to our restaurant example and look at how
we would model an order. In a relational system, the or-
This should look familiar to you; RavenDB supports LINQ der model would probably be composed of Orders, Cus-
Figure 3: An example of an order and allows you to perform complex queries on your enti- tomers, OrderLines, Products, etc.
document in RavenDB. ties without any trouble at all. For that matter, let’s see
how we can find a Menu that has a cheap course: Each of those would be a separate entity. But does it re-
ally make sense to store OrderItems outside of an Order,
var menus = or is this just an aspect of the Order? What about Pay-
from menu in session.Query<Menu>() ments on the order? As you can see in Figure 3, modeling
where menu.Courses.Any(c => c.Cost < 2) in RavenDB is quite different.
select menu;
You can see the classes for this model in Listing 1. There
That leads to an interesting observation. Using our current are a few things to note. Both OrderLine and Payment
model, we can’t really ask for a specific Course, because are embedded inside the Order. In other words, it is non-

Listing 1: A restaurant Order model


public class Order Lines.Sum(x => x.Price*x.Quantity);
{ if (tip <= 0)
public DateTime Time { get; set; } return 0;
return tip;
public List<OrderLine> Lines { get; set; } }
public List<Payment> Payments { get; set; } }
}
public bool PaidInFull
{ public class Payment
get {
{ public decimal Amount { get; set; }
return Payments.Sum(x => x.Amount) >= public string Method { get; set; }
Lines.Sum(x => x.Price*x.Quantity); }
}
} public class OrderLine
{
public decimal Tip public string Name { get; set; }
{ public int Quantity { get; set; }
get public decimal Price { get; set; }
{ }
var tip = Payments.Sum(x => x.Amount) -

20 Getting Started with RavenDB codemag.com


sensical to talk about Payment #1 or OrderLine #45; they public class Customer
don’t have a separate existence outside for their order. {
public string Id { get; set; }
That leads to some very interesting observations. First, public string Name { get; set; }
because we include those details inside the same docu- public Dictionary<string, object>
ment, accessing those details is now very cheap. Let’s Attributes { get; set; }
look at the following code snippet: }

public bool PaidInFull And we can save it to RavenDB with the following code:
{
get session.Store(new Customer
{ {
return Payments.Sum(x => x.Amount) >= Name = "Joe Smith",
Lines.Sum(x => x.Price*x.Quantity); Attributes =
} {
} {"IsAnnoyingCustomer", true},
{"SatisfactionLevel", 8.7},
This is perfectly acceptable in RavenDB; all the data is {"LicensePlate", "B7D-12JA"}
already there. In a relational database, this sort of code }
(which is quite natural and elegant) would result in two });
separate queries to the database.
So far, this is very simple. You can see the resulting docu-
Concurrency ment in Figure 4.

Another issue that no longer raises its ugly head is concur- So far, so good. But the really fun part comes when we
rency. In a relational database, the unit of concurrency want to work with it. As you can see in Figure 4, we didn’t
is the row. But we usually have to store data in multiple really care in RavenDB that this is a dynamic property. We
tables. That makes it possible to update parts of the entity just store the data, but that is just half of the job. How do
without proper concurrency control. Anyone who ever had we work with this information?
to make sure that whenever an OrderLine or a Payment is
updated, the Order is properly locked so we won’t have a As it turns out, really easily:
race condition is intimately familiar with the problem.
session.Query<Customer>()
With RavenDB we don’t have to worry about that. The .Where(x => x.Attributes["IsAnnoyingCustomer"]
unit of change is the document, and the document can .Equals(true)
contain complex objects, so changing an OrderLine or )
adding a Payment means that we don’t make any contor- .ToList();
tions with regards to concurrency control in non-trivial
scenarios. What we need to do is simply ask for optimistic This will prodouce the right results, and give us a really
concurrency, like so: nice interface to query dynamic properties without any
problem at all.
session.Advanced.UseOptimisticConcurrency = true;
Of course, I don’t recommend going that route unless you
And any call to SaveChanges will use optimistic concur- actually need dynamic properties. It is easier to work with
rency and throw a ConcurrencyException if someone went static properties, not because of any RavenDB limitation,
behind our back and changed the entities that we modi- but simply because you can use the compiler to help you.
fied.

Schemaless Data Store Indexing


RavenDB is schemaless. That means that you can store We have been working with RavenDB for a while now. We
data in any shape inside RavenDB. We usually work with have seen how we can store structured and unstructured
RavenDB using a POCO (Plain Old Clr Objects) model, data inside it, and how we can query it. But we have only
which means that we have a well-defined shape for the been working with it on a surface level.
objects we work on (at the client side), but we can also
take advantage of the schemaless nature in more explicit This is quite intentional. One of the guidelines in Rav-
ways. For example, let’s say that we want to allow users enDB’s design was that It Should Just Work. And for the
to add arbitrary data to our entities. simple CRUD tasks, which compose over 90% of our work,
this is quite enough. For the remaining few percentage
In the restaurant example, we may want to be able to add points, however, we need to go a bit deeper and discuss
things like IsAnnoyingCustomer and SatisfactionLevel to the how RavenDB actually works.
Customer entity. Not as standard properties, but just things
that the user can dynamically add to an entity on the fly. There are actually two distinct parts inside RavenDB:
storage and indexing. Storage is for actually storing
Let’s see how this works. First, we define the Customer the documents; we store them in a transactional store
entity: which is fully ACID. RavenDB ensures that when you save

22 Getting Started with RavenDB codemag.com


build an index with a known shape, and query that ef-
ficiently.

Indexing Execution and Staleness

I find this to be a very elegant solution for the problem of


dealing with unstructured data. But it is only part of what
RavenDB actually does. You are probably used to indexes
which are being updated whenever an update is made to
the database, but RavenDB doesn’t work that way.

Instead, RavenDB indexes are always being updated in


Figure 4: A customer document with dynamic attributes. the background. Whenever there is a change to the data-
base, the indexing thread wakes up and starts indexing
a document (or a set of documents) that happens in a the new updates. This allows us to significantly optimize
transaction (yes, just like in a relational database). It indexing because it allows batching several updates at
either goes all the way in or gets rolled back completely. the same time. And it also means that we don’t have to
wait for indexing to happen on every write.
Storage isn’t really interesting for external users. It
works; it supports transactions, backups and so on. But This design decision has a few interesting implications
that is pretty much it. when we start considering real-world systems. The most Safe by Default, Part II –
obvious one is that it is possible for us to query the da- Temporary Indexes
RavenDB’s indexing is a lot more interesting. RavenDB tabase after an update but before it was indexed. What You might be worried that defining
doesn’t require you to define any schema. You can store would happen then? temporary indexes is expensive
any document inside RavenDB. You can even store a Cus- and something to be avoided in
tomers/1 and Customers/2 documents with totally dif- As you can see in the diagram in Figure 6, we are going production. And you’re right.
ferent schema. But there is something that needs to add to return a reply based on what is currently indexed. That But RavenDB’s philosophy is to
some order to this mix. Putting the data in is easy, and so might be a problem, as you can imagine, because we are be Safe by Default, and it would
is getting it out when you know the document id. returning data which is not correct. make no sense whatsoever to
introduce such a useful feature
But what about querying? How can we query on such a There are several reasons why this is the case and why without considering how to use it
schemaless data set? Are all queries in RavenDB effec- for the most part, this is a good thing. As you can see in in production.
tively a “table scan” that gets progressively slower as the Figure 6, we don’t just return the wrong information. We
database grows? return the information that we have at hand and tell you The Query Optimizer will monitor
that it is stale. all temporary indexes, and if they
In a word: No! aren’t being used, they will be
This is important. By moving all indexing to a background removed after a short period. But
what if they are used? The Query
RavenDB supports the notion of indexes, but while they task, we are able to complete write requests much faster,
Optimizer keeps them around,
serve some of the same purposes as indexes in a relation- and batch all the indexing updates together. And be-
and if they are used enough, it’ll
al database, they are actually quite different. RavenDB cause we tell you that the information might be stale, promote the temporary index into
supports exactly two ways to query the data: you now have the choice of what to do about it. a permanent one.

1. Loading a document (or documents) by id. For a surprisingly large number of cases, returning stale This way you don’t really have
2. Querying an index. information is perfectly fine. Just consider everywhere to worry about defining most
were you have ever applied caching. In those cases, you indexes ahead of time. You can let
But what is an index? Here you go: were explicitly deciding to return potentially stale infor- RavenDB create and manage them
mation for the user in order to increase performance. for you. It will do the right thing.
from customer in docs.Customers
select new { customer.Name }; Along with reporting whether a response is stale or not,
we report how stale it is. You can see a full example in
This is a RavenDB index, indeed. “Wait!” I can hear you say, Listing 2 where we show how you can get the statistics
“This isn’t an index, this is a LINQ statement.” It is both. for a request and make a decision based on the informa-
tion provided there.
The way indexes in RavenDB work, you construct a
LINQ statement and hand it over to RavenDB. RavenDB Finally, remember that RavenDB is composed of two ma-
will then execute this LINQ statement on a background jor components. Indexes can be stale, but documents
thread, finding all the Customers in the database and never are. That means that if you make a request by id,
projecting out their names. We can then take the names you are guaranteed never to get old information.
and store them in an index.

In fact, as you can see in Figure 5, because RavenDB can


store arbitrary data, we need something else that will
provide some structure for us.

The indexes provide us with this structure. Because a


LINQ statement has a well-defined result type, we can Figure 5: Indexes brings structure to RavenDB.

codemag.com Getting Started with RavenDB 23


Dynamic Indexes the query. This is how RavenDB implements its ad-hoc
queries capabilities.
You might have been wondering something by now. I said
that you can only query RavenDB using an index, so how Please see the sidebar about temporary indexes for ad-
come we can do things like this? ditional discussion for how temporary indexes are man-
aged. The short of it is that this is a production-ready
session.Query<Customer>() feature, and it saves quite a lot of work, because you
.Where(x => x.Attributes[“IsAnnoyingCustomer”] don’t have to define indexes ahead of time. RavenDB will
.Equals(true) create and manage them for you.
)
.ToList(); Static Indexes

You might wonder if I pre-defined an Since RavenDB can create indexes for us on the fly, do
index behind your back. Well, no, not you want to define your own static indexes? The answer
really. What we actually did is ask Rav- is, as you might have imagined, yes.
enDB to query all Customers’ documents
where Attributes.IsAnnoyingCustomer Static indexes are useful in any number of scenarios, from
is equal to true. And because we didn’t full text searches to geo-spatial queries, from map reduce
explicitly specify an index, what hap- operations to event sourcing. I don’t have the space in
pens is that the query goes to RavenDB this article to cover static indexes in enough depth (that
and it is up to the Query Optimizer to can be an article or two all on its own), so I would just
decide what indexes is going to handle say that proper use of indexes can make your RavenDB
this query. applications shine.

And what happens if there is no match-


ing index? Let’s look at Figure 7 for an Summary
answer.
One of the parts that is the most fun in building RavenDB
What is this index? Well, that is what applications is the attention given to actually making
happens when the Query Optimizer things works properly. All too often you see products that
can’t find a matching index; it will cre- are truly awe inspiring, as long as you use them for a demo.
Figure 6: Diagram of a stale response to a query. ate a temporary index that can answer
RavenDB took the approach that you can be a truly awe-
some product and still be something that doesn’t require
a lot of tweaks to go to production.

I previous mentioned the notion of Safe by Default. Rav-


enDB will actively monitor itself and stop and prevent
misuses that could take down your applications early on.
Having a safety net to catch you if you don’t notice that
you missed something is quite nice.

In this article I have really been only able to touch Rav-


enDB on the very surface. I have shown you how to do
Figure 7: A temporary index, created by the query optimizer. basic CRUD operations with RavenDB, a bit about the de-
sign approach and how indexes work.

Listing 2: Working with stale indexes There is a lot more to learn and do. RavenDB supports
sharding, map reduce, spatial queries, replication and
RavenQueryStatistics stats;
much more. It has a fully async API and is available for
var queryable = session.Query<Customer>()
Silverlight as well.
.Statistics(out stats)
.Where(x => x.Attributes["IsAnnoyingCustomer"].Equals(false));
You can read more about it at http://ravendb.net or join
var customers = queryable.ToList(); the discussions about it in the mailing list http://groups.
google.com/group/ravendb/

Console.WriteLine("Stale: {0}", stats.IsStale); Oren Eini


Console.WriteLine("Last update: {0}", stats.IndexTimestamp);

if((DateTime.UtcNow - stats.IndexTimestamp).TotalSeconds > 10)


{
// too old, we want to wait for indexing
queryable.Customize(x => x.WaitForNonStaleResultsAsOfNow());

customers = queryable.ToList();
}

24 Getting Started with RavenDB codemag.com


FROM THE PRODUCERS OF CODE MAGAZINE

Vancouver Chicago Boston

New York
Los Angeles

Philadelphia

es:
Phoenix Includ out
All Abws 8!
o
Dallas Wind
Houston

A Free Afternoon of .NET Insider Know-How!


Join Microsoft Regional Director, MVP, and publisher of CODE Magazine State of .NET events are generally held with Microsoft’s support, but the
Markus Egger, for an afternoon of free and independent information about content is independently produced and not influenced by other parties. State
current development technologies! Our network of CODE Magazine, CODE of .NET events provide beefy content for developers and decision makers
Consulting, and CODE Training experts are producing this well established without marketing fluff. Best of all, thanks to our sponsors, it is free of charge!
series of events with the purpose of taking a look at the current state of Also take a look at recordings from prior events at www.StateOfDotNet.com.
.NET. Which of the many .NET technologies have gained traction? Which
ones can you ignore for now? What’s new in .NET and what will be added in See more details at: www.StateOfDotNet.com
the near future? What other Microsoft technologies should you include in
your development efforts or consider for future planning?

The goal of the State of .NET events is to share our extensive experience.
Due to our efforts around CODE Magazine, CODE Consulting, CODE Training,
and our community involvement, we are in a unique position to see a
larger number of real-world projects than anyone else in the industry.
Our relationship with Microsoft provides us a behind-the-scenes look. In
combination, this results in a unique position, and as a content provider,
we are eager to share this information. An EPS Event
ONLINE QUICK ID 1203051

The Baker’s Dozen Doubleheader:


26 New Features in SQL Server 2012
(Part 1 of 2)
When I was a kid, I loved baseball. I lived it 24/7. In the summertime, happiness meant a pickup game
during the day and a Phillies doubleheader at night. I’m still a kid at heart and I still love baseball – and I also
love SQL Server. And right now, happiness means seeing all the cool new features in SQL Server 2012. There

are so many of them that I can’t list them in a single The examples use the AdventureWorks2008R2 OLTP da-
article. So, I’m penning a two-part Baker’s Dozen. The tabase. (As of this writing, the AdventureWorks OLTP
first part of this “twin-bill” (yes, expect a few baseball database hasn’t yet been updated for SQL Server 2012).
analogies!) will be 13 new T-SQL and database engine You can find AdventureWorks2008R2 on the CodePlex
features in SQL Server 2012. The “night-cap” in the next site: http://msftdbprodsamples.codeplex.com/releases/
issue will be 13 new features in SQL Server Integration view/55330.
Services and the new Business Intelligence Semantic
Model. Tip 1: The Baker’s Dozen Spotlight: The New
Columnstore index
Kevin S. Goff
Kgoff@KevinSGoff.NET Starting Lineup for Game 1 Over the last 3-5 years, many companies have sent a
Kevin S. Goff has been a SQL clear message that they view Microsoft SQL Server as a
Server MVP since 2010, and Normally, in Baker’s Dozen tradition, I say, “What’s on viable option for large database applications. No longer
was a C# MVP from 2005-2009. the menu?” This time I’m saying, “The starting lineup is just a “database server for medium-size companies,”
He is currently a full-time SQL as follows!” SQL Server has become the database of choice for
Server/Business Intelligence companies like WiPro Technologies (2nd largest IT
Practice Manager for SetFocus, • Leading off, the Baker’s Dozen Spotlight: The new company in India), Arcelik (one of Europe’s largest
LLC, a Microsoft Certified Part- Columnstore index in SQL Server 2012, which can manufacturers), and Clalit Health Services (Israel’s
ner for Learning Solutions. provide dramatic performance improvements in largest HMO) – all of whom have converted Oracle/SAP
many data warehousing scenarios Systems to SQL Server.
• Batting second, the new SSDT environment
• Batting third, the new sequence generator object But Microsoft hasn’t rested on the laurels that have
• Batting fourth, the new Lag and Lead functions helped it achieve a more “prime-time” status: they
• Batting fifth, the Baker’s Dozen Potpourri: the new continue to augment their flagship database product.
Percentile window functions One can plainly see that in the Parallel Data Warehouse
• Batting sixth, the new Fetch language feature for appliance that scales to petabytes (http://msdn.micro-
paging result sets soft.com/en-us/library/ee730351.aspx). One can also
• Batting seventh, the new EXECUTE…WITH RESULTS see it in the topic of this first tip: the new Columnstore
for extending the use of stored procedure result sets index that can increase the performance of data ware-
• Batting eighth, the new IIF feature house queries by anywhere from 10-100 times.
• Batting ninth, the new TRY…CONVERT feature
Article Project File • Batting tenth (yes, I realize there are only 9 players The new Columnstore index groups and stores data for
on a team), a set of new date and DateTime functions each column and then join all columns to build the
You can find the entire source • Batting eleventh, the new THROW statement to index. (By contrast, regular indexes group and store
code and project file on my throw an error data for each row and then join all the rows to build the
website at www.KevinSGoff.net, • Batting twelfth, two new string and formatting index.) Here are the major attributes of the Columnstore
in the download area. functions index (with an example to follow):
• And last but not least, the new FileTable feature
• Based on Microsoft’s Vertipaq technology that’s
Enhancements in Batter Up! The Demo Database for the Examples used in Microsoft PowerPivot – a highly com-
SQL Server 2012 pressed index, more compressed than a non-clus-
Each new version of SQL Server As I am writing this article (early January 2012), SQL tered covering index.
always provides some exciting new Server 2012 is in a release candidate status, which • Very easy to create (same syntax as an existing
functions. A data warehousing generally means that the product is beyond the beta/ index, but with the Columnstore keyword).
professional will definitely look technology preview status and that a formal release to • It is a read-only index: meaning that once you
forward to the new Columnstore manufacturing (RTM) is next. At the PASS Summit in create it, SQL Server will not maintain it when
index, which offers query October 2011, Microsoft announced that SQL Server 2012 you subsequently insert new rows to the table.
performance boosts of anywhere was on schedule for a formal release in the first half of This makes Columnstore indexes useful for data
from 10-100 times! 2012. warehousing scenarios (where data is loaded on

26 The Baker’s Dozen Doubleheader: 26 New Features in SQL Server 2012 (Part 1 of 2) codemag.com
Figure 1: Results of processing time with Columnstore index.

a schedule), not for OLTP systems (data inserted


constantly).
• Utilizes read-ahead reads in IO statistics (SQL
Server reading data into memory cache as a sepa-
rate thread).
• Potentially dramatic effect on query performance
– sometimes by a factor of 100x.
• Can handle all data types except varbinary, Figure 2: Execution plan for Figure 3: Execution plan for
varchar(max), hierarchyid, timestamp, uniquei- Columnstore index. nonclustered covering index.
dentifier, sqlvariant, xml, image, text. In addition,
no filtered indexes, no computed column. an index seek might not take as much advantage of a
• Has been described as a “covering index on mas- Columnstore index as a query that retrieves a greater
sive steroids.” portion of data.
• Can only have 1 covering index per table.
• Less IO; more can be stored in memory. For an example, I’ve created a script (Listing 1) to create
• Uses new batch execution mode in SQL Server a 10 million row table – not as large as a production
2012. data warehouse, but certainly not a peanut database
either. Listing 2 shows the creation of a Columnstore
Some people look at the IO statistics from a Columnstore index and a query with a basic join and aggregation.
index and wonder if a Columnstore index will always Figures 1 through 3 show the performance differences
perform better than a covering index. Often it will – # of reads, execution time – between scenarios of a
depend on the selectivity of the query. A query that clustered index, a covering index and a Columnstore
retrieves a very small percentage of the data using index.

Listing 1: Script for new Columnstore index


use AdventureWorks2008R2 (PurchaseOrderID int identity primary key, VendorID int,
go OrderDate Date, TotalDue money)

set nocount on ; declare @RowCounter int = 1, @VendorRow int,


@TotalDue money, @VendorID int, @DateCounter int = 1
if exists( select * from sys.sysobjects
where id = object_id('dbo.GetRandomInteger') ) while @RowCounter <= 100000000
drop procedure dbo.GetRandomInteger begin
go exec dbo.GetRandomInteger 1,104, @VendorRow OUTPUT
exec dbo.GetRandomInteger 100, 10000, @TotalDue OUTPUT
create procedure dbo.GetRandomInteger exec dbo.GetRandomInteger 1, 1095, @DateCounter OUTPUT
@minRandomValue int, @MaxRandomValue int, set @VendorID =
@ReturnValue int OUTPUT (SELECT BusinessEntityID from
as (select BusinessEntityID,
SET @ReturnValue = ROW_NUMBER() OVER (ORDER BY BusinessEntityID)
(SELECT CAST(((@maxRandomValue + 1) - @minRandomValue) as RowNumber
* RAND(CHECKSUM(NEWID())) + @minRandomValue from Purchasing.Vendor) TempVen
AS INT) ) where RowNumber = @VendorRow)
RETURN @ReturnValue insert into dbo.BigPurchaseOrderHeader
go (VendorID, OrderDate, TotalDue)
values (@VendorID,
if exists( select * from sys.sysobjects dateadd( d, @DateCounter, '1-1-2005'),
where id = object_id('dbo.BigPurchaseOrderHeader') ) @TotalDue)
drop table dbo.BigPurchaseOrderHeader set @RowCounter = @RowCounter + 1
end
create table dbo.BigPurchaseOrderHeader

codemag.com The Baker’s Dozen Doubleheader: 26 New Features in SQL Server 2012 (Part 1 of 2) 27
Listing 2: Query to test performance
set statistics io on -- Now Create ColumnStore Index and re-run query
set statistics time on CREATE NONCLUSTERED COLUMNSTORE INDEX [IX_BPO_ColumnStore]
ON [BigPurchaseOrderHeader]
select Vendor.Name, SUM(TotalDue) as TotDue (VendorID, TotalDue)
from Purchasing.Vendor GO
join dbo.BigPurchaseOrderHeader BPO on
Vendor.BusinessEntityID = BPO.VendorID
group by Vendor.Name -- Now drop Columnstore and try a non-clustered
-- covering index
-- Results of query performance in Figure 1: (this reads
-- across 10,000,000 rows -- Performance is better than a clustered index but still
-- not as good as a Columnstore index

Listing 3: New Sequence generator


use adventureworks2008r2
go if exists(select * from sys.objects
where object_id = object_id('MyTest') )
if exists(select * from sys.objects where drop table MyTest
object_id = object_id('DemoSequence') )
DROP SEQUENCE [dbo].[DemoSequence] CREATE TABLE MyTest (SequenceValue int, Name varchar(50))
go

CREATE SEQUENCE DemoSequence


START WITH 1 insert into MyTest values
INCREMENT BY 1; (next value for DemoSequence, 'Kevin Goff')

SELECT NEXT VALUE FOR DemoSequence -- Gives us 2


-- Gives us 1

The performance numbers show that, indeed, Microsoft (NOTE: SSDT was previously known as code-named
“hit the ball out of the park” with Columnstore indexes. “Juneau.”)
This is one of the most significant enhancements in the
history of SQL Server with regards to data warehouse You can read more about SSDT here: http://msdn.microsoft.
query performance!!! com/en-us/data/gg427686.

Tip 2: The New SSDT (SQL Server Data Tools) Tip 3: New Sequence Generator Object
Environment
Have you ever wanted a table-independent identity
One of the frustrations of SQL Server and Business generator? Other databases (e.g. Oracle) have had a
Intelligence Developers has been the lag of Business sequence generator to produce a new integer identity on
Intelligence Development Studio (BIDS) with respect to demand, without association to a specific table. Imagine
Visual Studio. Additionally, developers working in BIDS a scenario where you could create an integer value for
often need to ALT-TAB back and forth with SQL Server every row in every table, where the value is unique across
Management Studio. tables – and without the complexity of a uniqueidentifier.

SQL Server 2012 contains a new sequence generator


The new sequence generator database object that performs this very task (Listing 3).
object in SQL Server 2012 allows
database administrators to have a Tip 4: The New Lag and Lead Functions
table-independent factory: one that
In the last few versions of SQL Server, Microsoft has
produces an integer value that will be implemented T-SQL language features that have an OLAP
unique across every table/row in the “feel” to them. For instance, GROUPING SETS in SQL
database. This effectively creates the Server 2008 allow SQL developers to produce multiple
equivalent of a uniqueidentifer levels of subtotals from a query. And going back further,
SQL Server 2005 introduced the RANK family of functions
within a database. to assign a sequential ordering number “across” a set (or
“window”) of rows. Many of these functions are ones you
Fortunately, SQL Server 2012 comes with a tool called can find in the MDX programming language that’s used
SQL Server Data Tools (SSDT), an integration environment with OLAP databases.
that allows developers to work with Visual Studio and BI
projects AND also access many of the capabilities that SQL Server 2012 introduces two new functions that
were previously found in SQL Server Management Studio. have similar functionality in MDX: Lag and Lead. For

28 The Baker’s Dozen Doubleheader: 26 New Features in SQL Server 2012 (Part 1 of 2) codemag.com
FROM THE PRODUCERS OF CODE MAGAZINE

shu ters
shut ers tockk
rstock
Mobile Development from the
Most Trusted Source in .NET!
Looking for a company who can help you with your mobile platform projects, provide man-power and know-how,
and reduce your overall risk?

CODE Consulting is your perfect partner! It is difficult to ignore the growing demand for applications that run on mobile devices like
smart phones and slate devices, but you don’t have to venture into this new technology alone. CODE Consulting is here to help you develop
your mobile applications on Android, iOS (iPhone/iPad/iPod), Windows Phone, WebOS, and more. CODE Consulting provides a wide
range of services for every need and scale, from mentoring your team to make sure your mobile project is on track, to the complete design
and development of your mobile application.

CODE Consulting is the consulting, development, and custom software arm of CODE Magazine. We have access to the most extensive network
of experts through both in-house staff, as well as a vast network of CODE authors, trainers and consultants, MVP and RD networks, and
community involvement. At CODE Consulting, we work with technologies and standards like .NET, Java, Objective-C, HTML, CSS, JavaScript,
Silverlight, SOA, and much more.

See more details at: www.codemag.com/consulting CONSULTING


An EPS Company
instance, suppose you are generating a result set of order by OrderYear, OrderMonth)
sales by month – and for any one row, you wish to show as dollarsLastMonth,
sales for the prior month (the “lagging” month) and
the next month (the “leading” month). Figure 4 shows Listing 4 contains a complete example using LAG and
an example of a result set that shows sales by month, LEAD, with the result set in Figure 4.
along with the sales for the prior month and the next
month. Listing 4 contains a complete example of LAG Tip 5: Baker’s Dozen Potpourri: the New Percentile
and LEAD, which both operate similar to the existing Window functions
RANK function that generates a scalar value “over” a set
of rows in a particular order. If the LAG and LEAD functions weren’t enough, Microsoft
added several new functions for determining different
The last few versions of percentile and median calculations. While not every SQL
developer will use this – anyone looking to generate
T-SQL have contained new language analytic statistics against relational data will find these
features designed to provide additional functions a major hit – a solid double off the outfield
analytic capabilities. Grouping Sets, wall.
LAG/LEAD, and Percentile Functions all
From my own perspective, I welcome some of the new
give SQL developers better ways to functions that will eliminate the need for workarounds
work with data. that sometimes spark protracted discussions. For in-
stance, SQL Server does not contain a mathematical
lag( SumTotalDue, 1, 0) over median function, which is often necessary to calcu-
(partition by ShipMethodID late a “middle score/middle observation” that isn’t

Figure 4: Results of Lag and Lead.

Figure 5: Output for new Analytic Percentile functions.

Listing 4: New Lag and Lead functions


use AdventureWorks2008R2 select ShipMethodID, OrderMonth, OrderYear, OrderMonth,
go SumTotalDue,
lag( SumTotalDue, 1, 0) over
;with TempCTE as (partition by ShipMethodID
(select ShipMethodID, Month(OrderDate) as OrderMonth, order by OrderYear, OrderMonth)
year(OrderDate) as OrderYear, as dollarsLastMonth,
datename(m,OrderDate) as OrderMonthName, lead(SumTotalDue, 1, 0) over
sum(TotalDue) as SumTotalDue (partition by ShipMethodID
from Purchasing.PurchaseOrderHeader order by OrderYear, OrderMonth)
where year(OrderDate) = 2006 as dollarsNextMonth
group by ShipMethodID, from TempCTE
Month(OrderDate),year(OrderDate), order by ShipMethodID,TempCTE.OrderYear,
datename(m,OrderDate) ) TempCTE.OrderMonth

30 The Baker’s Dozen Doubleheader: 26 New Features in SQL Server 2012 (Part 1 of 2) codemag.com
Listing 5: New Percentile functions
USE AdventureWorks2008R2 order by sum(TotalDue) desc) as Rank ,
GO ROUND(PERCENT_RANK() over
-- PercentRank = (Rank minus 1 ) / (TotalRows - 1) (partition by CreditRating
order by sum(TotalDue) desc) * 100,4) as PctRank ,
-- Percentile_Cont = Median ( between 0 and 1, .5 for middle score) ROUND(CUME_DIST() over
(Partition by CreditRating
-- Cumulative distance = # of rows higher/lower than lowest value order by sum(TotalDue) desc),4) as Cumul_Dist,
-- / # of total rows ROUND(PERCENTILE_CONT(.5) within group
(order by sum(TotalDue) desc)
over (partition by Vendor.CreditRating) ,2)
select Vendor.Name as VendorName, CreditRating as Rating, as Median_Interpolate,
ROUND(sum(TotalDue),2) as VendorTotal, ROUND(PERCENTILE_DISC(.5) within group
(order by sum(TotalDue) desc)
ROUND(First_Value (sum(TotalDue)) over (partition by Vendor.CreditRating) ,2)
over (Partition by CreditRating as Median_Actual
order by sum(TotalDue) ),2) as VendorLow,
ROUND(Last_Value (sum(TotalDue) ) from Purchasing.PurchaseOrderHeader
over (Partition by CreditRating join Purchasing.Vendor on BusinessEntityID = VendorID
order by sum(TotalDue) where CreditRating = 3
RANGE BETWEEN CURRENT ROW AND UNBOUNDED group by Vendor.Name, CreditRating
FOLLOWING ),2) as VendorHigh, order by CreditRating, VendorTotal desc
rank() over (partition by CreditRating

Listing 6: New Fetch feature for Paging result sets


use AdventureWorks2008R2 BzID AccountNumber Name RowNum
go 1530 COMFORT0001 Comfort Road Bicycles 21
declare @PageNumber int =3 1508 COMPETE0001 Compete Enterprises, Inc 22
declare @RowsPerPage int = 10 1694 COMPETE0002 Compete, Inc. 23
1624 COMPETIT0001 Competition Bike Training Systems 24
select BusinessEntityID, AccountNumber, Name, 1548 CONSUMER0001 Consumer Cycles 25
ROW_NUMBER() OVER (ORDER BY Name) as RowNum 1598 CONTINEN0001 Continental Pro Cycles 26
from Purchasing.Vendor Order by Name 1658 CROWLEY0001 Crowley Sport 27
offset (@PageNumber-1) * @RowsPerPage rows 1536 CRUGERB0001 Cruger Bike Company 28
fetch next @RowsPerPage rows only 1568 CUSTOMF0001 Custom Frames, Inc. 29
1502 CYCLING0001 Cycling Master 30
-- Results (Page 3 would show rows 21 through 30)

impacted by outlier conditions. In my Baker’s Dozen performance. Fortunately, SQL Server 2012 provides two
article in the November/December 2011 issue (QuickID new functions (PERCENTILE_CONT and PERCENTILE_
1112061), I showed a workaround for calculating a DISC) to natively handle a median calculation.
median average by assigning a row number and then
averaging the middle values (which would be 1 value Figure 5 shows a screen shot for a result set that shows
for an odd number of rows and 2 values for an even seven vendors, ranked by their sales dollars. See Listing
number of rows). 5 for a new code example, plus Figure 5 for the screen
shot.
DECLARE @NumObservations int = @@ROWCOUNT
• First_Value – provides the first value (thus the name)
;WITH ScoreCTE AS ( across a set of rows, based on a particular order
SELECT Id, Score, • Last_Value – provides the last value across a set of
ROW_NUMBER() OVER (ORDER BY Score) rows, based on a particular order, with the option
AS ScoreRank of specifying a “between” range
FROM @StudentScore) • PERCENT_RANK – the percentage of rows/values
in the range/window (“distribution”) of rows that
SELECT AVG(Score) AS Median FROM ScoreCTE are the same or lower than the current row. For ex-
WHERE ( ScoreRank IN ample, in Figure 5, the vendor Federal Sport has a
((@NumObservations+1)/2, percentile rank of 33.33%. That means that 33% (2
(@NumObservations+2)/2) ) rows) of the total number of other rows (6 rows)
have a sales dollar amount lower than vendor Fed-
While this type of code works, it’s usually better for a eral Sport.
software product to provide a native function, providing • CUME_DIST – similar to the Percentile Rank func-
the native function provides good functionality and tion in the example in Figure 5, the ranking for

codemag.com The Baker’s Dozen Doubleheader: 26 New Features in SQL Server 2012 (Part 1 of 2) 31
Vendor Federal Sport (3) divided by the total num- certain functions, but others don’t. Take, for instance,
ber of rows (7) (i.e., .4286). This number repre- the IIF function. It exists in MDX and in SSRS, but not
sents the relative position of the vendor with re- T-SQL….
spect to the total number of rows.
• PERCENTILE_CONT and PERCENTILE_DISC, for all Until now!!!
intents and purposes, both calculate the median
score/value (i.e., “middle score”), over a set of SELECT IIF(CreditRating=1,'Good Credit Rating',
rows. In Figure 5, the middle vendor dollar amount 'Bad Credit Rating')
is Inner City Bikes with sales of $27,308.61. In this AS CreditMessage, Name
scenario, with an odd number of vendors in Figure FROM Purchasing.Vendor
5, both functions return the same value. However,
had the number of vendors in Figure 5 been an Tip 9: The New TRY…CONVERT and TRY…PARSE
even number (such as 8 vendors), the PERCEN- Features
TILE_CONT function would calculate/interpolate a
median by taking the straight average of vendors If you follow baseball closely, you know that some hitters
4 and 5. in the lineup contribute not by hitting home runs, but
by getting the “little things done” (like laying down a
Tip 6: New Fetch Language Feature for Paging bunt, or hitting into an out that advances another base
Result Sets runner).

When Microsoft introduced the new ROW_NUMBER func- Well, SQL Server 2012 has a few of these types of “role
tion in SQL Server 2005, developers used it (in conjunc- players” that, while not huge features, can certainly help
tion with the new common table expression capability) to a team out. For instance, have you ever wanted to parse
generate an internal row number for paging result sets. a value to see if it’s a valid date?
While this worked quite well, it meant using either a sub-
query or common table expression, since a ROW_NUM- SELECT IIF(
BER (windowing) function cannot be used in the WHERE TRY_CONVERT(date, '02/29/2010') is NULL,
clause. 'Invalid Date', 'Date')
AS TestDateResult
SQL Server 2012 now contains a new set of statements:
offset and fetch next. SELECT TRY_PARSE( 'cannot be a number' as int)
AS result1,
OFFSET (@PageNumber-1) * @RowsPerPage ROWS TRY_PARSE( '100' as int)
FETCH NEXT @RowsPerPage ROWS ONLY AS result2

See Listing 6 for the full code example, which retrieves N Tip 10: A Set of New Date and DateTime Functions
number of rows based on page number Y (where both N
and Y are variables). Listing 6 also contains the sample Another nice “utility player” in the Microsoft line-up is
output. the new set of date and DateTime functions.

Tip 7: The New EXECUTE…WITH RESULTS For instance, creating a new date is as simple as using
the new function DATEFROMPARTS:
Have you ever wanted to rename the columns from a
stored procedure result set? Listing 7 shows an example SELECT DATEFROMPARTS( 2011, 12, 24) AS NewDate
of the new EXECUTE WITH RESULTS statement, which
allows you to rename the columns from a result set. SELECT datediff(mi,
DATETIMEOFFSETFROMPARTS
Tip 8: The New IIF Feature (2011, 01, 8, 8, 00, 00, 0, -5, 0, 7 ) ,
DATETIMEOFFSETFROMPARTS
As an instructor, I sometimes have challenges in teaching (2011, 01, 8, 10, 30, 00, 0, -8, 0, 7 ))
students that certain Microsoft languages/tools have As MinutesDiff

Listing 7: EXECUTE with RESULTS


use AdventureWorks2008R2 select BusinessEntityID as VendorID, Name as VendorName,
go CreditRating
from Purchasing.Vendor
if exists(select * from sys.objects where object_id =
object_id('dbo.GetVendors') ) go
drop procedure dbo.GetVendors
go exec dbo.GetVendors with result sets
(
( VendorID int,
create procedure dbo.GetVendors VendorName varchar(50),
as CreditRating2 int))

32 The Baker’s Dozen Doubleheader: 26 New Features in SQL Server 2012 (Part 1 of 2) codemag.com
This next one is a personal favorite of mine: the ability GO
to determine the last day of a month, using the new EXEC dbo.ThrowTest
EOMONTH function:
This further improves error-handling scenarios in SQL
DECLARE @date DATE Server 2012.
SET @date = getdate()
SELECT EOMONTH ( @date ) AS Result; Tip 12: New String and Formatting Functions

Tip 11: New Ability to Throw an Error Suppose you’re working with an international application,
and need to display currencies in different country
In SQL Server 2005, Microsoft made tremendous strides in currency formats (such as the output in Figure 6, which
exception handling with the implementation of TRY-CATCH. uses the different currency symbols).
This allowed SQL developers to build more robust stored
procedures with transactions and better error handling. SQL Server 2012 contains a new capability in the FORMAT
function to render currency in different formats:
Part of the improved methodology in SQL Server 2005
was the ability to raise an error “politely” (using DECLARE @Dollars MONEY = 1412.95
RAISERROR) back to the calling application. However,
this introduced one complication: it changed the error SELECT
line number. FORMAT(@Dollars,'c','en-US') [US],
FORMAT(@Dollars,'c','it-IT') [Italy],
Fortunately, Microsoft has further refined this capability FORMAT(@Dollars,'c','fr') [France],
by allowing developers to “throw” the same error that FORMAT(@Dollars,'c','ar-SA') [Arabic],
was “caught” to begin with: FORMAT(@Dollars,'c','ja-JP') [Japan]

CREATE PROCEDURE dbo.ThrowTest Tip 13: New FileTable


as
BEGIN Many years ago, I worked on a major application that
BEGIN TRY managed scanned images for verification of a business
SELECT 1/0 process. The application stored images in the file
END TRY system (i.e. “outside the database”), with database
BEGIN CATCH references to the external file names. I felt very
THROW strongly after the experience that images and any
END CATCH other binary content belonged outside the database,
END with custom references inside the database to the
content

Over the years I’ve (stubbornly) held to that view, even


after Microsoft introduced the FileStream capability in
SQL Server 2008. However, Microsoft has introduced a
Figure 6: Currency formats. feature in SQL Server 2012 that has led to an apostasy

Figure 7: Images in a folder linked to a SQL Server FileTable.

Figure 8: Contents of the FileTable corresponding rows in SQL Server.

codemag.com The Baker’s Dozen Doubleheader: 26 New Features in SQL Server 2012 (Part 1 of 2) 33
Listing 8: New FileTable
EXEC sp_configure filestream_access_level, 2
RECONFIGURE --The sys.database_files shows 3 file types - for the data file,
Go -- the log file, and the FILESTREAM
SELECT * FROM sys.database_files
USE MASTER Go
GO
--go back to master
IF DB_ID ('FileTableExampleDB') IS NOT NULL USE MASTER
DROP DATABASE FileTableExampleDB GO
GO
-- Set the non-transaction access level and directory name

CREATE DATABASE FileTableExampleDB ON PRIMARY ALTER DATABASE FileTableExampleDB


( SET FILESTREAM ( NON_TRANSACTED_ACCESS = FULL,
NAME = FileTableExampleDB, DIRECTORY_NAME = N'FileTableExampleDB')
FILENAME =
'E:\Program Files\Microsoft SQL Server\' + GO
'MSSQL11.SQL2012STANDARD\MSSQL\DATA\FileTableExampleDB.mdf'
), SELECT DB_NAME ( database_id ), directory_name
FILEGROUP FileTableExampleDB_FileGroup CONTAINS FILESTREAM FROM sys.database_filestream_options
( where directory_name is not null
NAME = FileTableExampleDB_FileGroup,
FILENAME = 'E:\Program Files\Microsoft SQL Server\' +
'MSSQL11.SQL2012STANDARD\MSSQL\DATA\FileTableExampleDB' USE FileTableExampleDB
) GO
LOG ON --Create the FileTable
( CREATE TABLE tblFileTableBaseballLogos AS FileTable
NAME = FileTableExampleDBLog, WITH
fILENAME = 'E:\Program Files\Microsoft SQL Server\' + (
'MSSQL11.SQL2012STANDARD\MSSQL\DATA\FileTableExampleDB.ldf' FileTable_Directory = 'tblFileTableBaseballLogos',
) FileTable_Collate_Filename = database_default
GO )
GO
USE FileTableExampleDB SELECT * FROM tblFileTableBaseballLogos
GO

for me (and probably others) with regards to this topic. DELETE FROM [dbo].[tblFileTableBaseballLogos]
The feature is called FileTable.
Next Time Around in the Baker’s Dozen
The SQL Server FileTable is a mechanism that allows
you to map a folder/file system structure to a special In the “night-cap” of this Baker’s Dozen doubleheader
database table, where SQL Server maintains a (i.e., in the next issue), I’ll cover the new features in SQL
relationship dynamically. Yes, it’s that simple. (FileTable Server 2012 Integration Features. SSIS has always been
builds on the concept of the FileStream object from SQL a good tool for ETL development, though certain aspects
Server 2008). Listing 8 shows an example of creating of the tool have had “opportunities for improvement.”
a FileTable database, with a table that synchronizes a Microsoft meticulously re-crafted many aspects of SSIS
folder of images. The listing does the following: in SQL Server 2012. As a result, a good tool just got much
better. Stay tuned!
• Configures the instance of SQL Server for FileStream
access Kevin S. Goff
• Creates an empty database FileTableExampleDB
with FileStream capabilities
• Alters the new database and sets a FileStream di-
rectory name reference
• Creates a table with a reference to a specific direc-
tory (in this case, a folder that will hold images)

This means I can load the folder with images (Figure 7), and
have a corresponding table (tblFileTableBaseballLogos)
that’s associated with the images (Figure 8).

And most important, I can also issue standard DML


statements against the table in SQL Server, and it will
affect the contents of the folder!

34 The Baker’s Dozen Doubleheader: 26 New Features in SQL Server 2012 (Part 1 of 2) codemag.com
FROM THE PRODUCERS OF CODE MAGAZINE

Code Training 4 Seiten

g 2 012
Sprin dule
Sche

Training from the Most Trusted


ow !
Source in .NET! g up Si e y ou r
Brought to you by the experts at CODE Magazine
Sec u r ou t!
rd d i sc
early-bi
Scheduled Training Classes
On-site and online
Classes include videos, slides and code samples
Custom classes tailored to your needs
Training at your location for your team

See more details at: www.codemag.com/training TR AINING


An EPS Company
CODE Training Spring 2012
e
Go o li etail
CODE Training, CODE Magazine’s training division, offers standard classes scheduled at regular intervals, as well as
d
custom training classes taught at our customer’s offices (see below for details). Standard training classes can be
for ore class!
o each
attended on-site in Houston, as well as online. We record all classes and make the recordings available to attendees as
downloadable videos. Attendees also receive code samples, slides and other collateral.

Scheduled Classes
The following classes are currently scheduled for the Spring 2012. The most up to date information, as well as additional details, can be found at
www.codemag.com/training.

presented is designed for .NET developers who want to move into


Agile Scrum Immersion Android development rapidly and maintain as much of their current
knowledge and even infrastructure as possible. As such, this class
Organizations are increasingly moving from traditional waterfall also includes information on how to integrate Android with existing
methods of software development to agile methodologies. Scrum .NET back-ends. No prior Android or Java knowledge is required.
has emerged as one of the most commonly applied agile practices.
Today’s successful software projects implement at least some aspect
of Scrum. Learn ASP.NET MVC in a Day!
This intensive two-day instructor-led course guides participants This intensive 1-day lecture style boot-camp on ASP.NET MVC is
through every characteristic of Scrum, including roles, planning, specifically designed for developers of business applications who
artifacts, and most importantly, the motivation behind implementing wish to learn the latest Microsoft .NET technologies. Attendees of
these elements. All this will be experienced through a balanced this class will learn how to use ASP.NET MVC and will have gained an
combination of lecture, candid discussion, hands-on exercise, and understanding of MVC to a point where they can start working on ASP.
demonstration, as well as a few surprises. NET MVC applications productively on their own. Attendees of this
class will also be able to judge whether a scenario is appropriate for
Note: This class is a joint-venture MVC and they will have a good understanding of how MVC will impact
between CODE Training and Improving their future development efforts.
Enterprises.
Note: This class can also be booked at a discount as part of our new
“Web Combo” class.
Professional Scrum Master Certification
In a joint venture between Improving Enterprises and CODE Training, C++ for .NET Developers
we are now offering the Scrum.org Professional Scrum Master (PSM)
certification course. This is the first significant update of the Certified C++ is making a comeback as a prime language for business developers.
ScrumMaster (CSM) course that Ken Schwaber introduced and shared Whether it is Windows 8 Metro, or other platforms, C++ is gaining in
in 2002. As in the original, the framework, mechanics, and roles of importance again. And fear not: C++ is not your father‘s C++ anymore
Scrum are covered. The course then goes further by teaching students and probably is much more enjoyable and productive to program than
how to use Scrum to optimize value, productivity, and total cost of you might think. Attend this 2-day class geared towards developers
ownership of systems and products. Students will learn through who are already familiar with languages such as C# or VB or even Java,
instruction and team-based exercises, and will be challenged to think and get up and running with C++ in much less time than you would
on their feet to better understand what to do when they return to have previously thought possible! Attendees of this class will get an
their workplaces. introduction to C++ from the ground up, starting with language concepts
and syntax. The class takes a close look at C++ paradigms as well as tools
Note: This class is a joint-venture and libraries commonly used. In particular, this class uses Visual Studio
between CODE Training and Improving to develop C++ (however, the core concepts are also applicable to other
Enterprises. environments and compilers).The class then proceeds to demonstrate
the use of C++ in modern business applications. One of the example
environments used is Windows 8 and its new Metro environment, which
Android for .NET Developers treats C++ as a prime citizen for building highly responsive and polished
business applications.
Google’s Android Operating System is the most widely deployed mobile
operating system and adoption is growing further at a rapid pace. As is
the case with all other mobile devices, Android applications are becoming Cloud Computing
more and more sophisticated and are thus gaining in importance for
business application developers. No matter what you are working on The “Cloud” has been making headlines, but experts still do not agree
today, you will probably encounter a need for Android sooner or later. on the role of the Cloud in development or even what the Cloud is for
that matter. This class is designed to establish what the Cloud is, what
Attendees of this class will learn how to architect, design, develop it can and can’t do, when it makes sense to go to the Cloud, what your
and deploy applications on Google’s Android OS. All the material Cloud options are, and how to implement it all.
This workshop teaches attendees how to design and develop for the by devices such as the iPhone, iPad, and iPods. While Google’s
Cloud, starting with Cloud basics such as providing data and services Android operating system may edge out Apple’s iOS in deployed
through the Cloud. The second day of the workshop explores various numbers, Apple still remains the market leader in revenue
cloud options such as Azure, Amazon’s Cloud, the Force.com Cloud, generated from applications as well as traffic generated by Apple
Google’s Cloud and the Rackspace Cloud. We will also explore hybrid devices.
Cloud options. Attendees of this workshop will learn how to develop
for the Cloud from start to finish. In the modern world of mobile development, developers often
are required to build mobile extensions to existing applications,
or even brandnew apps. .NET developers are on the forefront of
Being Productive with the CODE Framework business development and as such extremely likely to encounter
the need to build iOS applications, even though they are not .NET
CODE Framework aims at applications.
making developers super-
productive while building Attendees of this class will learn how to set up, architect, design,
applications with state-of- develop and deploy applications using Apple’s iOS to create
FR AMEWORK the-art architecture. This applications for the iPhone, iPad and iPod. The entire class is geared
class teaches using the towards .NET developers who want to move into iOS development as
framework to build a modern business application with various quickly as possible, and preserve as much of their prior knowledge
user interfaces (emphasis on Windows and Web, but with a brief and infrastructure as possible. This class also includes information
excursion into Web UIs) and a sophisticated SOA layer. While this on how to integrate these client platforms with existing .NET back-
workshop is specific to CODE Framework, many of the techniques ends.
are applicable as general development techniques.

The CODE Framework can be downloaded for free (including source Learn JavaScript and jQuery in a Day!
code) from Codeplex.com. It consists of various components
and tools that help developers with common aspects of business This intensive 1-day lecture style boot-camp on JavaScript and
application development, such as simplified SOA development with jQuery has been designed specifically for developers who wish to
various clients, or WPF development, data access, and much more. quickly learn how to use these important technologies in various
The main focus of this framework is to enable productive, flexible, scenarios. Attendees of this class (who are assumed to know at least
and highly maintainable business application development. This the basics of another programming language such as C#, Visual
workshop answers all your CODE Framework questions. Attendees Basic, C++, or...) will first learn JavaScript language concepts and
will learn proper application architecture and design, enabling syntax and will then learn how to apply these concepts in various
attendees to build systems that are easy and productive to build scenarios including the use of the popular jQuery open-source
using the CODE Framework on various the supported platforms JavaScript framework. The class then proceeds towards a detailed
such as Windows, Web and Mobile. The workshop teaches highly look at the powerful features provided by jQuery, including its
productive development techniques. These topics are CODE Training various versions and modules (including 3rd party modules). The
specialties that are not taught anywhere else, making this one of aspects learned in this training class are generic and can be used
our most popular classes. Attendees of this workshop will learn in any JavaScript development environment, although most of
how to work productively and build future proof applications and the examples will use HTML web browser scenarios, sometimes in
systems, regardless of their prior knowledge (or lack thereof). combination with Microsoft back-end technologies to facilitate the
explanation of certain concepts.

Learn HTML5 and CSS3 in a Day! Note: This class can also be booked at a discount as part of our new
“Web Combo” class.
This intensive 1-day lecture style boot-camp on HTML5 and CSS3 for
developers who wish to understand what is new in HTML5 and CSS3,
how to apply those technologies and techniques to daily development A Day of SOA & WCF with Markus Egger
tasks today and tomorrow, and to judge the impact HTML5 will have on
the overall development landscape (including a discussion on HTML5 in Spend a day with Microsoft RD (Regional Director) and veteran MVP
non-browser scenarios, such as Windows 8 Metro). The class includes a Markus Egger to lean all about SOA (“Service Oriented Architecture”)
detailed look at all the aspects of HTML5 (such as new features, document and WCF! Attendees of this class will not just learn how to use
structures, changed elements, and so forth) as well as a general review WCF and SOA to a point where they can immediately start to build
of CSS and a close look at CSS3. The class also provides a guidance as to applications based on these techniques, but they will also be able to
which HTML5 features are ready for prime-time, which you still should evaluate the impact of these techniques and technologies on their
hold off on, and which may be useful in specific scenarios. future development efforts. This comprehensive 1-day class starts
at a beginner level, but quickly moves beyond theory to enable
Note: This class can also be booked at a discount as part of our new attendees to learn how to write real world SOA & WCF applications.
“Web Combo” class. Attendees will get to see many real-world examples that showcase
the benefits of such systems and have the opportunity to discuss
their projects and have their questions personally answered by MVP
iOS (iPhone/iPad/iPod) for .NET Developers and RD Markus Egger.

Apple has single-handedly re-invented mobile development, and Note: This class can also be booked at a discount as part of our new
started the whole “app craze”, with the iOS operating system used “Web Combo” class.
Visual Studio LightSwitch Windows Phone 7 (and 7.5) applications. No prior mobile device
With LightSwitch, RAD (Rapid Application Development) returns development knowledge is required.
to the world of Visual Studio, enabling incredibly fast business
application development for the “90% need”, with the ability to
further extend LightSwitch applications with “normal” Visual Studio WPF for Business Applications
techniques and technologies.
WPF, the de-facto standard for .NET Windows development, is a very
In this 2-day class, attendees will learn everything there is to know important technology for business application developers. However,
about Visual Studio LightSwitch, starting with the basic concepts coming from Windows Forms, WPF is a huge paradigm shift. This class
and paradigms behind LightSwitch. The workshop then continues will help drastically reduce the learning curve and allow attendees to
with the creation of a representative LightSwitch application. write productive WPF code quickly.
Attendees also learn how to properly organize and structure these
types of applications and how to best use technologies utilized by This workshop answers all your WPF questions by teaching
LightSwitch, such as Silverlight and WCF RIA Services. The workshop fundamental techniques that apply to WPF. Attendees will also learn
also allocates a significant amount of time towards LightSwitch proper application architecture and design, enabling attendees to
extension as real-world applications often need to venture beyond build systems that are easy and productive to build in WPF, but can
the built-in capabilities of LightSwitch. also be easily extended to other platforms and clients. The workshop
teaches highly productive development techniques. Time is also
allocated towards teaching attendees how to build applications
Web Combo - SOA & WCF, ASP.NET MVC, that look professional, and how to do so productively and without
the need of artistic talent. Many of these topics are CODE Training
JavaScript & jQuery and HTML5 & CSS3 specialties that are not taught anywhere else, making this one of our
This “Web Combo“ provides an easy and discounted way to book a most popular classes.
series of four of our most popular classes as a single event: “A Day
of SOA and WCF with Markus Egger“, “Learn ASP.NET MVC in a Day!“, Attendees of this workshop will learn how to work productively and
“Learn JavaScript and jQuery in a Day!“, and “Learn HTML5 and CSS3 build future proof applications and systems, regardless of their prior
in a Day!“. This provides a knowledge-packed 4-day event, allowing WPF knowledge (or lack thereof).
attendees to get up to speed with four of the most important areas of
modern web development (and beyond) in less than a week!

Note: All four topics can also be booked as individual days.


Advanced WPF for Business Applications
This workshop, which is an extension of our most popular training class
(“WPF for Business Applications“), provides a detailed and in-depth
A Day of Windows 8 Development with look at many advanced concepts used in WPF business applications. This
workshop is perfect for attendees who have attended the fundamental
Markus Egger “WPF for Business Applications“ workshop, or for developers who have
This intensive 1-day lecture style boot-camp on Windows 8 is aquired a fundamental level of WPF knowledge on their own and want
specifically designed for developers of business applications who to take the next step. After attending this workshop, attendees will
wish to learn how Windows 8 will impact their efforts today and in have a better understanding of many WPF concepts and how to use
the future, and how to prepare today to make sure their investment them to their advantage. They will be more productive WPF developers
in both skill and technology is safe. This class provides an overview of who can write better and more reusable WPF code with less effort, as
various ways to develop for Windows 8, including the new Windows they will learn how to do things “the WPF way“.
8 “Metro” platform. The class aims to teach development in this new
world, but perhaps more importantly, it aims to provide an overview Note: This workshop can be booked at a discount together with
of what’s to come and how that will impact development even today. the regular “WPF for Business Applications” class for a full week
For instance, the class teaches architecture and implementation packed with WPF information.
techniques that will make sure you can bring your technology and
skills forward far into the future. Covered topics include C#/VB style
development for Windows 8 in combination with Metro. It also takes VFPConversion
a detailed look at HTML5 and JavaScript development for Metro.
We also teach our popular “.NET for VFP Developers” classes on
Note: C++ development for Windows 8 is covered in our C++ class. an ongoing basis. We offer both an introductory class (one week,
bookable in a 3-day version and a full-week version) and an Advanced
.NET follow-up class as well.
Windows Phone Development These workshops are designed for developers with a Visual FoxPro
background who want to learn .NET as quickly as possible, based on
Mobile devices are not just here to stay, but they are rapidly moving the knowledge they already possess. We provide specific information
into scenarios previously dominated by PCs. No matter what system on how to move existing VFP systems to .NET and SQL Server. Part of
one is working on today, it is almost guaranteed that a mobile device the class provides very specific examples from one of the many VFP-to-
aspect is required or will be required in the future. .NET migration projects we have handled or have been involved with
and we are proud to be able to pass on a tremendous amount of real-
As Microsoft developers, Windows Phone 7 is a very attractive offering world experience in this class.
and simple to develop for. This 2-day class will teach developers how For details on various .NET for VFP devel oper training classes, visit
to use their existing knowledge to architect, design, and develop www.codemag.com/training or www.VFPConversion.com.
More than Training! Individualized Custom Training
CODE Magazine offers more than just training in the classroom. CODE CODE Training also provides custom training classes tailored entirely
Training attendees gain access to the whole CODE Network. Attendees around a customer’s individual needs. Why send your developers to
thus gain the ability to use CODE as an ongoing resource, be it for a generic training class to learn about a specific technology when we
a short question (we are not the kind of company that charges for can come on-site and provide a class that teaches your staff exactly
that sort of thing!) or a mentoring relationship and beyond. We the skills needed for their next project?
have developed many personal friendships and mutually beneficial We offer various degrees of customization. A simple option is to pick
business relationships based on our training classes. and choose from our vast list of topics and sub-topics. Alternatively,
we can take a close look at your needs and current skill levels and
develop training classes entirely from scratch. In many cases,
the answer lies somewhere in between. We work closely with our
Our Trainers customers to determine the proper course of action.
CODE Magazine has the most extensive network of employees and Example: You need your team to implement an ASP.NET MVC based web
freelancers who work together for various reasons, such as authoring, site (Web 2.0) and expose certain functionality as services. In that
presentations, podcasts, user group meetings, consulting, and of case, we can present a list of possible topics and create a multi-day
course training! Through our involvement with Microsoft and the training program. Depending on the exact details, we may even
Microsoft Developer Community (especially networks such as the MS create some custom content, such as how to implement a specific
MVP and MS RD networks), we have access to top experts in just type of service that is required by the application. We can also
about any .NET topic and beyond. Our classes are taught by industry provide further mentoring after the class ends to make sure the team
leaders such as Markus Egger. We take great pride in picking the best knows how to apply what they have learned in each specific case and
trainer for each of our classes. for each specific need.
We can provide custom training for just about all topics relevant to
.NET business application developers and beyond. We also provide
training for generic topics such as User Interface Design or System
CODE Mentoring Program Architecture.
The CODE Mentoring Program gives you access to our developers and trainers
Custom training can be held at the customer’s location, at our
when you need guidance or quick help over a road-block but do not want
offices, online, at another location such as a hotel, and often as
to engage a firm as a large-scale consulting partner. The CODE Mentoring
a combination of these, such as on-site and online for distributed
Program is an efficient and economical way to take advantage of our
teams. Training classes can be held in a single block or spread out
expertise. For only a small investment, you always have an expert to consult
over time. Custom classes are usually also recorded to enable later
with - whether it’s just a quick question or to discuss more in depth technical
viewing and repeat, or can be passed on to team members who
or architectural details. It’s the advantage of having a large group of experts
weren’t able to attend the class.
as part of your team, but without the expense.
For more information on the CODE Mentoring Program, visit
www.codemag.com/training/mentoring
State of .NET – The Road to Windows 8

Corporate Training Accounts


Corporate Training Accounts provide organizations with sophisticated
training needs with a way to train their staff in a flexible and inexpensive
way. With a Corporate Training Account, you buy a certain number of An EPS Event
“Training Day Vouchers“ at a significantly reduced rate, which can then
be used flexibly at any of our publicly scheduled classes or even for In addition to our training classes, CODE Training also holds
custom training, on-site at your location. “State of .NET” events in various cities across the US. These
events provide an afternoon of free .NET know-how and are
Example: You have 10 developers with a training need in various technologies
independently produced by CODE, although held in conjunction
and you estimate a need of 8 days of training for most of them. You can
with Microsoft and usually take place at Microsoft offices. The
thus buy 80 days worth of Training Vouchers at a rate of $250 each. You can
current series of State of .NET events focuses in part on current
then send each developer to any of our training classes whenever needed,
.NET technologies and architecture, but also takes a very close
regardless of the actual higher cost of each training day if you were to
look at Windows 8 from a developer’s point of view (hence “The
purchase that training individually. Or, you can even ask us to come to your
Road to Windows 8” sub-title).
location and train on site (see below for details). And if one of them needs
a little more training and another a little less, no problem, since you decide Upcoming locations include Philadelphia, New York, Boston,
how to use your vouchers! Also, your vouchers never expire. Vancouver, Houston, Dallas, and more.
For more information on Corporate Training Accounts, visit For more information, visit www.StateOfDotNet.com. Also visit us on
www.codemag.com/training/corporate Facebook at www.Facebook.com/StateOfDotNet
CODE Training Schedule - Spring 2012
March 19 – 21, 2012 Intro to .NET for VFP Developers
VFP1
March 22 – 23, 2012 Real-world VFP to .NET Conversion Training

ASI April 11-12, 2012 Agile Scrum Immersion

VFP2 April 16 – 20, 2012 Advanced .NET for VFP Developers

May 7 – 9, 2012 WPF for Business Applications


WPF
May 10 – 11, 2012 Advanced WPF for Business Applications

May 14 – 15, 2012 Android for .NET Developers

Mobile May 16 – 17, 2012 Windows Phone 7 and 7.5 (Mango) for .NET Developers

May 21 – 23, 2012 iOS (iPhone/iPad/iPod) for .NET Developers

PSM May 16-17, 2012 Professional Scrum Master Certification

CODE May 24 – 25, 2012 Being Productive with the CODE Framework

June 4, 2012 A Day of SOA & WCF with Markus Egger

June 5, 2012 Learn ASP.NET MVC in a Day!


Web
June 6, 2012 Learn JavaScript and jQuery in a Day!

June 7, 2012 Learn HTML5 and CSS3 in a Day!

Windows 8 June 8, 2012 A Day of Windows 8 Development with Markus Egger

LS June 11 - 12, 2012 Visual Studio LightSwitch

Cloud June 14 – 15, 2012 Developing Cloud Applications

C++ June 18 – 19, 2012 C++ for .NET Developers

* Individual line items can be booked as individual days. Alternatively, blocks (color-coded) can be booked in combination at greatly discounted rates.
Group and repeat-customer rebates may apply as well. For details, visit www.codemag.com/training

** Note that exact dates are subject to change based on customer needs. Please double-check dates on www.codemag.com/training

p Today !
Sig U
To sign up, visit www.codemag.com/training or contact us via
email (info@codemag.com) or phone (1-832-717-4445 ext 13).
Call us for group or repeat-customer discounts! TR AINING
An EPS Company
ADVERTORIAL

TeamCompanion: Team Foundation


Server and Outlook Together
Envision this frequent real-life scenario: You receive an email with a new requirement or feature request. If you just
answer that email and continue the discussion in Outlook, all important information about this request will get
lost among the multitude of emails you work with every day. Obviously, it would be better if you saved that new

request in the form of a work item on the backlog in and other Outlook/TFS integration features we already
Team Foundation Server (TFS). Doing that manually could mentioned.
mean that you must copy important information from the
email to appropriate work item fields, attach the email On top of that, TeamCompanion offers a powerful agile
and all its attachments to the work item, fill up other project management toolset with team support. Most
necessary fields, possibly send a confirmation reply and non-developer users will find in TeamCompanion every-
other similar steps. This is way too many small steps that thing they require to work with TFS and they will never
will make you want to avoid dealing with new requests in need to switch from Outlook to any other tool.
the first place.
Ognjen Bajic
Using TeamCompanion from Ekobit, you create a new Information at Your Fingertips obajic@ekobit.hr
work item based on an email with just one click. Easily, TeamCompanion Product Owner
quickly and effortlessly. If a related work item already Making information available in an easy manner and at
exists, it is just as easy to find it and attach the email the right time is what TeamCompanion excels at. Drag
to it instead. work item queries to the Outlook Favorites folder to have
them always in sight and configure their scheduled ex-
And there is much more in this Outlook add-in than just ecution at regular intervals. As soon as there are chang-
email integration. It integrates Outlook and TFS in many es, you will be notified. Changed, new, and unread work
other ways: It connects Outlook appointments or tasks items appear clearly highlighted in bold, just the way
with respective work items, lets you set up work item re- newly received emails do. This is the least intrusive and
mainders, helps you send TFS reports via email or search most efficient way to be notified of changes. Usually, you
emails related to a particular work item, etc. would subscribe to receive notification emails. Scheduled
queries can spare you of such emails and provide the
same information in a much more efficient way. Ana Roje Ivancic
Stakeholders and Developers Collaborate Principal Tester
If you still like notifications and subscribe to them, than
By bridging the gap between email communication and when a build, changeset or work item change notification
TFS work item management, TeamCompanion connects arrives, it is easy to open the related TFS object from that
two worlds: the outside world of various stakeholders’ email and drill in its properties.
types and the inner world of the development team.
Stakeholders are looking at the project from outside
and usually can’t access TFS directly. This bridge en- Agile Project Management
sures their continuous involvement and high quality
direct communication. Uninterrupted interaction with TeamCompanion comes with a powerful agile project man-
stakeholders critically contributes to the success of the agement feature set. It works out of the box with all three
project. standard process templates (Agile, CMMI and Scrum) and is
highly configurable and suitable for any agile methodology.
Besides improving your communication with all involved It covers all major phases of agile processes: product back-
in the project, TeamCompanion provides you the right in- log grooming including ordering of product backlog items
formation whenever and wherever you need it. It helps (PBIs), sprint planning and assigning PBIs to sprints includ-
you work more efficiently and easily collaborate. ing capacity planning, resource load balancing and progress
tracking using the burndown chart. Velocity chart, various
embedded statistics and the burndown chart are based on
Full-fledged Team Foundation Server Client the transactional work item database and reflect all changes
to work items in real time. Using drag and drop you can
TeamCompanion is a full-featured TFS client inside Out- easily reorder PBIs, plan them for a particular sprint or sim-
look that supports all work item management related ply assign tasks to team members. All these actions directly
actions, SQL Server reports, and SharePoint document change all charts and statistics and help you constantly
library integration, adding to this many unique en- keep track of the project status and trends.
hancements. You can create and edit work items and
work item queries, execute queries in various ways, Once the team starts sprinting, TeamCompanion continu-
group query results or export them to Excel or Project. ously keeps load statistics for each team member and the
There are also work item reminders and appointments, team burndown up to date.

codemag.com TeamCompanion: Team Foundation Server and Outlook Together 41


support for teams, TeamCompanion is the perfect tool to
support your Scrum-based development.

Offline Support and What-If Analysis


All changes done in these agile tools (and most every-
where else in the TeamCompanion) are first saved locally
only. You can determine how changes influence various
statistics and project parameters and whether they make
sense, without having to save them on the server. It is
easy to undo multiple changes at once or commit them to
TFS. The project planner can work out different scenarios
and find the optimal one easily, which is especially handy
while balancing the workload among the team members.

Supports the New TFS 11 Beta


The newest version of TeamCompanion supports the new
TFS 11 Beta, TFS 2010 and Outlook 2010, with earlier
versions supporting different combinations of Outlook
2003, 2007 and 2010 and TFS 2005, 2008 and 2010. You
can find more information at www.teamcompanion.com.
Figure 1: Work item queries added to the Favorites folder with one of them scheduled and
showing two changed work items. Ognjen Bajic

Ana Roje Ivancic

Figure 2: With real-time burndown chart and remaining capacity statistics for each team
member, it is easy to track progress during the sprint.

Manage Agile/Scrum Teams


TeamCompanion provides first class support for teams.
Teams have their own backlog, set of iterations, mem-
bers, burndown, etc. Planning is done for each team sep-
arately: Capacity is defined on a per team basis and tasks
are assigned to and balanced among the corresponding
team members.

With its rich feature set, comfortable and efficient user


interface, offline support and what-if analysis and native

42 TeamCompanion: Team Foundation Server and Outlook Together codemag.com


ONLINE QUICK ID 1203061

CODE Framework: Building Services


and SOA Business Layers
In the last issue of CODE Magazine, we took a look at CODE Framework’s WPF features. This time, we are going to look at a
completely different area of the framework: Creating business logic and middle tiers as SOA services. SOA is the cornerstone
of many modern applications, creating systems that are more maintainable, flexible, and suitable for a wide range

of scenarios, ranging from Windows to web and mobile up to the standards you set in the last decade or two,
scenarios using a wide variety of technologies, and out- not to mention expectations in the future? How can we
performing conventional multi-tiered applications in a fulfill the expectations of a technical and economic envi-
range of metrics. Using CODE Framework, it also becomes ronment where it is not acceptable to have to throw out
easy and extremely productive to build SOA layers. the entire application to support the latest mobile de-
vice or browser? And how do we fulfill those expectations
In today’s application landscape, there only seems to be in a way that’s a realistically feasible approach, highly
one aspect that is certain: Uncertainty. Which UI tech- productive, creates highly flexible and exquisitely archi-
nology or which mobile platform will be dominant in the tected systems that are easy to maintain without a large
years to come? We know that for business applications squad of rocket-science-level developers, and generally
especially, rich Windows UIs are still very popular and promotes high quality as a goal that is easy to achieve? Markus Egger
the most productive type of application. We also have megger@eps-software.com
no doubt about the significance of web applications in Markus is an international
general, and HTML5 in particular. We know that iOS and Services are the Answer speaker, having presented ses-
Android are important mobile operating systems, and we sions at numerous conferences
hope Windows Phone will catch up. There also is a good I believe very strongly that Services and SOA (Service in North and South America
chance that Windows 8 Metro will have a significant role Oriented Architecture) are a very good answer to this and Europe. Markus has written
to play. But do we know any of these for sure? And how problem. And by that, I do not mean the creation of XML many articles for publications
many of these does any system have to support now or Web Services or the creation of REST Services or any simi- including CODE Magazine, Visual
in the future? Even if you know that you want to build lar technology you might choose. Instead, I am talking Studio Magazine, MSDN Brazil,
your application based on HTML5, which is going to be about creating services that are more abstract and bro- asp.net Pro, FoxPro Advisor,
the predominant tool for building such applications a few ken out as generically callable objects with an agreed- Fuchs, FoxTalk and Microsoft
years down the road? Or which approach to building Win- upon interface (“contracts”). Once such abstract services Office and Database Journal.
dows 8 Metro applications will be the one you choose? are created, various deployment choices can be made. Markus is the publisher of CODE
Magazine.
Do you feel that REST is the ideal way to get to those ser-
Basing your systems on SOA and vices? Fine choice! You like XML Web Services, and SOAP
Markus is also the President and
Services is the best way to deal with the better? That’s fine with me too. You prefer binary optimized
Chief Software Architect of EPS
Software Corp., a custom software
uncertainties of today’s development services for efficiency? In scenarios where binary optimized development and consulting
landscape, build systems that will be services are technically possible, they might be the best firm located Houston, Texas.
maintainable for a long time, and adjust choice of all. But these are decisions that are made later. He specializes in consulting for
Start out with a REST Service and you might be stuck with object-oriented development,
flexibly to new demands. REST forever. The same is true for many systems that are Internet development, B2B, and
based solely on SOAP. But if you start out generic, you have Web Services. EPS does most of its
In short: It is currently impossible to answer many of these great freedom in choice. Perhaps you use TCP/IP-based ser- development using Microsoft Vi-
questions now, and it’s certainly impossible to answer these vices initially, but then decide you want to write an iOS or sual Studio (.NET). EPS has worked
questions if you are aiming for a 5- or 10- or even 20-year ho- Android client, and REST is the better choice for that. With on software projects for Fortune
rizon. 20 years may seem like an extremely long time in IT, but solid architecture, that is simply a deployment choice. 500 companies including Philip
realistically speaking, databases that have been maintained Morris, Qualcomm, Shell, and
for 10 or 20 years, or business logic that has its roots in VB6 None of these aspects are new. SOA has been around for a Microsoft. Markus has also worked
is not uncommon. In fact, one of the most common operating while and different types of service standards as well. But as a contractor on the Microsoft
systems in use today (Windows XP) is now more than a de- how do you really approach a project that utilizes SOA and Visual Studio team, where he
cade old. Although UI choices and platforms (such as phones do so in a way that is highly productive yet at the same was mostly responsible for object
and slates) have changed very rapidly and will likely continue easy to do, even for junior developers? And how do you modeling and other object- and
to do so, middle-tiers and databases have evolved at a much really call services using all these different standards? component-related technologies.
slower pace. Consider CODE Magazine as an example. The sub-
scriber system we are using for the magazine has continually If you have done service work in the past, you know that
evolved over the years, but many of its components are now a lot of this theory is not necessarily the way things work
over a dozen years old and that is perfectly fine. in the real world. Lots of services are stuck in SOAP. Lots
of services are REST-based and cannot adjust to other
So how do you work productively as a developer or archi- standards. In fact, many environments are specifically
tect in such an environment? How can you build middle geared towards the creation of specific types of services
tiers, business logic, and databases in a way that will live but can’t easily cross over to other standards. If you are

codemag.com CODE Framework: Building Services and SOA Business Layers 43


Downloading the Framework using WCF in .NET, you are in a pretty good position, as makes this a convenient option). You can install the tools
WCF is highly flexible; even so, services created for SOAP through the Visual Studio Extension Manager (found in the
You can download CODE do not easily translate to REST and vice-versa. Tools menu) by searching for “CODE Framework” on the On-
Framework with source code from line Gallery (scroll down a bit if you don’t see it right away).
CodePlex (http://codeframework. Figure 1 shows the Extension Manager in action. Once in-
codeplex.com). Various versions CODE Framework SOA Features stalled, the CODE Framework Tools provide CODE Framework
are provided, including debug and
project and item templates as well as other useful tools.
release builds, as well as all the
And this is where CODE Framework’s SOA features enter the
source code. CODE Framework is
picture. CODE Framework is a free and open source framework
completely open source and free
of charge. provided by the makers of CODE Magazine. It has grown out Creating a First Service Contract
of a larger commercial product, enhanced with new features,
Note that in many cases it is and it is available on CodePlex (http://codeframework.code- The WPF client application created in last issue’s CODE
not necessary to download the plex.com). For specifics as to how to get and install it, see Framework article shows a customer management applica-
framework components manually, the sidebar. The range of features includes anything from tion that enables you to look at a list of customers, search
but you can let the CODE data access to front ends of various kinds (WPF, Web, Mobile, for customers, and edit customers, but it uses a fake data
Framework Tools (which you can etc.). For a taste of CODE Framework’s WPF features, see the layer (hardcoded data in the front end) for the purposes
get as a Visual Studio Extension article in the Jan/Feb 2012 issue of CODE Magazine. This time of the example. In the example shown in this article, we
using the Visual Studio Extension however, we are going to take a look at features in the Ser- will create some of the services that can be used to sup-
Manager) handle this task for vices and SOA sub-sections of the framework. port those features through to the middle tier. (We will
you. Whenever a CODE Framework still forego the step of accessing data in a database, which
component is needed that is not The particular goals of the CODE Framework SOA features may be a topic for a future article in this series.)
present, these tools automatically (which are all based on WCF) include the creation of con-
retrieve them through a dialog tracts and services in a highly productive way, enable To start out, let’s create a contract definition so we know
box that pops up. (This dialog box hosting of those services in ways that are convenient for what features we want to support in our middle tier. This
also provides the option to pull
both development and runtime deployment, and enable defines which methods (“operations”) our service has,
the assemblies from a local source,
seamless swapping beyond various standards and proto- and which parameters we send to it and what return val-
in case you have downloaded a
specific version that you would
cols to support any conceivable caller and scenario with- ues we expect (in SOA lingo “data contracts” or “mes-
like to use, rather than retrieving out the need for any rewrites. In addition, CODE Frame- sages”). Our service isn’t going to be overly complex or
the latest version online). work provides tools and templates to make this easy and difficult. It supports a way to get all customers (whether
more productive than creating old-fashioned business you want to do that in a real world scenario is a differ-
layers in conventional multi-tiered scenarios. ent question due to the potentially large number of cus-
tomers – but perhaps for some smaller support data this
To start exploring the CODE Framework SOA features, we would be more realistic). We need a way to search for
will create a new service contract definition as well as a sub-set of customers based on different criteria. And
an implementation. The example will closely match the we need a way to retrieve a single customer, modify the
features used by the WPF client application I described in customer, and save the customer.
last month’s CODE Framework article, which used hard-
coded dummy data. If you were so inclined, you could use We do all this by creating a new solution and project
the example created in this article and call the services based on the CODE Framework Service Contract project
from that WPF client to create a more complete applica- template. This project template can be found under the
tion. However, to keep things simple, the downloadable “CODE.Framework” category in your “New Project” dialog
sample accompanying this article will be stand-alone. (see Figure 2). This project template is rather simple,
and you could probably create the same project by hand
To follow this example, you need the CODE Framework on without even using the provided tools. It makes sure all
your computer, or at the very least the CODE Framework the right .NET Framework references are included (CODE
Tools (which will automatically retrieve all needed compo- Framework SOA projects are based on WCF) and it pro-
nents from CodePlex, in case you are missing any, which vides a first example contract that is also customer re-
lated. This means that there is a default contract file,
called ICustomerService.cs, and is quite convenient for
our needs. Most real-world projects are likely to remove
or rename this file, or use it as initial guidance.

The default ICustomerService interface in this file al-


ready provides two methods (operations) that are simi-
lar to what we want to create in our example, but not
quite right. What we want are the following four opera-
tions:

1. GetAllCustomers()
2. SearchCustomers()
3. GetCustomer()
4. SaveCustomer()

These operations are self-explanatory. The first two pro-


Figure 1: Installing the CODE Framework Tools through the Visual Studio Extension Manager vide ways to retrieve full or partial customer lists. The third
provides everything you need to start working with the CODE Framework. operation retrieves a single customer with all its detail,

44 CODE Framework: Building Services and SOA Business Layers codemag.com


and the fourth allows us to save modified customer infor- As you can see, each of these classes uses a different The _ExternalComponents
mation in case we want to change what we retrieved with custom class for parameters and return values. Some of Project
the third operation. them are rather simple, such as the GetAllCustomersRe-
quest class: When the CODE Framework Tools
download framework components,
Using the CODE Framework, you can follow a standard pat-
they are automatically put into a
tern in how you define the parameters and return values for [DataContract]
project within your solution called
these operations. There is always a single input parameter, public class GetAllCustomersRequest
“_ExternalComponents”. This is
which is itself a class that usually has multiple properties. { } a dummy project that serves no
There is also a return value that is a custom class with vari- compiled purpose. It is a location to
ous properties. Of course, what you are creating here is a It’s admittedly not very exciting, but this class is pro- store external components (CODE
standard WCF service contract and you just use the CODE vided to provide a defined contract that can then be ver- Framework or otherwise).
Framework to make that as easy as possible. Because it is a sion controlled over time (“versioning”). Perhaps we may
standard WCF contract, you can do anything WCF supports, need to add a parameter in the future (such as Exclu- This is a simple approach to putting
including sending multiple parameters and simple types, deInactiveCustomers) which we can easily do by adding a all the external components into your
such as strings or numbers, as parameters and return val- property for that purpose. current solution. Each project then
ues. The pattern of “single complex parameter in, single adds references to that folder, which
complex return value out” maps very well to all kinds of ser- Some other classes are a bit more sophisticated, such as is always in the same location relative
to the project that uses the reference.
vice standards and provides maximum flexibility. Note that the GetCustomerRequest class:
we also like to create these custom parameter classes even This provides a number of advantages.
if we do not send a parameter value, because then we have [DataContract] For instance, you can check the entire
a simple empty class. This gives the ability to start adding public class GetCustomerRequest solution into your source control
parameters later without breaking the operation’s contract. { system and someone else can then
In other words, it is simple to keep the service compatible public GetCustomerRequest() join that project and have all required
over time. You do not have to follow these patterns to use { external components in a place where
the CODE Framework, but you will find that it makes your life CustomerId = Guid.Empty; they are automatically found. It also
easier and your architecture more maintainable. } means that each solution you create
can use a different version of the
We also name our parameters using a standard naming [DataMember(IsRequired = true)] framework, if desired. If you have
convention that includes a “Request” or “Response” suf- public Guid CustomerId { get; set; } an older project that you need to
fix. The class we use as the parameter for the Search- } change, but have a newer version of
Customers() method is called “SearchCustomersRequest” the framework installed, you are not
forced to update the older application,
and the return value is called “SearchCustomersRe- This class includes a single property that we use to tell the
just to make a minor change.
sponse”. Sometimes we also send what would be a pretty service which customer we want to retrieve. There are a few
close equivalent to a record in a database (such as the things to note here. For one, we explicitly flag data ele- Again, this is an approach that works
detailed information about a specific customer), in which ments in the contract as [DataMember]. This is not strictly very well for us but is completely
case we like to use an “Information” suffix instead (such required by WCF (which treats this property as optional if all optional. Use it if you find it beneficial,
as “CustomerInformation”). Again, this is not a require- members are data members) but we find that if we do not but feel free to change this approach.
ment, but we like the idea in many cases. Where it makes do it, it is a very common source of errors over time. We also
sense, we sometimes bend that rule a bit, too. like to use the IsRequired flag for members as a common
option to indicate that this data element is required. You
To create a contract with these four operations, change will see this often in our contracts, as it is often painful to
the ICustomerService interface to the following: deal with when elements are not required and are therefore
not serialized into the contract for some reason. In more
[ServiceContract] unusual client environments where you have to hand-code
public interface ICustomerService the service call, this can be quite inconvenient. Finally, you
{ may notice that we use a constructor to create an explicit
[OperationContract] default value for the property. Again, it’s not a requirement
GetAllCustomersResponse GetAllCustomers( but a convenience feature, as it makes it easier to deal with
GetAllCustomersRequest request);

[OperationContract]
SearchCustomersResponse SearchCustomers(
SearchCustomersRequest request);

[OperationContract]
GetCustomerResponse GetCustomer(
GetCustomerRequest request);

[OperationContract]
SaveCustomerResponse SaveCustomer(
CustomerInformation request);
}

Note that this is a standard WCF service contract using


standard WCF attributes such as [ServiceContract] and
[OperationContract] to indicate our intentions to WCF. Figure 2: Create a new Service Contract project based on a provided project template.

codemag.com CODE Framework: Building Services and SOA Business Layers 45


the contract in some cases. (Note that these defaults do not very little code, as it only defines structures but no logic. It
carry through to certain service clients, but it is still conve- has very few assembly references, and the only ones we have
nient to have them when they do show up). Many of these are to some fairly basic .NET Framework assemblies. There are
aspects work well for us and we recommend them, but you no references to CODE Framework assemblies. There are also
can substitute your own standards. After all, this is just a no references to any business logic assemblies. And that is
plain old WCF service contract. how we will keep things in this project. Contract assemblies
are supposed to be simple and transferable. This is one way
It is also interesting to take a look at some of the response (although not the only way, of course) to give a contract defi-
contracts. Here is the GetAllCustomersResponse class: nition to someone else. A potential caller using a .NET appli-
cation as a client could simply use this DLL to get everything
[DataContract] they need to know to interact with the service (or at least its
public class GetAllCustomersResponse structure). For that purpose, we would not want to have to
{ give away other assemblies that this DLL depends upon.
public GetAllCustomersResponse()
{
Success = false; Implementing the Service
FailureInformation = string.Empty;
Customers = new List<CustomerQuickInformation>(); So far, we have created a simple WCF Service Contract with
} some help by the CODE Framework, although so far, nothing
[DataMember(IsRequired = true)] has been surprising. As we start to implement our service,
public bool Success { get; set; } this changes drastically. The CODE Framework Tools are now
[DataMember(IsRequired = true)] starting to kick in further and make things simple for us.
public string FailureInformation { get; set; }
[DataMember(IsRequired = true)] As a first step, let’s create a new project for our service
public List<CustomerQuickInformation> implementation. To do so, add a new project to your cur-
Customers { get; set; } rent solution and pick the “CODE Framework Service Im-
} plementation” project template. Using this template, the
CODE Framework tools analyze your current solution, find
This class defines two properties that we add to all our re- all Service Contracts, and display them in a tool window
sponse contracts: Success and FailureInformation. Again, (Figure 3). This allows you to pick the services you would
this is not a requirement, but it works well for us. These like to implement, and the tools create a default imple-
properties indicate whether a service call was successful in mentation for you. In our example, we only have one
a technical sense (in other words: “Did an exception occur Service Contract, which is selected by default, so we can
on the server?”) and if not, we have a simple way to pro- click “OK” to continue with the creation of the project. If
vide very basic error information. As a little side-note: We multiple Service Contracts are found, you can pick all the
do not commonly use fault contracts, as we may encounter ones you want to implement and the tool will create as
scenarios where they are not supported or are inconve- many implementation classes as are needed.
nient. We also do not indicate detailed exception informa-
tion in the FailureInformation property, as that would be a The next step depends a bit on whether or not you have
security problem (passing detailed exception information already added CODE Framework assemblies to your project.
is a great source of information for hackers). Instead, we If you have followed along with the example so far, you do
provide some basic information back to the client, and log not have those. The tools detect this issue and will help you
detailed information on the server. (See below for more remedy this problem by asking you where to retrieve these
information as to how efficiently we handle that scenario). assemblies from. This includes automatically downloading
the latest version of the required assemblies from CodePlex,
Note that this contract also includes a List of Customer- which is also the default option (Figure 4). Accept that op-
QuickInformation objects. This is where the actual data is tion and pick “Add Assemblies” to have the tools download
stored. CustomerQuickInformation objects are data ele- the assemblies and add them to your current project for you.
ments that describe the most important aspects of a cus- Note that if you were to repeat the task of creating a service
tomer (Name, ID,…) as it would be convenient for display- implementation, this step is not required again and will be
ing lists of customers. Note again that we created a default skipped. The dialog box shown in Figure 4 is only displayed
empty List of CustmerQuickInformation in the constructor, if problems with missing assemblies are detected.
as it can be extremely inconvenient to have to repeatedly
check for null in many scenarios. We can avoid some of
those by setting the default in the constructor.

All of the classes used for requests and responses fol-


low a similar pattern. See Listing 1 for more details (or
download the associated code sample). Note that the full
listing contains quite a bit of documentation, which we
consider important for contracts, as they define the in-
terface to callers who may need to know what different
contract elements are used for.
Figure 3: The CODE Framework Service Implementation
And that’s about it for the contract. One further thing to template automatically detects service contracts and
point out is how simple the service contract project is. It has creates default implementations for them.

46 CODE Framework: Building Services and SOA Business Layers codemag.com


DON’T GET LEFT BEHIND!

© Taalvi - Fotolia.com

SUBSCRIBE TODAY
AND DON’T MISS AN ISSUE!
Special offer!
Get a 3-year subscription for the price of 2!
www.codemag.com/subscribe/cm412

See more details at: www.codemag.com/magazine MAGAZINE


An EPS Company
Listing 1: The complete ICustomerService service contract definition.
using System; /// errors or problems.</summary>
using System.Collections.Generic; /// <remarks>'Success' is a standard member for CODE Framework
using System.Runtime.Serialization; /// contracts. It is not technically required but we recommend
using System.ServiceModel; /// supporting it.</remarks>
[DataMember(IsRequired = true)]
namespace Customer.Service.Contracts public bool Success { get; set; }
{
/// <summary>Example customer service</summary> /// <summary>If Success is false, FailureInformation contains
[ServiceContract] /// a brief indicator of what went wrong.</summary>
public interface ICustomerService /// <remarks>This should NOT contain an exception message for
{ /// security reasons. ‹FailureInformation› is a standard member
/// <summary>Retrieves a list of customers</summary> /// for CODE Framework contracts. It is not technically required
/// <param name=»request»>Request</param> /// but we recommend supporting it.</remarks>
/// <returns>Response</returns> [DataMember(IsRequired = true)]
[OperationContract] public string FailureInformation { get; set; }
GetAllCustomersResponse GetAllCustomers(
GetAllCustomersRequest request); ///<summary>Actual list of customers returned by
/// GetCustomerList()</summary>
/// <summary>Retrieves a list of customers</summary> [DataMember(IsRequired = true)]
/// <param name=»request»>Request</param> public List<CustomerQuickInformation> Customers { get; set; }
/// <returns>Response</returns> }
[OperationContract]
SearchCustomersResponse SearchCustomers( ///<summary>Response contract for GetCustomerList() operation</summary>
SearchCustomersRequest request); [DataContract]
public class GetAllCustomersResponse
/// <summary>Retrieves a specific customer</summary> {
/// <param name=»request»>Request</param> ///<summary>Constructor</summary>
/// <returns>Response</returns> /// <remarks>Explicitly set default values for all properties
[OperationContract] /// in the constructor</remarks>
GetCustomerResponse GetCustomer(GetCustomerRequest request); public GetAllCustomersResponse()
{
/// <summary>Retrieves a specific customer</summary> Success = false;
/// <param name=»request»>Request</param> FailureInformation = string.Empty;
/// <returns>Response</returns>
[OperationContract] Customers = new List<CustomerQuickInformation>();
SaveCustomerResponse SaveCustomer(CustomerInformation request); }
}
/// <summary>Indicates whether the call succeeded without
/// <summary>Request contract for GetAllCustomers() operation</summary> /// errors or problems.</summary>
/// <remarks>Always create a request object, even if this object /// <remarks>'Success' is a standard member for CODE Framework
/// has no parameters. This allows for future changes in a structured /// contracts. It is not technically required but we recommend
/// fashion.</remarks> /// supporting it.</remarks>
[DataContract] [DataMember(IsRequired = true)]
public class GetAllCustomersRequest public bool Success { get; set; }
{
/// <summary>Constructor</summary> /// <summary>If Success is false, FailureInformation contains a
/// <remarks>Explicitly set default values for all /// brief indicator of what went wrong.</summary>
/// properties in the constructor</remarks> /// <remarks>This should NOT contain an exception message for
public GetAllCustomersRequest() /// security reasons. ‹FailureInformation› is a standard member for
{ /// CODE Framework contracts. It is not technically required but we
} /// recommend supporting it.</remarks>
} [DataMember(IsRequired = true)]
public string FailureInformation { get; set; }
///<summary>Response contract for GetCustomerList() operation</summary>
[DataContract] /// <summary>Actual list of customers returned by
public class SearchCustomersResponse /// GetCustomerList()</summary>
{ [DataMember(IsRequired = true)]
/// <summary>Constructor</summary> public List<CustomerQuickInformation> Customers { get; set; }
/// <remarks>Explicitly set default values for all properties }
/// in the constructor</remarks>
public SearchCustomersResponse() [DataContract]
{ public class SearchCustomersRequest
Success = false; {
FailureInformation = string.Empty; public SearchCustomersRequest()
{
Customers = new List<CustomerQuickInformation>(); FirstName = string.Empty;
} LastName = string.Empty;
CompanyName = string.Empty;
/// <summary>Indicates whether the call succeeded without }

48 CODE Framework: Building Services and SOA Business Layers codemag.com


Listing 1: Continued
/// in the constructor</remarks>
[DataMember(IsRequired = true)] public CustomerInformation()
public string FirstName { get; set; } {
[DataMember(IsRequired = true)] Id = Guid.Empty;
public string LastName { get; set; } FirstName = string.Empty;
[DataMember(IsRequired = true)] LastName = string.Empty;
public string CompanyName { get; set; } CompanyName = string.Empty;
} Address = string.Empty;
Phone = string.Empty;
/// <summary>Request contract for GetCustomer() operation</summary> CreditLimit = 1000m;
[DataContract] CustomerSince = DateTime.Today;
public class GetCustomerRequest }
{
/// <summary>Constructor</summary> /// <summary>Id/Primary key that uniquely identifies the
/// <remarks>Explicitly set default values for all properties /// customer</summary>
/// in the constructor</remarks> [DataMember(IsRequired = true)]
public GetCustomerRequest() public Guid Id { get; set; }
{
CustomerId = Guid.Empty; ///<summary>The customer›s first name.</summary>
} [DataMember(IsRequired = true)]
public string FirstName { get; set; }
///<summary>ID of the customer that is to be returned</summary>
[DataMember(IsRequired = true)] ///<summary>The customer›s last name.</summary>
public Guid CustomerId { get; set; } [DataMember(IsRequired = true)]
} public string LastName { get; set; }

/// <summary>Response contract for GetCustomer() operation</summary> ///<summary>The customer›s company name.</summary>
public class GetCustomerResponse [DataMember(IsRequired = true)]
{ public string CompanyName { get; set; }
/// <summary>Constructor</summary>
/// <remarks>Explicitly set default values for all properties ///<summary>City, State for the customer›s main offices.</summary>
/// in the constructor</remarks> [DataMember(IsRequired = true)]
public GetCustomerResponse() public string Address { get; set; }
{
Success = false; /// <summary>Main phone line (switchboard) for the
FailureInformation = string.Empty; /// customer.</summary>
[DataMember(IsRequired = true)]
Customer = new CustomerInformation(); public string Phone { get; set; }
}
/// <summary>Customer’s total credit limit for all
/// <summary>Indicates whether the call succeeded without errors /// departments.</summary>
/// or problems.</summary> [DataMember(IsRequired = true)]
/// <remarks>'Success' is a standard member for CODE Framework public decimal CreditLimit { get; set; }
/// contracts. It is not technically required but we recommend
/// supporting it.</remarks> /// <summary>Date of customer›s first signed contract
[DataMember(IsRequired = true)] /// with us.</summary>
public bool Success { get; set; } [DataMember(IsRequired = true)]
public DateTime CustomerSince { get; set; }
/// <summary>If Success is false, FailureInformation contains a }
/// brief indicator of what went wrong.</summary>
/// <remarks>This should NOT contain an exception message for /// <summary>Shortened customer information suitable for use
/// security reasons. ‹FailureInformation› is a standard member for /// in lists</summary>
/// CODE Framework contracts. It is not technically required but we /// <remarks>For detailed customer information, use the
/// recommend supporting it.</remarks> /// CustomerInformation contract. However, for large lists (with
[DataMember(IsRequired = true)] /// potentially large amounts of data), use this contract
public string FailureInformation { get; set; } /// instead.</remarks>
[DataContract]
/// <summary>This is the payload this sample call will public class CustomerQuickInformation
/// return.</summary> {
[DataMember(IsRequired = true)] /// <summary>Constructor</summary>
public CustomerInformation Customer { get; set; } /// <remarks>Explicitly set default values for all properties
} /// in the constructor</remarks>
public CustomerQuickInformation()
/// <summary>Detailed information for a single customer.</summary> {
[DataContract] Id = Guid.Empty;
public class CustomerInformation FullName = string.Empty;
{ }
/// <summary>Constructor</summary>
/// <remarks>Explicitly set default values for all properties /// <summary>Unique customer ID</summary>

codemag.com CODE Framework: Building Services and SOA Business Layers 49


Listing 1: Continued
[DataMember(IsRequired = true)]
public Guid Id { get; set; } /// <summary>Indicates whether the call succeeded without errors
/// or problems.</summary>
///<summary>The customer›s full name.</summary> /// <remarks>’Success’ is a standard member for CODE Framework
[DataMember(IsRequired = true)] /// contracts. It is not technically required but we recommend
public string FullName { get; set; } /// supporting it.</remarks>
} [DataMember(IsRequired = true)]
public bool Success { get; set; }
/// <summary>Response contract for GetCustomer() operation</summary>
public class SaveCustomerResponse /// <summary>If Success is false, FailureInformation contains a
{ /// brief indicator of what went wrong.</summary>
/// <summary>Constructor</summary> /// <remarks>This should NOT contain an exception message for
/// <remarks>Explicitly set default values for all properties /// security reasons. ‹FailureInformation› is a standard member for
/// in the constructor</remarks> /// CODE Framework contracts. It is not technically required but we
public SaveCustomerResponse() /// recommend supporting it.</remarks>
{ [DataMember(IsRequired = true)]
Success = false; public string FailureInformation { get; set; }
FailureInformation = string.Empty; }
} }

Once the creation of the new implementation project fin- to be executed to retrieve the list runs (the part that is
ishes, you have a project with all the required references to represented by a TODO comment) and finally, the Success
.NET Framework assemblies, CODE Framework assemblies, and flag is set to true, and the response object is returned. If
of course the contract assemblies for all the contracts you any of this fails, the catch-block kicks in, uses the CODE
choose to implement (ICustomerService, in this case). You Framework Logging System to log the problem away, and
also end up with a valid default implementation of all services returns a response that indicates failure with some fairly
(in a file called CustomerService in this example). The default rudimentary failure information (slightly more detailed
implementation is a class that implements the contract inter- than in the snippet above, which we trimmed for brevity)
face by creating implementations for all the required opera- that allows the caller to track down further information.
tions. For instance, the default for GetAllCustomers() is:
Note the use of the CODE Framework Logging System.
public GetAllCustomersResponse GetAllCustomers( This is a good idea, because there are other components
GetAllCustomersRequest request) in the system that can pick up this information, as we will
{ see below. Of course, a lot of people have their own log-
try ging systems or may even use other logging frameworks.
{ That is fine. You can easily plug those into the CODE
var response = new GetAllCustomersResponse(); Framework LoggingMediator object. This is an example of
a design philosophy we follow throughout all parts of the
// TODO: Add service-specific code here framework: We provide interesting default features, but
enable bringing in other components easily if desired.
response.Success = true;
return response; At this point, it is up to you to create the missing logic. For
} instance, you could go to the database to retrieve the cus-
catch (Exception ex) tomer information and return it from the service. This could
{ be done any number of ways. For instance, you could use
LoggingMediator.Log(ex); Entity Framework or NHibernate to connect to a database.
return new GetAllCustomersResponse
{
Success = false,
FailureInformation = «Generic fault...»
};
}
}
}

Again, this implementation follows a standard pattern


that we use in all of our services (you could deviate if
you wanted to, but we don’t recommend it as this works
so well for us—well, you get the idea). Our operations
have a try/catch block that wraps all the code. The ser-
vice then implements its logic. In the GetAllCustomers()
method, the final goal is to send back a fully populated Figure 4: You do not have to manually install the
GetAllCustomersResponse object that contains all the CODE Framework. If you add project types that need
customers in the database. For that purpose, a response CODE Framework assemblies, you have the option to
object instance is created, then whatever code that needs retrieve them from CodePlex as needed.

50 CODE Framework: Building Services and SOA Business Layers codemag.com


Read CODE Magazine
on Xiine!

All You Can Read.


Now also on Android
and iPhone/iPad!
Read all your issues of CODE
Magazine and more in Xiine.
We now support your PC
as well as your mobile device,
both online and offline.
b
Download your free client today,
D
or read online at www.Xiine.com!
Maybe you have an existing business logic layer that you can now follow the instructions of any WCF book to host these
invoke. Or maybe you want to use optional CODE Framework services. Or, you can let the CODE Framework help and worry
data access components for this purpose. This decision is about many of these details later (if you are so inclined).
completely up to you. And note the following interesting as-
pect: The service contract provides a high degree of abstrac- One of the aspects of service hosting is that there are quite
tion. If you decide that you want to use a certain technology a few different ways to do it. Some of the choices for true
and it turns out to be a bad choice, it is easy to change this production deployment are somewhat of a pain to deal
implementation without any risk of breaking service callers. with during development. For instance, if you choose to
This also means that you can create quick-and-dirty imple- host services yourself in a Windows Service process, you
mentations or simulated implementations and replace those face a scenario that is a bit of a pain to debug. To alleviate
later with final code, and you are at no risk of causing the that problem, CODE Framework provides different ways to
caller problems. It is some nice extra insurance against im- host your services (and as mentioned above, you can use
plementation problems that might otherwise be disastrous. all default WCF hosting options as well if you like that bet-
ter). One of them is specifically geared toward development
For this example, we will hard-code the return value. scenarios, and that is what people usually start out with.
(Perhaps we will take a look at CODE Framework business
object and/or data access components in a future arti- To create a hosting project that is particularly suitable dur-
cle). Replace the TODO comment with the following code: ing development, add another project to the solution based
on the CODE Framework Service Development Host project
for (int x = 0; x < 100; x++) template. Once again, this template type analyzes the entire
Mapping { solution to find implemented services. You will see a dialog
response.Customers.Add( box, as shown in Figure 5. In this dialog box, you can choose
A task that is frequently
new CustomerQuickInformation all the services you would like in your development host and
encountered in services (both on
the server as well as the client) { the standards and protocols you want to support (note that
is mapping data from one object Id = Guid.NewGuid(), there is a practically identical dialog in the project template
or data source to another. This FullName = «Customer #» + x for Windows Service process hosting, which is a common fi-
task is tedious by hand and }); nal deployment choice for finished projects). In most scenar-
thus ideally added aided by } ios, you can accept all of these defaults and click OK, which
infrastructure. Although this creates a complete hosting project that requires no further
article doesn’t specifically discuss This populates the list of customers with 100 dummy re- work. All that is left to do at this point is to make this new
mapping, the CODE Framework cords, which will serve our purposes just fine in this ex- project the solution’s startup project and click F5 to run it.
provides a mapping mechanism ample. In fact, this might even serve us just fine as a first
that handles many common and step in a real-world service. Once we can provide this basic There are a few more details to point out. For one, if you
uncommon mapping problems. implementation, even though the data is bogus, this may run this project the first time, you will probably get a mes-
Example: You retrieve an invoice already be useful for the other part of the development sage from Windows asking whether you want to allow this
with three line items from a team that has to implement the interface. In early stages hosting operation. Confirm this message. The second issue
service, delete two line items, of development, this may be highly useful (although in you may run into is that the project does not start up cor-
add four others, and change the later stages not so much for the obvious reason of it be- rectly and instead shows a security-related error message.
remaining original item. The ing bogus data). In fact, this scenario is so common and If you see this, it is because some of the hosted endpoints
changes are then sent back to the allows teams to work in such a high degree of parallel run on a URL that includes “http://localhost/...” which
server which now needs to map
development that we are working on new features of the may already be otherwise handled by your operating sys-
that updated information back
framework that can generate this kind of dummy data au- tem and you are now effectively competing for the right to
to data entities. The mapper now
needs to detect that this isn’t just
tomatically as an initial step. Perhaps by the time you read handle calls to that domain. There are various ways to fix
a case of two added lines, but it this article, this feature may already be available. this problem. By far the easiest is to run Visual Studio with
needs to identify the two removed Administrator privileges (right-click the Visual Studio icon
lines, and add four new ones and You can add similar dummy code to the other three meth- and pick “Run as Administrator”).
correctly update the existing one ods that the service provides. (Or download the sample
without violating any business code associated with this article). The running development service host includes an in-
rules. In complex hierarchical terface that provides a way to see which services are
scenarios (with potentially nested And that’s about it! You have now implemented a fully running (Figure 6) as well as a way to call the services
collections), this is not as trivial functional version of our service, although with dummy (Figure 7 and 8). Having the service host window is very
as it sounds. Luckily, the CODE data and no real access to a true database (which is a
Framework mapping system can not insignificant detail in general terms, but rather ir-
handle these scenarios (and many relevant for the purposes of this specific article).
others) for you.

Hosting the Service for Development


Purposes
Now that you have the service, you need to make it available
in some way. In other words: You need to start it up so it
becomes callable. This is where things usually get a bit unfa-
miliar for people who have never created services before. You
have to create endpoints and specify protocols and bindings Figure 5: Creating a service host project with CODE
and set a plethora of parameters. And because the services Framework is completely automated through a project
you have created so far are standard WCF services, you can template and wizard that creates all required code.

52 CODE Framework: Building Services and SOA Business Layers codemag.com


part of the REST standard. If you want to follow all the
REST ideas, you can still do that with CODE Framework,
but you have to create a REST-specific service. However, if
you have existing services and want to make sure you can
call them from REST clients (such as JavaScript, iOS, or
Android clients), this approach works very well and pro-
vides great reusability of existing code. For this reason,
we find this approach very useful and straightforward.
And for developers using this approach, exposing these
services becomes as simple as picking a project template.
(The problems we had to solve to enable this were not for
Figure 6: The development service host UI showing the the faint of heart.)
service hosted using a variety of different protocols and
standards. Also noteworthy are the URLs that act as the endpoints
for the services. Because we have not provided any sort of
configuration, the hosting tools come up with smart set-
tings by default. These include a “dev” virtual directory
(which is generally a good idea to differentiate multiple
services that may run on the same computer), the name
of the service, and appropriate prefixes to make sure none
of the endpoints conflict with each other. Of course, all
of these settings are configurable. The project template
includes a default App.config file with commented-out
Figure 7: The development service host test bench allows
settings that you can change. In addition, all normal WCF
the simple invocation of service operations.
configuration settings work (although it is simpler to use
the more abstract CODE Framework settings). You also
convenient during development for a number of different have the option to hook into the code that creates the
reasons. For one, you can see all the different ways the host so you can impact every aspect programmatically.
service is hosted (in the example, the single service is Using CODE
hosted five ways. More about that below). You can also The final aspect we want to highlight here is the ability
see the URL (“endpoint”) that each service is accessible to place cross-domain calls to these services. This is im- Framework SOA
under, as well as a few details, such as whether a WSDL portant in various scenarios. For instance, Silverlight ap- Features, you can
endpoint is exposed and how large the messages (data plications can only place calls to services on other domains host a single service as
amounts) can be that are communicated to the service if those services explicitly support cross-domain calls. This XML Web Services, REST
(by default, WCF services allow for a relatively small means putting a ClientAccessPolicy.xml file into the root of
amount of data that is often not sufficient for business the Web Server hosting the service. One of the default op-
Services, and binary
applications, so the CODE Framework default increases tions in the template wizard allows for this, and if you ac- services, completely
the size somewhat, and can be configured). cept that default, you end up with a development host that interchangeably.
serves up an appropriate response when this file is request-
The various supported protocols and bindings are worth ed. (This file doesn’t exist, but is served up dynamically.)
a second look. If you have accepted all the defaults, the You can see that as the first item in Figure 6. In fact, you
service is now exposed as an XML Web Service using both can double-click that item to see the “file” in a browser.
basic HTTP and WS-HTTP standards. It is also exposed in
a binary fashion using TCP/IP, which is an interesting op- A similar issue applies when making a service call from
tion if you want to access the service from a .NET client. JavaScript in a Web browser. This time however, the
Furthermore, the services are hosted as REST services, cross-domain call is enabled by adding certain HTTP
supporting both XML and JSON data formats. headers to each response. This is a hurdle many devel-
opers have difficulty with, but they become non-issues
This last point may give you pause if you are familiar with with CODE Framework services, as enabling this type of
WCF services, and especially with REST services. In WCF, cross-domain call is enabled by picking that option in the
you create a service that is either REST or something else. wizard (Figure 5).
And for REST services, you pick either XML or JSON as the
data format. But those services cannot move seamlessly You can also see the code it takes to enable these fea-
between two non-REST formats or switch between XML tures in Program.cs of the generated project. Enabling
and JSON. Using CODE Framework, you can expose any cross-domain calls is as simple as the following two lines
service as REST and have the option to pick JSON or XML of code (with additional parameters allowing for further
as needed, or support both. fine-tuning):

If you are now scratching your head and wondering how host.AllowHttpCrossDomainCalls();
that works and whether that is even really possible fol- host.AllowSilverlightCrossDomainCalls();
lowing REST paradigms: We are exposing these services
as REST services that support POST operations. RESTafar-
ians may now point out that this is not following all the Taking the Services for a Spin
REST paradigms that should support other verbs and so
forth and they are absolutely correct! Mapping an exist- Now that you have your services up and running, how
ing service to REST in this fashion only supports and uses can you take them for a spin? Using the development

codemag.com CODE Framework: Building Services and SOA Business Layers 53


host, this is child’s play: Double-click one of the host back to the caller for security reasons, and are instead
items (Figure 6), such as the one listing the service using logged on the server. Using this development host, the
the TCP/IP (net.tcp) standard. This launches a test-bench host UI acts as a “log sink.” In other words: Everything
for the service, as shown in Figure 7. Pick the operation that gets logged using the logging components will au-
(method) you would like to call, which shows details of tomatically display in the host UI. This makes it easy to
the request contract. For instance, if you want to try the see logged details during development without having to
SearchCustomers() operation, you can see that it uses deal with systems such as the Windows Application Log.
a SearchCustomersRequest data contract that has three (Note: You can also double-click items to see a larger ver-
string data members (properties), which are all flagged sion of each message).
as being required. You can now type data into each of
those fields (because we are hard-coding the response, Also important for debugging: You can set breakpoints
the data you provide makes no difference in this exam- inside of your services as you would in any other .NET
ple, but would in the real world) and click Invoke to call application, as this service host is a simple local process.
Figure 8: The service call the service. The response is shown in Figure 8.
response from the development
host is shown in a visualization This provides a great way for developers to create ser- Calling Services
window. vices and immediately run them without having to create
a client application. In systems with a very large number For service developers, this just about wraps up the story
of services (as is common in real-world scenarios), this is and for the most part, it becomes a “more of the same” is-
a nice ability to have. sue. However, there also is the other side of the scenario,
which is the caller. Of course you also want to be able to
SPONSORED SIDEBAR:
Note that depending on the service endpoint, the test call the service easily. CODE Framework provides a large
Free and Open Source but bench behaves somewhat differently. For instance, if you number of features for the client-side as well, making it
Fully Supported choose a REST-based endpoint with XML formatted data, easy to call all kinds of services (including, but not limited
the result is shown as raw XML. Similarly, if you use JSON to our own services) from clients such as .NET, Silverlight,
CODE Framework is completely free formatted data, the response is displayed as raw JSON. and mobile applications, and JavaScript. This particular
and open source with no strings article focusses on the server side. Client-side service
attached. However, this does not
Technical note: All test-bench service calls use actual calls will be the topic of another in-depth article. How-
mean it is not supported! Feel
service infrastructure. For instance, if a TCP/IP service is ever, we want to provide at least a first glimpse of calling
free to contact us in case you have
called, the test-bench uses a TCP/IP infrastructure rather the service from one of the available client options. As an
any questions. We will not charge
you for answering a few questions than calling the object locally. Similarly, if you choose a example, we picked a new .NET Windows Forms client ap-
in email. For those looking for Basic-HTTP endpoint, that infrastructure is used, and if plication. (If you want to follow this example but make it
more sophisticated and hands-on you choose REST, a REST call is placed. This is important a bit more exciting, you can use the same code and put it
support, we also offer premium and somewhat complex to pull off, as it provides a real- into the WPF example we described in last issue’s article).
support options. world view of whether or not the service call works as
intended. A simple Windows Forms example will serve our purpose,
so we created a new project based on the standard .NET
Calling Services using the CODE Windows Forms template. The first default form created
also works well. You can add a data grid view control to
Framework is as easy and efficient as show the provided result.
calling a local object.
To call the service, use two CODE Framework assemblies
Another interesting aspect of making REST calls is that and the features they provide: CODE.Framework.Code.dll
as you want to place a call to a REST service, you need to and CODE.Framework.Services.Client.dll. To have access to
know the endpoint address (easily visible in the host UI) those, right-click the project References and browse to the
as well as the contract format and what that looks like location of those files (they are conveniently located in
exactly in XML or JSON format. This part is not as easily the _ExternalComponents/CODEFramework folder under
discerned. Using CODE Framework and this test bench, the current solution). In addition, you need to have a ref-
you can click the “Get XML” or “Get JSON” buttons to see erence to the contract you created, which you can do by
the XML or JSON representation of the input contract as it adding a reference to the contract project in the current
is currently displayed. For instance, the input as defined solution. (Note that you do not need access to the service
in Figure 7 translates to the following JSON, which could implementation as that remains on the server only!).
then be directly used in REST clients such as JavaScript: Finally, you need to provide some rudimentary configura-
tion so the client knows how to get to the desired service.
{ For this, add an App.config file to the project and add the
"CompanyName":"CODE", following config settings:
"FirstName":"Markus",
"LastName":"Egger" <?xml version="1.0" encoding="utf-8" ?>
} <configuration>
<appSettings>
This particular example is somewhat trivial. In real-world <add key="ServiceBaseUrl" value="localhost" />
scenarios, contracts can be quite complex and this particu- <add key="ServiceProtocol" value="NetTcp" />
lar feature has saved us a lot of time on many occasions. <add key="ServiceBasePath:ICustomerService" value="dev" />
<add key="ServicePort:ICustomerService" value="50000" />
Note that as services are called, exceptions may occur. As </appSettings>
mentioned before, those exceptions details are not sent </configuration>

54 CODE Framework: Building Services and SOA Business Layers codemag.com


This specifies that you want to use binary-optimized TCP/ efficiency, as they do not need any other running compo-
IP. The rest of the settings match the settings on the nents. CODE Framework provides a special project template
server-side that were chosen for you by default. It is im- that works nearly identically to the development host tem-
portant that these settings match so that the client and plate, but ends up creating a Windows Service host.
the server can find each other. If you want, you can also
pick other protocols since you are supporting five differ- One of the concerns people usually raise when it comes
ent ones on the host. to SOA is performance. Isn’t it much slower to call a
service than a local object? That concern is not without
Now you can go to the constructor of the form and use merit. Yes, it is quite a bit slower to call external servic-
a CODE Framework helper class called “ServiceClient” to es, especially when the call goes across the Internet. Of
Figure 9: A very simple example make a call to the service right after the call to Initial- course, this also provides significant advantages (such
client is written as a Windows
izeComponent(): as the ability to run in distributed scenarios as well as
Forms application.
good scalability and great maintainability and flexibil-
ServiceClient.Call<ICustomerService>(service => ity over time) but in some scenarios, raw performance
{ may still be an important consideration. For those sce-
var response = service.GetAllCustomers( narios, CODE Framework provides a special feature that
new GetAllCustomersRequest()); is not available elsewhere: In-Process hosting!

if (response.Success) “In-Process hosting” means that you build your applica-


dataGridView1.DataSource = tion in a SOA fashion and follow all the ideas of SOA, but
response.Customers; when it comes to deployment, you deploy in a more con-
SPONSORED SIDEBAR:
}); ventional fashion wherein the application includes the
CODE Framework Training DLLs that implement the service. Development-wise, this
Classes The ServiceClient class provides various ways to connect is not nearly as clean as true distributed deployment, but
to services. The Call() method allows specifying a type and on the other hand, it is no worse than an application that
CODE Training (CODE Magazine’s then passing the code that is to be executed. A very similar doesn’t use services at all. This way, all the services can
training division) continuously approach returns a reference to the service. There are quite be automatically invoked as local objects (this is simply a
schedules training classes for
a few variations on this theme that are beyond the scope configuration choice in CODE Framework) and thus have
CODE Framework (as well as many
of this article. The important part is: It becomes easy to exactly the same performance characteristics as all other
other topics of course), which can
call services. So much so, that it is as easy for developers .NET objects. (In other words, it’s very fast!)
be attended online or on-site.
Check out http://www.codemag. to make service calls as it would be to use a local object.
com/training for more details In many cases, you may choose a combination of deploy-
and a complete list of scheduled Now that your simple example client is done, you can launch ment options. Perhaps a service is deployed to a server as
training classes. both the client and the host at the same time (you can set a Windows Service process, which is called in a plethora
multiple startup projects in the solution properties). The re- of ways from .NET Windows apps, to Web apps, to JavaS-
sult of this simple example can be seen in Figure 9. cript, and mobile devices, but for the one scenario where
you need raw performance (perhaps for a sub-set of the
Note: In real-world scenarios it can sometimes happen that application, or perhaps for very specific scenarios) you
the host process is slower to start up than the client ap- create an additional deployment with CODE Framework
plication, in which case, the client application (that calls in-process activation to eliminate 100% of the perfor-
the service in the constructor of the first form) fails to call mance penalty normally associated with services. It’s a
the service (that hasn’t quite started up) and shows an er- very nice option to have.
ror. If you encounter this problem, put a wait-state (such
as Thread.Sleep) before your launch code. This is usually As you can see, there is a lot more to talk about that goes
not a problem with real-world clients, but sometimes test far beyond the scope of this article. However, with what
clients are very small and launch extremely quickly. you have learned in this article, you should now be able
to create services in a quick and productive fashion, and
In a future article in this series, we will take a closer look end up with a result that is more flexible and maintain-
at various service client options, from .NET (including able than most services built in the past. Furthermore, you
WPF) to Silverlight, Silverlight for Windows Phone, other do not have to worry about maneuvering yourself into a
mobile platforms such as iOS and Android, and of course dead end due to things you might want to do in the future
web applications, both in the form of ASP.NET as well as but are not yet aware of. With the approach demonstrated
JavaScript within HTML. here, you can add additional new features (such as secu-
rity) as the need arises. Feel free to send me an email if
you would like to discuss these further aspects.
Production Deployment Considerations
Markus Egger
Projects do not remain in development stages forever, and
at some point you have to start considering production
deployment options. You can, of course, deploy services
using standard WCF deployment options, such as hosting
in IIS or hosting in Azure. We often enjoy the option to
self-host services in Windows Services processes, which
provides full control over the services as well as the ulti-
mate freedom in hosting options. It also allows hosting of
services on servers with very small attack surface and high

56 CODE Framework: Building Services and SOA Business Layers codemag.com


Get oodles of free XAML clipart!

· Get thousands of cliparts free of charge!


· Get clipart in XAML Canvas and XAML Brush formats
· Use live tools to manipulate cliparts
· Styles, skins, templates, and shaders coming soon!
· SVG, JPG, PNG, BMP, GIF, and other formats
are also available!

www.Xamalot.com
ONLINE QUICK ID 1203071

Introducing a huMONGOus Database


Nowadays archiving, searching and processing the explosion of data generated in applications means coming up
with nontraditional ways of dealing with the data. NoSQL solutions offer intriguing and unique ways of handling
the volumes of data available to us. Additionally, 10Gen offers an open source distributed document-oriented

solution called MongoDB. MongoDB straddles the quick lookup and management capabilities for your Mon-
NoSQL space nicely. A low barrier to entry and great goDB system.
performance help MongoDB continue to gain followers.
However, like all database solutions, MongoDB will not MongoDB uses JavaScript in the MongoDB shell. Every-
solve all of your problems. You need to know when and thing done in the shell will be JavaScript. When you en-
how to use it properly and more importantly, when not ter a command without the parenthesis the code for the
to use it. command displays. Having the ability to use JavaScript
can be really powerful whether you are writing MapRe-
duce queries or creating custom functions you want to
Mike Benner Oddly Familiar use in the shell.
me@mikebenner.com
http://mikebenner.com MongoDB stores your data in documents using a JSON-
https://twitter.com/#!/refried
chicken
style syntax known as BSON (binary JSON) making it a Installation
part of the document-oriented class of NoSQL solutions.
Mike Benner is CTO of Author- This article uses Mongo 2.0.2 for all of the examples, but
ityLabs where he gets to play anything over 2.x should work. You can download the lat-
with large amounts of data MongoDB is considered a
est version from http://www.mongodb.org/downloads.
and technologies. He is also a document-oriented datastore and The MongoDB shell that comes bundled in the download
technology mentor for Gang- it stores those documents in a will be sufficient for all examples.
plank and heads the Gangplank
Jr Initiative and coaches their
JSON-style syntax called BSON
(binary json). After downloading and unzipping the binary you will
robotics team.
need to create a path for the data to be stored. The de-
http://authoritylabs.com
fault location is /data/db. MongoDB does not create this
http://gangplankhq.com
Document-oriented solutions can take some getting directory, so you need to create it yourself. After you’ve
used to. Traditional RMDBS systems house their data created the directory you can start MongoDB by simply
in very well-defined schemas which are represented as calling:
tables. Each table definition is comprised of various
columns which effectively define the data model in /path/to/mongofiles/bin/mongod
that RMDBS system. Each time data is inserted into a
table, a new row is created. This data can be queried, If the installation went as it should, MongoDB is running
updated, deleted and inserted using Structured Query and the real fun begins.
Language (SQL). MongoDB, on the other hand, does
not store its data in tables; MongoDB stores its data
in collections. MongoDB collections are comprised of One Document to Rule Them All
JSON documents instead of rows. Documents consist
of key/value pairs – essentially a JSON hash. Unlike The examples will use Major League Baseball players and
traditional RDMBS systems which adhere to a strict their statistics. The database will be named mlb and con-
data schema, Mongo does not have a strict data sche- tains a collection called players. The documents in players
ma. MongoDB doesn’t care if you have a key/value pair hold the individual player details and statistics.
in one document but not in another. Each document
can contain its own data structure (if needed) in the All of the examples in this article will use the MongoDB
same collection. See Listing 1 for an example of the shell that comes bundled with the download. The shell
flexibility in action. uses JavaScript for all commands and functions.

An example of schemaless flexibility, Listing 1 has four Now you’re going to start the Mongo shell so that you
MongoDB documents that reside in the same collection. can interact with the MongoDB instance. To start the
Each document has an _id and name key, but the similari- MongoDB shell, open a terminal/command prompt and
ties stop there. A couple of documents contain a platform navigate to the location in which you installed MongoDB.
key. One document has a Twitter key and some have oper- Then type the following commands:
ating_system and homepage keys.
/path/to/mongofiles/bin/mongo
A powerful command-line shell comes bundled with use mlb;
MongoDB. You use the MongoDB shell for managing the
server, setting up authentication and everything else you This launched the Mongo shell, created a new database
need. Third-party graphical administration tools do exist named mlb and switched to that database. Using the db
for MongoDB and you’ll find them at http://www.mon- command before each method call tells MongoDB to ref-
godb.org/display/DOCS/Admin+UIs. These tools provide erence the mlb database.

58 Introducing a huMONGOus Database codemag.com


Listing 1: Sample Mongo documents
{ {
"_id" : ObjectId("4f06168ab00ccb47b436d0b9"), "_id" : ObjectId("4f06168ab00ccb47b436d0b7"),
"name" : "Fang of Mongo", "name" : "MongoExplorer",
"platform" :"web", "platform" :"silverlight",
"twitter" : "@fangofmongo" "operating_system" : ["windows","mac osx","linux"]
} "homepage" : "http://mongoexplorer.com"
}
{
"_id" : ObjectId("4f06168ab00ccb47b436d0b8"), {
"name" : "JMongoBrowser", "_id" : ObjectId("4f06168ab00ccb47b436d0b6"),
"platform" :"java", "name" : "MongoHub", ,
"operating_system" : ["windows","mac osx","linux] "operating_system" : ["mac osx"]
"homepage" : "http://edgytech.com/jmongobrowser" "homepage" : "http://mongohub.todayclose.com"
} }

You will now create a new collection and insert a new Listing 2: Inserting additional players
JSON document into that collection. In your terminal/
db.players.insert({
command window, enter the following:
name: "Miguel Montero",
age: 26,
db.players.insert({
bats: "left",
name: "Harry Blanco",
throws: "left",
age: 40, years_played: [
bats: "right", {year: 2011, team: "Arizona
throws: "left", Diamondbacks"},
years_played: [ {year: 2010, team: "Arizona
{year: 2011, team: "Arizona Diamondbacks"}
Diamondbacks"}, ]}
{year: 2010, team: "New York Mets"} );
]} db.players.insert({
); name: "Konrad Schmidt",
db.players.find(); age: 27,
bats: "right",
You have now created a collection named players and throws: "right",
inserted a document with the details of Harry Blanco. years_played: [
MongoDB does not require a predefined schema so your {year: 2011, team: "Arizona
collection was created for free just by referencing it in Diamondbacks"},
the command. Similar to the flexibility with key/value {year: 2010, team: "Arizona
Diamondbacks"}
pairs in documents, you can just as easily create new col-
]}
lections. The flexibility of schemaless design comes with a
);
caveat; typos will create new collections or keys if you are
not careful. You can see your new collection by entering
the show collections command. query against those embedded documents and create in-
dexes on keys contained within them.

Retrieving Documents
Diving for Data
db.players.find() returns all the documents in the col-
lection. In our case we only have one document to re- Go add a couple more players (Listing 2) to the mlb col-
turn. If you look at the output you will see a key we did lection. After inserting the additional documents, run
not insert labeled _id. _id refers to the MongoDB Objec- db.players.count() in the console/terminal to return the
tId that is assigned to all of your documents. Think of it total number of records in the collection.
as incrementing the primary key field in a SQL system.
This ObjectId gets created using a combination of items db.players.count();
which go beyond the scope of this article, but have to
do with MongoDB’s clustering and sharding capabili- The shell simply shows 3. Now how about all of the play-
ties. ers that bat right-handed?

MongoDB does not support joins like a typical SQL solu- db.players.find({ bats: "right"});
tion. Instead MongoDB uses embedded documents. Our
insert command contained an array of embedded docu- The query returns two documents containing Harry and
ments called years_played. Embedded documents allow Konrad. What about players that played in the year 2011?
you to make a single query and return all the data back
without joining to other tables. Even better, you can db.players.find({ "years_played.year": 2011});

codemag.com Introducing a huMONGOus Database 59


As mentioned earlier in the article, you can query by keys the rest. Look up Miguel and you will see the age and throws
contained in embedded documents. In this instance you values updated while leaving the existing data intact.
use years_played.year to dig down into the embedded
documents located at years_played key and look for the Passing a true flag in at the update function tells MongoDB
child key year. What if you wanted to know who played on to do something called an upsert. Like it sounds, an upsert
the Diamondbacks in the year 2010? You may be tempted performs an update or an insert if the document is not
to write this: found. Upserts are atomic and useful in a system where pro-
cesses can be modifying and creating items at the same time.
db.players.find({
"years_played.year": 2010, db.players.update(
"years_played.team": "Arizona Diamondbacks" {name: "Geoff Blum"},
}); {name: "Geoff Blum",
age: 38,
If you ran the query above you would notice it returned bats: "right",
all three players. Unfortunately this is not what you throws: "right",
want and you know from our previous queries that Harry years_played: [
Blanco played for the Mets in 2010. The previous query {year: 2011, team: "Arizona Diamondbacks"},
returns all three players because each of them meet at {year: 2010, team: "Houston Astros"}
least one of the criteria requested. Getting the correct ]},
results requires use of a special operator. true
);
MongoDB offers several features for more advanced que-
ries, including the $elemMatch operator. $elemMatch Run the code above and run db.players.find(). A new docu-
ensures the documents returned match all of our criteria. ment containing Geoff Blum and his details will be returned.
Now try that query again using the $elemMatch operator. Assume that you made a mistake in your initial insert and re-
alized that Geoff Blum actually bats switch so you’ll want to
db.players.find({ run that command again but change him to a switch hitter.
"years_played":{
$elemMatch: { db.players.update(
year: 2010, {name: "Geoff Blum"},
team: "Arizona Diamondbacks" {name: "Geoff Blum",
} age: 38,
} bats: "switch",
}); throws: "right",
years_played: [
That’s better. The query now returns only Konrad and {year: 2011, team: "Arizona Diamondbacks"},
Miguel as expected. You can find a list of the features {year: 2010, team: "Houston Astros"}
offered for more advanced queries at http://www.mon- ]},
godb.org/display/DOCS/Advanced+Queries. true
);

Updates, Upserts and Document Replacement Query your collection again and you will see he was not
added a second time but his record was updated to reflect
Updating documents in your collection is not as straight his ability to switch hit.
forward as in SQL. For example, if we wanted to correct
Miguel Montero’s age to 28 and that he throws right
handed, we can’t simply do this: House Cleaning
db.players.update({"name": "Miguel Montero"}, For most developers and DBAs, learning MongoDB re-
{age:28, throws: "right"} quires a paradigm shift and learning to think about
); things differently can cause you to make mistakes, but
they are easy enough to clean up in MongoDB. The re-
The document-oriented nature of MongoDB causes the move command will let you delete documents based on
update to replace all the values in the current document the criteria you provide. For example, you can remove
with completely new values, removing keys you did not Miguel Montero with the following command:
provide in the update. MongoDB replaces the document
because it does not track the key/values in the document db.players.remove({"name": "Miguel Montero"});
like a RDBMS does for columns. Using another special
operator, we can avoid replacing the whole document. Not using any criteria will cause all records to be re-
moved.
db.players.update({"name": "Miguel Montero"},
{$set: {age:28, throws: "right"}} db.players.remove();
);
Or you can just drop the whole collection.
The addition of $set in the update function informs Mon-
goDB to update the keys in the document and not to remove db.players.drop();

60 Introducing a huMONGOus Database codemag.com


All Star Lineup of Advanced Features Capped Collections

MongoDB goes well beyond being a document-oriented MongoDB has a feature called
data store with special tricks for accessing and updating capped collections that enables
your data. For example, MongoDB has built-in cluster- you to build a collection that is
ing called Replica Sets. MongoDB also has the ability to limited to a specific size. A capped
Shard across multiple servers and allows you to write Ma- collection is a performant First
In First Out collection (FIFO) that
pReduce functions.
can be useful in situations such as
logging.
Replica Sets are a solution in which three or more servers
operate with a single primary and multiple secondaries/ You can update documents in
arbiters. If you lose your primary for any reason, a vote a capped collection but that
will take place and one of the secondaries will be pro- document will still be removed
moted, minimizing downtime and data loss. While you based on the order that it was
can always run MongoDB in a standalone solution, you inserted.
should always use a Replica Set in your production en-
vironments. You cannot remove documents
from a capped collection. They
When your app collects more data than you know what are removed automatically as the
to do with you will find yourself needing to shard across collection hits its storage limit.
multiple servers. MongoDB gives that option to you out
of the box. The sharding capabilities of MongoDB makes
scaling to handle your growth easy by setting up multiple
Replica Sets and spreading your data across them with
relative ease. Sharding can be useful when your inserts
are coming faster than your disk can handle, when your
collection reaches MongoDB’s 10TB collection limit or
you need more performance for reads and need to share
the load across servers.

MongoDB’s MapReduce functionality takes input from


one collection and dumps the results out in another.
You can use MapReduce for batch processing, data ag-
gregation and performing analysis across large data sets.
Write your MapReduce functions in JavaScript and you
can have them included by default when launching the
Mongo Shell.

You can find more information on all of these features and


more at http://www.mongodb.org/display/DOCS/Home

Where to Next?
I encourage you to look through the operators linked to
earlier and see what other queries you could run. Mon-
goDB allows JavaScript, so be creative. It takes time to
really grasp the doors MongoDB opens. Look at your ex-
isting apps and imagine how you could structure your
data in MongoDB.

Mike Benner

codemag.com Introducing a huMONGOus Database 61


ONLINE QUICK ID 1203081

Smashing the Myth:


Why You Must Learn F# – Even If You
Aren’t Writing Rocket Science Apps
If you are a .NET software developer, you have heard of F#. You may have read an article, seen a talk at a user
group, or otherwise heard the buzz. However, if those means of reaching you have failed, at the very least,
you have noticed it conspicuously appear in the list of languages you can base a solution on in Visual Studio

2010. If you write code on the .NET Framework, you public class Invoice
would have to be living under a rock to have not heard {
of F#. public LineItems InvoiceLineItems { get; set; }

So you know it’s there – the question really is, what is it public void ProcessLineItems()
useful for? Why do you need another programming lan- {
guage? Is C# not good enough? Conventional wisdom has //what if LineItems is null?
told us that C# is what you use for line of business apps, foreach(var item in this.InvoiceLineItems)
and that you only use F# for scientific apps, heavy math {
Aaron Erickson apps, or apps that do monte-carlo simulation. Strangely //process each lineitem
Website: http://nomadic- missing from that list are apps that you and I are likely to }
developer.com/ be asked to write. F#, according to some, is like the One }
Twitter: AaronErickson
Ring to Rule Them All – all powerful, but so dangerous }
Aaron Erickson is a technology that it must be kept under lock and key!
writer, software developer and In this example, Invoice contains an implied contract.
consultant at ThoughtWorks. Specifically, it states that InvoiceLineItems will be ini-
His life’s work is helping
F# isn’t just for Wall Street; tialized before someone tries to call ProcessLineItems. Of
convert the best human capital it is a compelling technology for course, one can fix this code rather easily:
into results for companies that Main Street as well.
empower both the knowledge public class Invoice
workers who produce software, Balderdash, I say, to those who want to keep the power {
and the people in the compa- of F# locked up inside of research labs, universities and public LineItems InvoiceLineItems { get; set; }
nies whom we serve. hedge funds. Power to the people! F# isn’t just for Wall
Aaron frequently speaks at Street; it is a compelling technology for Main Street as public void ProcessLineItems()
events such as TechEd, VSLive, well. In this article, I will cover specific reasons, with {
and .NET user groups – with examples, that demonstrate why you should learn this if (this.InvoiceLineItems != null)
a goal of furthering the language and advocate for its adoption. {
exchange of ideas – be they //Now we guarantee that LineItems isn't null
technology contributions – or foreach(var item in this.InvoiceLineItems)
observations about the tech- The Evils of Null – Use F# to Set Yourself Free {
nology consulting business. From NullReferenceException Console.WriteLine( item );
}
If you have written any non-trivial amount of code, and }
actually seen such code through to production, you have }
likely had to deal with the dreaded NullReferenceExcep- }
tion. It is one of the most common types of Exceptions,
particularly in production. It is also one of the hardest to Now at least we do not throw the NullReferenceExcep-
track down, particularly in complex systems with lots of tion. However, we have also added “code-noise” making
moving parts. the code harder to understand at a glance, adding three
lines that are there purely due to the fact that the object
The Source of NullReferenceException may be ill constructed at the time of the line items being
processed.
A very common cause of NullReferenceException is failure
to fulfill an implied contract. Much like a married man Now lets look at this from the F# point of view:
who gets in trouble for not getting the implied flowers
that are due on an anniversary, systems get in trouble type Invoice = { InvoiceLineItems : LineItems }
when they expect a value to exist in, say, a member vari- with
able, but none does, causing the offending NullRefer- this.ProcessLineItems() =
enceException: this.InvoiceLineItems |> Seq.iter (

62 Smashing the Myth: Why You Must Learn F# – Even If You Aren’t Writing Rocket Science Apps codemag.com
fun item -> Console.WriteLine( item ) invoice is to be paid to the normal address. It is not un-
) common to have fields like this that are optional – and it
is common that programmers will use null as a sentinel
Certainly, the syntax is different. Here, in F#, we use the value to represent the idea of “value not provided.” How
type keyword to define an F# record – a concept with cer- does F# handle such a situation if null is not allowed?
tain similarities to a C# class, but some really important
differences. The properties of the record get defined in the type Invoice = { InvoiceLineItems : LineItems;
braces that follow – the part that reads { InvoiceLineIt- BillToAddress : Address option }
ems : LineItems } (note, I called the property InvoiceLi- with
neItems purely for clarity of type versus name when com- this.ProcessLineItems() =
paring the syntaxes – one could just call the property Lin- this.InvoiceLineItems |> Seq.iter (
eItems as well for brevity). The part after the with state- fun item -> Console.WriteLine( item )
ment is where you can define methods for your record, like )
we do here with ProcessLineItems. The implementation
of the method then passes the InvoiceLineItems to Seq. If something is optional, in F#, you use the option key-
iter, which takes as its parameter the thing that should be word after the type name to indicate that you can have
done to each individual item when iterating. zero or one address. Great! But have we re-introduced
null? Not so fast:
That all said, do not let the syntax make you think F# is
hard. It is certainly different, particularly coming from //with a bill to
“curly-brace centric” languages like C#. Once you get let myInvoice = {
used to it – usually after a couple weeks of working with InvoiceLineItems = someLineItems;
the language – it will feel far more natural. BillToAddress = Some(myOtherAddress) }

The more important part of this example is what, as an //without a bill to


F# programmer, you do need to do. Notice that in F#, I let myOtherInvoice = {
did not do the null check. That is because in F#, you can’t InvoiceLineItems = otherLineItems;
set the elements of a record to null: BillToAddress = None }

//this won’t compile In the first example, where myInvoice is initialized, we


let myInvoice = { InvoiceLineItems = null } set the address to Some(myOtherAddress). In F#, options
take either a Some(T), where T is the underlying type of
In F#, you are not allowed to build objects that are in- the object, or they take None, as the second example
complete. If you are going to have an Invoice, you must demonstrates.
have InvoiceLineItems – even if the set of InvoiceLineIt-
ems happens to be empty. Incomplete, ill-initialized ob- None and Null – Same Thing?
jects are a large source of bugs in systems programmed in
C# or other imperative languages. In F#, creating these An astute observer might recognize that None is mysteri-
sorts of bugs is far, far more difficult. ously similar to null. However, the important distinction
here is that None can only be used where the author of
What about Optional Fields? the type has specifically allowed it to be used. By con-
trast, in C#, null is the default value of all objects. This
Of course, there are times when null is used to represent is the key – by severely limiting the scope over which
a lack of something. For example, let’s add something to absence can be represented, allowing it only where such
our invoice: absence is a valid state – you simplify your objects. You
create fewer possible states of your object, you reduce
public class Invoice the “surface area” you have to test and you make it far
{ less likely that you will leave something as null on acci-
public LineItems InvoiceLineItems { get; set; } dent. This leads to vastly fewer NullReferenceExceptions,
public Address BillToAddress { get; set; } and ultimately, more stable software.

public void ProcessLineItems()


{ F# Could Have Saved the US Government 125
if (this.InvoiceLineItems != null) Million Dollars
{
//Now we guarantee that LineItems isn't null In 1999, the world was excited as NASA was on the verge
foreach(var item in this.InvoiceLineItems) of a new round of exploration for the planet Mars. Only
{ one problem – the probe, worth an estimated 125 mil-
Console.WriteLine( item ); lion dollars, crashed, because a programmer mixed up
} metric and imperial units. Could F# have helped solve
} this problem?
}
} A C#-Based Clothing Recommendation Engine

In the case above, we have added an optional field – Bill- Perhaps so, perhaps not. F# will not will stop you from
ToAddress. Lack of a BillToAddress may indicate that the writing bad code that crashes orbiters. However, it does

codemag.com Smashing the Myth: Why You Must Learn F# – Even If You Aren’t Writing Rocket Science Apps 63
give you tools you can use to help avoid this class of let recommendationForFreezingWeatherWrongAgain =
problem should you choose to use these tools. Consider clothingRecommendation 32m<farenheight>
this example one might use in a piece of software that
recommends what to wear given certain weather condi- //but this will work!
tions: let recommendationForFreezingWeatherRight =
clothingRecommendation 0m<celsius>
public enum Clothing { Parka, Jacket, Shirt, Bikini }
In doing this we have done two important things. The
public class ClothingRecommendationEngine most obvious is that we have avoided a bug – the old code
{ would have left you outside in freezing weather wearing a
public static Clothing DoRecommendation(decimal t) bikini. The F# code recommends a nice, warm coat instead.
{ This alone makes it a win! But more importantly, the new
if (t < 0m) return Parka; version of the code is more clear. Before, the reader would
if (t < 15m) return Jacket; have had to look all around the rest of the code to infer
if (t < 30m) return Shirt; what units were expected. This new version makes the ex-
return Bikini; //unless your legs are hairy pected units much more explicit. The API of the F#-based
} recommendation engine requires much less guesswork.
}
This is no small thing. In any non-trivial piece of code, we
This is rather straightforward – based on the tempera- deal with numeric concepts. Most interesting software
Learn More about F# ture, recommend a given type of clothing. Upon closer deals in things that have numeric units – money, time,
inspection, you will notice that the algorithm assumes inventory or any other thing that we may count.
You can learn more about F#
online by visiting the HubFS
you are providing the temperature in Celsius. Imagine a
community at http://cs.hubfs. programmer in, say, Belize or the Cayman Islands, two of
net/, or by trying F# online at three countries that have yet to convert to Celsius. You F# Will Save You from Mutation
http://www.tryfsharp.org/. If you might end up doing this:
would like to take a deeper dive, Mutation – variables in your code may not be the root of
we recommend Professional F# 2.0 var recommendationForFreezingWeather = all evil, but they are close. Granted, they are a necessary
by Aaron Erickson, Ted Neward, ClothingRecommendationEngine.DoRecommendation(32m); evil for a small subset of problems. But I am not too far
Richard Minerich, and Talbott off when I say that variables, as we know them in C#, are
Crowell, available on amazon. In the event that it’s freezing someday in Belize, your like little demons inside your codebase that make it bug-
com (http://www.amazon.com/ software may be perceived to have a bit of an issue! gier and harder to maintain.
Professional-F-2-0-Ted-Neward/
dp/047052801X). Will F# Save Me From Freezing in Belize? Programming Without Variables? Are You Nuts?

“Units of measure” is the concept in F# that solves this The problem with variables is that they vary. Borrowing an
type of problem. We can rewrite the C# version using F# analogy from mechanical engineering, they are the moving
as follows: parts of your software. Any machine that does much needs
moving parts. However, any mechanical engineer worth her
type Clothing = Parka | Jacket | Shirt | Bikini salt does everything she can to reduce to the bare minimum
[<Measure>] type celsius the number of moving parts in a given machine. Doing so
reduces the number of things that can go wrong, reducing
let clothingRecommendation (temp:decimal<celsius>) = the amount of maintenance a given machine needs.
match temp with
| t when t < 0m<celsius> -> Parka Software is no different. You want as many moving parts
| t when t < 15m<celsius> -> Jacket (variables) as absolutely needed, but no more than that.
| t when t < 30m<celsius> -> Shirt Let’s look at a common example, a Money class:
| _ -> Bikini
public class Money
The code has many similar concepts, with a key differ- {
ence being the [<Measure>] type Celsius line, and the public string Currency { get; set; }
associated parameter temp that takes on what, to a C# public decimal Amount { get; set; }
programmer, looks like a generic specification. In fact, }
you can read it the same way – just as you would have
a List<T> in C#, in F#, you can have a decimal (or other Despite this being a small class, this code has far too
numeric type) of M, so long as M is a unit of measure. many moving parts. The first thing that needs to be done
is that we need to make sure that when this object is
So how does this help? The consumer of the function will created that both Currency and Amount have valid values
not be able to just pass any number to the recommenda- upon creation:
tion engine:
public class Money
//this will yield a compile failure... {
let recommendationForFreezingWeatherWrong = private Money() {} //remove parameterless cons
clothingRecommendation 32m public Money(string currency, decimal amount)
{
//as will this... Currency = currency;

64 Smashing the Myth: Why You Must Learn F# – Even If You Aren’t Writing Rocket Science Apps codemag.com
Amount = amount; have to go against a lot of established C# convention (no
} automatic properties for you!), and write lots of extra
public string Currency { get; set; } code. In F#, our Money class is as follows:
public decimal Amount { get; set; }
} type Money = { Currency : string; Amount: decimal }

This is a good first step. However, there are still too many Yes, that is one line of code. If you are being paid by line
moving parts. Changing currency should not be possible of code, this may not make you particularly happy. How-
without changing the amount, since a currency change ever, if you care about productivity and making it easier
implies an amount change outside of a rare case of a 1:1 to do the right thing, you probably should consider F#.
currency conversion ratio. We need to change the code to The F# difference isn’t that it lets you write immutable
enforce that constraint: code – you can do that in C# with a lot of work. F# makes
it simpler to do so, which results in more code being right
public class Money by default, which is a net win for your development team.
{
private readonly string _currency;
private Money() {} You Don’t Need to Understand Monads
public Money (string currency, decimal amount)
{ Notice that in this article, not once did I mention the
_currency = currency; word monads. One of the biggest reasons that F# has a
Amount = amount; reputation as a “hard to learn language for people with
} too many IQ points” has nothing to do with the language
public string Currency { get { return _currency; } } itself, but the functional programming community. Many
public decimal Amount { get; set; } of these people, God bless them, work in environments
} where the word monad has as clear of a meaning that the
word beer has to the rest of us. To these folks, catamor-
The improved version now has a _currency as a readon- phism is a word to be used in normal parlance. Nothing
ly property, which enforces a constraint that you can’t wrong with that – these folks do a great job pushing the
change the currency of an existing amount of money. It envelope and inventing things. We would not have things
is one less moving part – one that should never move in like Google, Pandora, or Siri without them!
the first place (i.e., if you want something as a differ-
ent currency, create a new Money object after doing a However, just as we took things from NASA and the Space
conversion). Program and integrated them into technologies that help
us on a day-to-day basis, we need to capitalize on the
While the design is improved, frankly, I am still a bit best technologies that come from our research labs. F#
paranoid. In a large system I could, in theory, pass my is one of those things – once a product of Microsoft Re-
money to some function out there, it could store a refer- search, it sits on your desk in Visual Studio 2010, ready
ence to me, change my amount later, and without some for you to write less buggy, more stable software with it.
explicit checks, I may not know it. To solve this problem, The next move is yours – load it up in Visual Studio 2010,
I can make the class immutable in C# as follows: or even consider trying it out on the web at http://www.
tryfsharp.org/. Either way, you will quickly be on your
public class Money way to enjoying its many benefits.
{
private readonly string _currency; Aaron Erickson
private readonly decimal _amount;
private Money() {}
public Money (string currency, decimal amount)
{
_currency = currency;
_amount = amount;
}
public string Currency { get { return _currency; } }
public decimal Amount { get { return _amount; } }
}

With all that work done, I can proceed along my merry


way. My class is nearly 100% immutable, outside of per-
haps something changing my internals via reflection or
changes to internals that occur during the execution of
the constructor. Close enough for now – though it took
a lot of coaxing.

F# - The Immutability Lover’s Best Friend

In C#, you can do immutability, but you will work for it.
Every time you want to make something immutable, you

codemag.com Smashing the Myth: Why You Must Learn F# – Even If You Aren’t Writing Rocket Science Apps 65
Post Mortem: Xiine for iOS
In the Sept/Oct 2011 issue of CODE Magazine, I wrote about Xiine for Android. Let me remind you that
Xiine is an electronic reader application for CODE Magazine. It was originally written in C# using WPF and is
based on SOA architecture. With this software, all subscribers (it’s free) can read CODE Magazine issues

on a PC. You can download Xiine at http://www. Like logging in and choosing a brand, there is
xiine.com. minimal difference between the Android and iOS
versions for choosing an article from the list.
Xiine is popular for digital content. There are
desktop, Web, WebOS, and of course, the Android There wasn’t much work to do to write the code
edition, which is now being distributed by An- for the interface because we could base the iOS
droid Market and Amazon Marketplace. on the Android code that already existed.

There was one platform missing, though: the iOS Because we already had the Android version, we
version. That’s the reason we decided to write didn’t need to worry about layout and how the
Xiine for iOS and share this new experience. objects would fit in different screen resolutions.
Because CODE is a magazine, the same version We already had the layout set and even though
should be supported on both the iPod Touch/ Objective-C was a brand new language for us, it
iPhone and the iPad. Figure 1: The architecture for Xiine service is simple. was learnable.

Xiine for iOS was CODE’s very first Apple project we could have the same simplicity and functional-
and we passed through some roadblocks. ity: Enter the user name and password. Because we already had
the Android version, we didn’t
We wanted the users to have a good UI experi- After the log in, the user can see the available need to worry about layout and
ence, just like the Android version so we made a brands (see Figure 2). The iOS version is much how the objects would fit in
list of goals: the same as the Android page and shows the title
and description on the list. different screen resolutions.
• Authenticate Xiine users.
• List available brands and respective issues. After the brand is chosen, a list of magazine Just like when we built the Android version, the
• Make clean and intuitive screens. issues with complete information is displayed usage of the JSON library was one of the most
• Display user information. when a magazine is clicked (Figure 3). It’s a important parts of the project, as all the infor-
• Enable reading articles. little bit different on the iOS version, but not mation needed was available from a WCF service.
• List already read articles. much. Also, we had already made the changes needed
• Zoom in and out on an article page.
• Save a history of what has been read.
• Use up minimal code-writing time.

What Went Right


Because we’d already done a lot of technological
work, this project seemed fairly painless.

The Architecture

We took advantage of the existing architecture


for the Android project.

The architecture is very simple (Figure 1):

1. Apple devices access the REST service at xi-


ine.services.com, requesting a JSON object.
2. The REST server responds to the device,
which understands the JSON object and con-
verts it into real information.

Creating a Similar User Interface and Re-


using Code
The login screen on the Android version should be
similar to the iOS version. Due to different resolu- Figure 2: These are available brands as viewed Figure 3: This is a list of magazine issues on
tions, it’s not possible to be exactly the same, but on the iPhone. the iOS.

66 Post Mortem codemag.com


Xiine for iOS as a Challenge
Xiine is all about reading digital content. The real
challenge was delivering a nice user experience for
small devices, such as smartphones.

We wanted to make sure that the user has a great


experience and with just a few lines of code, we can
detect whether the they have an iPhone or an iPad.

one interested in making multiple pages must


write a new engine. Unfortunately, that’s not an
easy task to accomplish and it’s one of advan-
tages of the desktop edition that was written in
WPF (Figure 4).

Memory Management

It’s not that the memory management didn’t go


well. But we did need to be careful when using vari-
ables or instantiating objects. Unlike C#, we had
to allocate and de-allocate memory manually. Ob-
jective-C doesn’t have a garbage collector and the
software can crash if you don’t de-allocate properly
or if you forget to release an unused object.

Figure 4: The paging system of Xiine for the desktop.


Summary
for the Android version, so we didn’t have to Things That Went Wrong Using existing services was a big deal! We could
touch a single line of code! take advantage of the whole service for either
Okay, so nothing’s perfect. There were a few the Desktop or Android version to build features
Easy Tools things that might have gone better. without having to write any extra lines of code on
the server side.
X-Code is easy to use even if you’re new to it. It Gotta Get a Mac
includes a complete set of tools to run, build, and The iOS itself has a large knowledge base easily
debug programs. If you want to write applications for iPhone/iPod available from the community. We found libraries,
touch or iPad, you need to have a computer that samples, and code to run HTTP calls, consume REST
Like Android, iOS has SQLite built in. And al- runs Mac OS, although there is a way to emulate services, handle JSON objects, etc. In the beginning,
though SQLite is not a professional database, it the Mac OS on a PC. We have tried this emulation we thought the iOS development would be hard to
does what it says it will: It stores information. method and it works. But it doesn’t have all the learn and understand – not so! Because C# was the
It’s also very easy to configure and use. Because same features as the real thing and it is not very primary language, memory management was one
it’s a light version, you don’t have to worry about stable. It freezes once in a while. And because it’s of the biggest challenges, because your system can
special field types. The most complicated type is an emulation, sometimes it was really slow. So we crash if you don’t handle it appropriately.
the BLOB, and even that is straightforward. We had to buy a Mac.
used SQLite to store the history feature. We are now certain that we can implement ex-
Coding actly the same features on either Android or iOS.
Local and Remote Repositories Each has different ways to accomplish the same
Coding was the largest roadblock because Ob- results, but in the end, it will hit the target.
Mercurial is a local repository where you can keep jective-C is not C#. We were very tempted to use
track of changes. You can get specific versions, alternative tools such as MonoTouch, but decided Milton Abe
commit, delete, merge, and so forth. NOT to because most iOS developers don’t and mabe@eps-software.com
this it would have been non-standard iOS devel-
BitBucket is a remote repository, where you can opment. Also, there were some legal issues re-
store and share source code to everyone or to a garding the use of this tool in the past.
specific group or person. X-Code source code was
easily stored on BitBucket, just like the Android
version. Coding was the
largest roadblock because
Using the iOS Emulator Objective-C is not C#.
Unlike the Android emulator, X-Code has an awe-
some emulator! It is fast and reliable. You might Pagination
wait at a full minute to start debugging on An-
droid emulator, but X-Code launches and runs the Just like the Android version, iOS does NOT sup-
emulator instantly. port pagination natively. This means that every-

codemag.com Post Mortem 67


ONLINE QUICK ID 1203091

ASP.NET MVC 4 Highlights, Part 1


Microsoft released ASP.NET MCV 3 just over a year ago. If history is a good indicator of timing, we can expect the
next ASP.NET MVC release in the not too distant future. As of this writing’s date, Microsoft has not announced a
firm release date. You don’t, however, have to wait to get your hands on the bits. You can download the developer

preview here: http://www.asp.net/mvc/mvc4. ASP.NET MVC out page. Structurally, it is very similar to ASP.NET MVC 3.
4 also runs inside of Visual Studio 10 and the Visual Studio In ASP.NET MVC 4, you will see a number of new additions
11 Developer Preview. MVC 4 can be hosted alongside MVC in the header:
3. You can find all the details concerning installation in the
aforementioned link. As with all developer preview/pre- • jQuery UI CSS
release software, features sets are subject to change, which • jQuery UI js library
may range from minor tweaks to major changes. Please keep • Ajax login js library
that in mind as you evaluate any developer preview as to
how you can incorporate it into your development efforts. In addition, you will see a number of new CSS class defi-
John V. Petersen nitions. For example, the new content-wrapper class en-
email: johnvpetersen@gmail.com capsulates the body which facilitates centering. Return-
blog: codebetter.com/johnpetersen Major New Features that Microsoft has ing to the header section, you will now find this code:
twitter: @johnvpetersen
Announced Thus Far
John Petersen has been develop- <meta name="viewport" content="width=device-width">
ing software for 20 years, starting
with dBASE, FoxBase+ and Clipper According to the public site, the following are the major Viewport is an HTML 5 meta tag that controls how your
thereafter, migrating to FoxPro new features that are part of the ASP.NET MVC 4 roadmap: content will appear in mobile browsers. This, in combina-
and Visual FoxPro and Visual Ba- tion with the new CSS classes is how adaptive render-
sic. Other areas of concentration • Revamped project templates ing works in ASP.NET MVC 4. While you could have always
included Oracle and SQL Server. • New mobile project template added this yourself, it’s nice to have the default project
John is the Philadelphia Microsoft • Recipes (a new method to generate code) templates handle these tasks.
Practice Director for CEI America • Enhanced support for async methods
(www.ceiamerica.com), a Micro-
soft Gold Partner. From 1995 to
2001, he was a Microsoft Visual
In this article, I’ll take a quick look at two of the four ma- New Mobile Project Template
jor features: revamped project templates and the mobile
FoxPro MVP. Today, his emphasis
project templates. In the next article, I’ll address recipes While adaptive rendering of a site that is primarily de-
is on ASP MVC .NET applications.
He is a current Microsoft ASP.NET and async support. Hopefully by the time part 2 comes signed for desktop browsers will get you pretty far, there
MVP and a member of ASP Insid- out, Microsoft will announce a more definitive release are situations when you will want to create a site that
ers and a member of the Telerik date for ASP.NET MVC 4 and they will lock-in the feature is written specifically for mobile devices. Recognizing
Community Insiders Program. set. For a complete list of announced new features, be that need, the ASP.NET MVC 4 team went ahead and gave
John is also a member of the sure to refer to the release notes http://www.asp.net/ us a mobile application template out of the box. In the
development team that develops whitepapers/mvc4-release-notes. Jan/Feb 2012 issue of CODE Magazine I introduced you to
and maintains the Nerd Dinner jQuery Mobile. As you learned, it was relatively simple to
Application (www.nerddinner. incorporate the jQuery Mobile libraries and CSS into your
com). John has published five Revamped Project Templates existing applications. Nevertheless, for those that are
books and over 60 industry just getting up and running with jQuery Mobile, it’s nice
articles. John also participates The steps to create an ASP.NET MVC project have not to have all of that in the box. Figure 5 illustrates how the
in several open source projects. changed. However, ASP.NET MVC 4 presents you with a home page (home/index) appears in a desktop browser.
In 2004, John graduated from new option in the new project dialog box illustrated in
the Rutgers University School of Figure 1. Figure 5 is probably not what you would want rendering
Law with a Juris Doctor Degree. to the desktop. Then again, I used jQuery Mobile to opti-
He passed the Pennsylvania and I will discuss the new mobile project application template mize this project for mobile devices. Figure 6 illustrates
New Jersey Bar exams and was in in the next section. To illustrate the new default Inter- how the home page appears on a mobile device.
private practice for several years.
net/intranet project templates, let’s keep the defaults in
Figure 1. As you can see in Figure 2, ASP.NET MVC 4 has Reviewing the contents in Views/Shared/_Layout.cshtml,
a significantly revised CSS design. we see something that is far less complex than its In-
ternet/intranet application template counterpart. In the
Even if you do not take advantage of the new mobile ap- header section, you will find references to the jQuery Mo-
plication templates, through a technique called adaptive bile CSS and js library resources. As with other jQuery
rendering, your application will adjust to different form Mobile pages, you will find references to the HTML5 se-
factors as illustrated in Figure 3. mantic markup data-role item.

Figure 4 illustrates how adaptive the rendering is with The support for mobile applications looks very encourag-
respect to the new Ajax-based login screen. ing. Up to this point, you have seen two separate examples
where in each case I demonstrated a distinctive project
As you navigate through the project artifacts to see template. What about cases where you have one project
what’s new, be sure to focus on the Views/Shared/_Lay- that could serve content to a variety of devices? What

68 ASP.NET MVC 4 Highlights, Part 1 codemag.com


about cases where you want a view optimized for a mobile
device to be rendered when a mobile device requests con-
tent but also render a view optimized for the desktop when
a desktop browser requests content? This is where the new
jQuery.Mobile.MVC Package comes in handy.

Introducing the New jQuery.Mobile.MVC NuGet


Package
In the real world your application will need to be able
to service multiple form factors: desktop, tablet, smart-
phone, etc. Users expect that when they hit your site with
a smartphone, the UI will be optimized for that device.
As you have already seen, jQuery Mobile is well suited to
this task. We have also seen how well the new mobile ap-
plication template consumes the jQuery Mobile services.
On the back end, one approach to servicing various clients
is to have separate optimized sites. Another approach is
to have one site and have that one application sort out
the details of which view to render based on the client
that is making the request. In other words, change the
display mode based on the client (desktop, iPhone, Win-
dows Phone, tablet, etc.) that is making the request. This
second approach will appeal to many developers and it will
be the focus of the remaining parts of this article. In order
to make this second approach work, we will want to use
NuGet to install the jQuery Mobile MVC Package. From the
Figure 1: The New Project dialog box has a new option for mobile applications. Package Manager Console, type the following command:

SPONSORED SIDEBAR:
Project Success Kit
CODE Consultants can help you
build applications better and
faster, with reduced risk and
increased return. The Project
Success Kit will help increase
the quality of your development
team. In all of our services, we
aim to achieve an excellent level
of maintainability and reusability.
We provide training, development,
project management and
architectural expertise.

With the Project Success Kit, your


team will ramp up development
to hit the ground running. The
best part? For one low fee, the
Project Success Kit includes
planning, coaching, training,
design and development from
world-class team application
developers. We don’t just make
recommendations and delegate;
we’ll sit down with your team
and write code alongside them.

Decrease the risk, increase your


return, and future-proof your
investment by getting started
with the project success kit
and “Wield Technology to Great
Effect!” – www.codemag.com/
consulting. Email info@codemag.
com for more information.
Figure 2: Microsoft has significantly redesigned the default CSS and page layout in ASP.NET MVC 4.

70 ASP.NET MVC 4 Highlights, Part 1 codemag.com


PM> Install-Package jQuery.Mobile.MVC cleared. If the browser is not a mobile device than a
browser override setting is established. In the case of
Be sure to have the latest version of NuGet installed. As of a desktop browser, the mobile version will be rendered.
this writing, the latest NuGet version is 1.6.21215.9133. From that point on, if the user navigates directly to the
For more information on NuGet, visit nuget.org. home page (home/index), the mobile version will be
rendered. To reverse these effects, simply navigate to
Figure 7 illustrates the Package Manager Console output the ViewSwitcher/SwitchView action and set the mobile
after running the previous command. parameter to false:

Installing the package adds a number of new items to http://192.168.1.103/mvc4/viewswitcher/switchview?


the project: mobile=false&returnurl=/mvc4/

• Views/Shared/_Layout.Mobile.cshtml Display Modes


• Views/Shared/_ViewSwitcher.cshtml
• Controllers/ViewSwitcherController.cs Within the mobile device space we can get more specific
• jQuery Mobile support files (jQuery js/css, etc.) with display modes. To illustrate, let’s assume that we
wish to render a specific view whenever an iPhone hits
If you are seeing JavaScript errors indicating that jQuery the site. For every other mobile device, the default mo-
is not defined, be sure to review the script references in bile view should be rendered. To make this happen, there Figure 3: With adaptive rendering,
the Layout and Layout.Mobile views. The jQuery referenc- are a few things we have to put in place. First, in the your ASP.NET MVC pages will be
es may be incorrect. Review the jQuery version you have Application_Start () in the Global.asax file, we need to useful in mobile devices.
in the /Scripts folder in the solution explorer. Chances add this code:
are there is a mismatch in the version # (contained in the
file name) between what is in the scripts folder and what DisplayModes.Modes.Insert(0, new
the layouts are referencing. Simply adjust the names in DefaultDisplayMode("iPhone")
the layout views to what is in the scripts folder and re- {
run the app. ContextCondition = (context =>
context.Request.UserAgent.IndexOf
If you navigate to the app from a desktop browser, you ("iPhone", StringComparison.OrdinalIgnoreCase) >= 0)
will not see any difference in the way the app is rendered. });
The app will appear just like it did in Figure 2. On the
other hand, if you navigate to your app from a mobile This code adds an iPhone entry to the DisplayModes.
device, the rendered view is significantly different as il- Modes hash. By default there are already two entries in
lustrated in Figure 8. that hash: a Default entry and another for Mobile. With
this entry, there will be three items in the hash. Next
From the desktop you can force the framework to render we need to create a new layout. ASP.NET MVC has, at its
the mobile view by invoking ViewSwitcher/SwitchView core, the concept of convention over configuration. To
action (replace this server with what is appropriate for illustrate the point, I added a new view under /Views/
your specific environment): Shared and I named it _Layout.iPhone.cshtml. I copied
the contents of the existing _Layout.Mobile.cshtml and
http://192.168.1.103/mvc4/viewswitcher/switchview? added one thing to the top of the page: Figure 4: The new Ajax-based
mobile=true&returnurl=/mvc4/ login page as rendered on a
@{ mobile device.
Figure 9 illustrates a breakpoint in the ViewSwitcher ViewBag.Title = "_Layout.iPhone";
Controller SwitchView Action Method. }

If the browser making the request is actually a mo- Figure 10 illustrates the view that is rendered when navi-
bile device, than any overridden browser settings are gating to the home page with an iPhone.

Figure 6: The home page


(home/index) of the mobile
application project as rendered
Figure 5: The home page (home/index) of the mobile application project as rendered in a desktop browser. on a mobile device.

codemag.com ASP.NET MVC 4 Highlights, Part 1 71


Figure 8: Behind the scenes,
once the jQuery.Mobile.MVC
package is installed, the ASP.NET
MVC framework, with the help of
the ViewSwitcher Controller, will
render the correct view if a mobile
device is making a request.
Figure 7: Package Manager Console output from installing the jQuery.Mobile.MVC package.

Figure 9: The ViewSwitcher Controller provides the ability to override default browser.

If you navigate to the same page from any other mo- this series, I’ll pick up with two additional major features
Figure 10: Display Modes allow bile device, the default mobile layout (_Layout.Mobile. in ASP.NET MVC 4: recipes and async method support.
us to create device-specific views. cshtml) will be rendered. Recipes are code generation plugins that are supported
through NuGet. Perhaps you have wanted to customize
what happens when you add an area, controller, view,
Conclusion etc. Recipes will make that task easier than before. As for
async method support, this feature ties into the C# 5 and
As you can see, if I could summarize ASP.NET MVC 4 in one the Async CTP (http://msdn.microsoft.com/en-us/vstu-
phrase it would be “Mobility Support – Out of the Box!” dio/async.aspx). Perhaps you have a long running task
Granted, we could do these same things with MVC 3. But that you would like to make cancellable. While we have
it would have required us to roll our own templates and in been able to handle these tasks with Ajax and JavaScript,
spite of our best efforts, nothing would be baked into the it would be nice if we could achieve the same thing with
framework. Display Modes is a great example of why we native C# code.
want such things baked into the framework. And like so
much in the ASP.NET MVC Framework, we get the best of John V. Petersen
both worlds: baked in functionality and extensibility. This
reminds me of when Microsoft introduced remote valida-
tion in ASP.NET MVC 3. Again, we were able to achieve the
same things before. With remote validation being baked
into framework, a much more elegant solution evolved,
one that makes it easier to bring new folks on board.
These new baked-in mobility features will make it easier
than ever for developers who have wanted to extend
their mobile applications to mobile devices. In part 2 of

72 ASP.NET MVC 4 Highlights, Part 1 codemag.com


CODE COMPILERS

(Continued from 74)

Pythagorean Theorem—is itself based on rigor going to be able to progress. They chose to re-
and logic and proof. Lots of geometric “founda- main mired in the concrete, and not bother with March/April 2012
tions” are in fact derivations. the abstraction, because to them, numbers were Volume 13 Issue 2
about counting sheep and rocks and land.
Interpretations Group Publisher
The Greeks took an abstraction, simplified the Markus Egger
The Greeks were famous for their schools and system, and a whole new way of thinking opened Associate Publisher
Rick Strahl
centers of learning, most of which got absorbed up.
into other cultures when the Greek Golden Age Editor-in-Chief
Rod Paddock
came to a crashing halt after some 50 short years And that, my friends, is what an abstraction
Managing Editor
in the historical spotlight. Lessons abound in this should do. Ellen Whitney
Grecian view of the world that we can utilize for
Content Editors
software. (For those interested in a light refresher on math H. Kevin Fansler
combined with the place in history and historical Erik Ruthruff
For starters, notice that the power of math came context surrounding these discoveries, I highly Melanie Spiller
when rather than adding to the mental model, recommend the book, Mathematics for the Non- Writers In This Issue
the Greeks stripped it down. They reduced it to mathematician, by Morris Kline.) Milton Abe Mike Benner
Markus Egger Oren Eini
its simplest essence: just the number, with no Aaron Erickson Kevin S. Goff
units or attachments. That suggests that maybe, Ted Neward Sahil Malik Ted Neward
just maybe, sometimes the right thing to do in Rod Paddock John V. Petersen
Paul Sheriff
a model is strip it down, not bury it underneath
more levels of abstraction. Technical Reviewers
Markus Egger
Rod Paddock
This is part of the problem I have with object/ Art & Layout
relational mapping tools: by the time we get King Laurin GmbH
through all the code to put the string into the info@raffeiner.bz.it
table, it’s been through dozens of classes and nu- Production
merous transformations. If the data wants to be Franz Wimmer
King Laurin GmbH
stored relationally, why not present it that way? 39057 St. Michael/ Eppan, Italy
And if it doesn’t want to be presented that way,
Printing
then why store it that way? Fry Communications, Inc.
800 West Church Rd.
The other lesson to learn is that simple empirical Mechanicsburg, PA 17055
evidentiary “proofs” are nothing but: no matter Advertising Sales
Tammy Ferguson
how many tests we write, we haven’t “proven” the 832-717-4445 ext 26
software safe unless we can somehow, based on tammy@code-magazine.com
logic and some core axioms, reason out the re- Circulation & Distribution
sults apart from the actual units. In other words, General Circulation: EPS Software Corp.
it is possible to have software failures despite Newsstand: Ingram Periodicals, Inc.
Media Solutions
unit tests that cover 100% of your codebase. Source Interlink International
Yes, unit tests will help give us evidence that the The News Group
cases we anticipated are covered. And that’s a Subscriptions
good feeling, no doubt about it. But that’s not Circulation Manager
“proven” correct. Cleo Gaither
832-717-4445 ext 10
subscriptions@code-magazine.com
Type systems, as it turns out, are the program-
ming language’s attempt to provide that math- US subscriptions are US $29.99 for one year. Subscriptions
outside the US are US $44.99. Payments should be made
ematical basis for determining a program’s in US dollars drawn on a US bank. American Express,
correctness, and even there we run into some MasterCard, Visa, and Discover credit cards accepted.
distinct cliff edges. It has become fashionable Bill me option is available only for US subscriptions.
Back issues are available. For subscription information,
in the past decade to discard type systems and email subscriptions@code-magazine.com
rigorous type checking by a software system de- or contact customer service at
signed for such checking (e.g., a compiler) in 832-717-4445 ext 10.
favor of languages that “get out of the way” and
a scaffolding mechanism to run a piece of the Subscribe online at
www.code-magazine.com
system. Instead, we look at the results (e.g., a
unit test). CODE Component Developer Magazine
EPS Software Corporation /
Publishing Division
The ancient Babylonians used the value “3” to 6605 Cypresswood Drive, Ste 300, Spring, Texas 77379
describe the magic number used when calculat- Phone: 832-717-4445
ing the area of a circle, because it was the closest Fax: 832-717-4460
approximation they could make to the value pi.
It was good enough for their use, but that didn’t
make it right. And without that, they were never

codemag.com Managed Coder 73


MANAGED CODER

Managed Coder:
On Abstraction
Writing software is hard, particularly when the schedules keep programmers “nose to the
grindstone”; every so often, it’s important to take a breather and look around the world and
discover what we can find—ironically, what we find can often help us write software better.

Programmers, software designers, and architects an even more accurate source of popular percep- that we do to the greater good of humanity. I’ve
constantly talk about the need for “good abstrac- tions. seen (in fact, I’ve made) the comparison of the
tions” and “well-defined models” of the software software abstractions we build to the “flickering
being built, but recent readings have led me to Anybody here remember the opening scenes of shadows” that Plato used to describe the concept
wonder whether we’re using the idea correctly. the recent TRON movie sequel? You know, the of “forms,” the abstract essence, if you will, of
one where they took Jeff Bridges (my twin from the material world around us. The analogy he
It’s not uncommon for software guys to argue— a distant universe) and reverse-aged him to look used is that we are men in a cave, sitting with our
for days at a time, in some cases—over the “ab- like he did in the original TRON movie and had backs to a fire, only able to view objects passing
stractions” being written. Everywhere you look him play both himself (the good guy) and the in front of the fire (but behind us) as shadows
in software, we find abstractions. Everything in program-copy of him from twenty years ago (the flickering against the wall. We can glean the basic
software seems to be an abstraction over some- bad guy)? If you don’t, no worries: go grab the shapes, but without any degree of accuracy, and
thing else: objects are abstractions over data- TRON:Legacy soundtrack from your favorite music none of the nuance.
bases, databases are abstractions over one or store. It’s good coding music.
more files, files are abstractions over file streams, The rationale, then, is that the closer our mod-
which in turn are abstractions of the data moving Cue up “The Grid” and listen to the little back- els can get to the “real world” the better. The
across the peripheral bus (itself an abstraction) story speech he gives. deeper the level of nuance, the more accurately
that communicates with the hard drive, storing the model reflects the business world, the more
bits of data in (you guessed it) abstractions of The Grid. A digital frontier. I tried to picture clus- successful the software will be.
sectors, tracks, blocks, and who knows what else. ters of information as they moved through the
Drill down far enough, and sure enough, it all computer. What did they look like? Ships, motor- Mathematics
turns into 1’s and 0’s. But even those 1’s and 0’s cyles? Were the circuits like freeways?
are abstractions for an arbitrary decision made The Greeks had a different notion of abstraction.
somewhere around the “big bang” of the com- Waaaait a minute. I realize this is a movie, fic- They were really the first civilization to notice
puting universe, to consider a certain amount of tionalized to Hollywood’s weird, distorted tastes, that whether you had three rocks, three pigs,
positive current to be a “1” and a certain amount but this is a little over the top. When’s the last or three acres, an abstract idea of “three-ness”
of a negative current to be a “0”. Maybe. I’m not time you kicked off a build and saw a little mo- was present, and it didn’t really matter whether
sure—I’m a software guy, I deal in abstractions, torcycle light-cycle take off across your screen, you were adding together rocks, pigs, or acres
not a hardware guy who ends up watching those complete with cool energy trail to kill all those (or even some combination of all of them): the
voltage fluctuations in oscilloscopes which dance other motorcycle light-cycles trying to use the concept of combining “three” and “three” yielded
around in patterns that, while pretty, mean abso- CPU? Or clicked “Save” in Word and saw a big ol’ “six” regardless of what kinds of things we were
lutely nothing to me. supertanker full of article data shove off and sail combining.
across the bus to rendezvous with the stream on
I’m a software guy. We use abstractions. Keep the other end of a buffer? That led to all kinds of interesting realizations.
your bits and bytes away from me, man—I deal in It meant that we didn’t have to think about the
managed code. You know, that code that runs on Yes, I’m mixing metaphors here. Or, if you prefer, concrete aspects of things, which led to the de-
a virtual machine, which is sometimes executing all of our abstractions. If you’re having a hard velopment of geometry, for one. I know, I kinda
inside a virtual machine, which in turn is running time keeping them all straight, then imagine how hated geometry in school, too, but when you
on top of an operating system (itself an abstrac- the people who don’t live with this stuff all the think about it, somehow these old guys in to-
tion over the machine), which is often running time must feel. gas figured out that if you have a right triangle,
in some kind of virtual machine environment on the squares of the right-angled sides will always
the chip. If you want to experience this feeling firsthand, equal the square of the opposite side. Every time.
go find a college quarterback and ask him to walk Without fail.
With all these abstractions in place, it’s a wonder you through a play of his on video, complete with
that anybody in the software world realizes that the jargon. Heck, high school, even. Anybody And they did this not by simply writing test after
it’s all just 1’s and 0’s in the end. Or that anybody who suggests that football quarterbacks aren’t test after test, and if a certain number of these
can understand what we do. intelligent has never played the game. (Whether empirical tests pass, declaring that it must be so
they can pass an English exam or an accounting for all numbers a, b and c. The Greeks did this
The Grid class is another question entirely.) by rigorous application of logic, relying on ba-
sic axioms (fundamental truths of mathematics)
Actually, it’s pretty obvious that they don’t. I Flickering Shadows and derivations and applications based on those
could cite examples of conversations with ev- truths. What we take as a fundamental truth—the
eryday people (I refuse to call them “users” for In many ways, we imagine the creations of these
purposes of this article), but instead I’ll point to abstractions to be a kind of noble art, something (Continued on page 73)

74 Managed Coder codemag.com


VENDORS: ADD A REVENUE STREAM BY OFFERING ESCROW TO YOUR CUSTOMERS!

han
Less t

ay!
per d

Affordable High-Tech
Digital Escrow
Tower 48 is the most advanced and affordable digital escrow solution available. Designed and built specifically for software and other
digital assets, Tower 48 makes escrow inexpensive and hassle free. Better yet, as a vendor, you can turn escrow into a service you offer to
your customers and create a new revenue stream for yourself.
Regardless of whether you are a vendor who wants to offer this service to their customers, or whether you are a customer looking for extra
protection, visit our web site to start a free and hassle-free trial account or to learn more about our services and digital escrow in general!

Visit www.Tower48.com for more information!


FROM THE PRODUCERS OF CODE MAGAZINE

shu
ssh
h uuttte
hut ooccckk
toc
ersstto
tters
ter
Application Framework from the
Most Trusted Source in .NET!
Brought to you by CODE Magazine, the CODE Framework is a free and open-source business application development framework,
focusing on productivity, maintainability, and great application architecture. The CODE Framework provides a wide range of features,
from various UI development approaches (Windows, Web, Mobile,…) to Middle-Tier and Service components, to data access, security,
various utility features, and much much more. CODE Framework also aims to not re-invent features that are already available by making
“mashability” with other frameworks a high priority.

To get the CODE Framework, visit www.codemag.com/framework or download various versions and tools from http://codeframework.codeplex.com.

See more details at: www.codemag.com/framework


FR AMEWORK
An EPS Company

You might also like