Tutorial: Create Custom External Services in Azure AppFabric June CTP

Introduction
One of the first things I wanted to do after installing the Azure AppFabric June CTP was to create an AppFabric application that used the Bing Map SOAP services. That was when I hit my first roadblock. There is currently no option in the AppFabric Application Designer to add a reference to an external service. After asking around in the forums I learned that I should build an external service to do this. There is currently very little documentation on creating external services for Azure AppFabric, so after a couple of days experimenting I managed to get a basic external service working. As this is something that many AppFabric developers will want to do I thought I’d share what I learned in the form of a tutorial.
In this tutorial I will run through the creation of an AppFabric external service that will provide a proxy for the Bing Maps Geocode service. I have kept the implementation as simple as possible, there is a lot more you can do with external services, such as providing a configuration setting for the Bing Maps key, and customizing monitoring, but I will save this for future webcasts and tutorials. Also, bear in mind that as we are on the first CTP of these tools, things can, and will change. One of my loudest shouts to the AppFabric development team is to make it easier to consume services outside the AppFabric application, so hopefully we will see some development there.
Hopefully this tutorial will act as a starting point for creating your own external services that can be consumed by AppFabric applications. If you have any questions or comments, feel free to ping me using the comments section on my blog.
Consuming External Services
At present consuming a service outside the AppFabric application can be done in one of two ways. The quick-and-dirty way is to use the traditional “Add Service Reference” option. The proper way is to create a custom external service.
Traditional “Add Service Reference”
Whilst it is possible to use the traditional “Add Service Reference” method to consume an external service, there are a number of drawbacks to this. When consumed from an ASP.NET service the web.config is read by the application, and configuration can be used for the client endpoints, however when consumed from a stateless WCF service, configuration is not read and therefore client endpoint settings must be hardcoded. Either way the application must be re-deployed if anything changes.
Another drawback is that the external service is not recognized by the AppFabric application model, and therefore will not appear on the application diagram. There will also be no monitoring on the calls made to the external service.
Create a Custom External Service
Creating a custom external service will allow the external service to be recognized by the AppFabric application model. This means it can be used in the composition of an application, and will use the AppFabric service reference infrastructure. The external service can provide monitoring data to show usage of the service and also expose configuration settings that can be set at development time and reconfigured when the application has been deployed.
This tutorial will focus on the creation of a custom external service.
Pre-Requisites
If you are going to run through the tutorial as I have written it, you will need to install the relevant Visual Studio components and register for the relevant services. You can follow the steps using a different service if you don’t want to use the Bing Maps services.
Install Windows Azure AppFabric June CTP Developer Tools
I recommend installing the June CTP tools on a separate virtual environment to avoid possible compatibility issues with past and future releases.
You can find it here.
Install Visual Studio 2010 SDK
The Visual Studio SDK is required for creating the Visual Studio package that will contain the external service.
The Visual Studio SDK is here.
The Visual Studio Service Pack 1 SDK is here.
Create a Bing Maps Developer Account
If you want to test against the Bing Maps SOAP services you will need a developer account. It’s free to apply for, and you will receive a key to call the Bing Maps Geocode service. If you don’t want to do this you can pick another external service to consume and adjust the tutorial accordingly.
There are details on registering for an account here:
Create an AppFabric Labs Account (Optional)
If you want to test your application “In the Cloud”, and see the configuration options you will need an AppFabric account.
You can register for an account here.
Create a Bing Maps External Service
The Bing Maps Geocode service provides search functionality that takes address details as search parameters and returns a list of addresses and coordinates as a result. An external service will be created that allows the Bing Maps Geocode service to be called from an AppFabric application using the AppFabric application model. The service will be represented on the application diagram and the service endpoint will be configurable in the development and hosting environments.
Create a new MEF Component
An MEF Component will be created to contain the external service. This can then be installed in Visual Studio for the service to appear in the AppFabric designer. It is possible to do more advanced things with the Visual Studio extension, but in the interests of the tutorial I’ll keep it as simple as possible.
%u00b7 In Visual Studio, Create a new project, and select Visual Studio Package in the Visual C# / Extensibility section, name it BingMapsExternalService. (If you don’t see the Extensibility option, install the Visual Studio 2010 SDK.)

%u00b7 In the Select a Programming Language page, select Visual C# and Generate a new key file

%u00b7 Keep the default options for the next two pages.

%u00b7 In the Select Test Project options, clear both check boxes.
Visual Studio will create the project, and open the vsixmanifest file.
%u00b7 In the Content section of the vsixmanifest file, remove the VS Package content.

%u00b7 Add Content for an MEF Component and select the project name as the source.

%u00b7 Save and close the vsixmanifest file.
Add Required References
The extension project will need to hook in to the internals of the AppFabric application model, as well as serialize the metadata for the external service properties.
%u00b7 Add references to the following assemblies:
o Microsoft.ApplicationServer.ApplicationModel
o Microsoft.VisualStudio.ApplicationServer
o System.ComponentModel.Composition
o System.Fabric
o System.Runtime.Serialization
Add the Bing Maps Service Reference
The external service will return a client proxy for the Bing Maps Geocode service. Adding a service reference to the project will create the classes for this client proxy and the data contracts for the request and response.
%u00b7 Use the Add Service Reference dialog box to add a reference to the Bin Maps Geocode Service setting the namespace to GeocodeServiceReference.
o http://dev.virtualearth.net/webservices/v1/geocodeservice/geocodeservice.svc
Note: The client configuration that is added to the app.config file will not be used in the external service.

Add Required Classes
The external service requires three classes to be implemented. Each of these will derive from a class in the AppFabric application model and provide overrides of methods and properties.
%u00b7 Add a folder named BingMaps to the project.

%u00b7 Add classes with the following names to the folder:
o GeocodeServiceExport
o GeocodeServiceExportDefinition
o GeocodeServiceMetadata
Implement the Service Export Definition Class
The service export definition class provides details of the type of the service that is exported, and any configuration settings that can be set for the service. Data contract serialization is used for the configuration settings.
%u00b7 Make the GeocodeServiceExportDefinition class public and derive it from ServiceExportDefinition, adding a using for the Microsoft.ApplicationServer.ApplicationModel.Definitions namespace. (Use [Ctrl] + [.] to do this.)

%u00b7 Use [Ctrl] + [.] to provide the implementation of the ExportType property.

%u00b7 Implement the Export Type property as follows:

protected override Type ExportType
{
get
{
return typeof(GeocodeServiceExport);
}
}
%u00b7 Add a public property for the Uri of the service, also adding a using for the System.Runtime.Serialization namespace.

[DataMember]
[RequiredProperty]
public string Uri { get; set; }
Note: This property will appear in the properties pane for the external service in the AppFabric Designer. It will also allow for configuration of the service Uri in the AppFabric hosting environment.
%u00b7 Add a constructor to set the Uri to a default value:

public GeocodeServiceExportDefinition()
{
Uri = “http://dev.virtualearth.net/webservices/v1/geocodeservice/geocodeservice.svc”;
}
%u00b7 Build the project and fix any errors.

%u00b7 The complete class should look like this:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.ApplicationServer.ApplicationModel.Definitions;
using System.Runtime.Serialization;
namespace Company.BingMapsExternalService.BingMaps
{
public class GeocodeServiceExportDefinition : ServiceExportDefinition
{
[DataMember]
[RequiredProperty]
public string Uri { get; set; }
public GeocodeServiceExportDefinition()
{
Uri = “http://dev.virtualearth.net/webservices/v1/geocodeservice/geocodeservice.svc”;
}
protected override Type ExportType
{
get
{
return typeof(GeocodeServiceExport);
}
}
}
}
Implement the Service Export Class
The service export class will create a new client proxy for the Bing Maps Geocode service using the URI specified in the service export definition, and return it to the code in the application that calls the service. As no configuration is used for the client proxy, it must be created using code.
%u00b7 Make the GeocodeServiceExport class public and derive it from ServiceExport, adding a using for the Microsoft.ApplicationServer.ApplicationModel namespace.

%u00b7 Use [Ctrl] + [.] to provide the implementation of the Resolve method.

%u00b7 Implement the Resolve method as follows, adding usings for System.ServiceModel and Company.BingMapsExternalService.GeocodeServiceReference.

protected override object Resolve(ExportResolutionContext context)
{
GeocodeServiceExportDefinition definition =
(GeocodeServiceExportDefinition)GetDefinition();
BasicHttpBinding binding = new BasicHttpBinding();
EndpointAddress address = new EndpointAddress(definition.Uri);
GeocodeServiceClient client = new GeocodeServiceClient(binding, address);
return client;
}
%u00b7 Build the project and fix any errors.

%u00b7 The complete class should look like this:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.ApplicationServer.ApplicationModel;
using System.Diagnostics;
using System.ServiceModel;
using Company.BingMapsExternalService.GeocodeServiceReference;
namespace Company.BingMapsExternalService.BingMaps
{
public class GeocodeServiceExport : ServiceExport
{
protected override object Resolve(ExportResolutionContext context)
{
GeocodeServiceExportDefinition definition =
(GeocodeServiceExportDefinition)GetDefinition();
BasicHttpBinding binding = new BasicHttpBinding();
EndpointAddress address = new EndpointAddress(definition.Uri);
GeocodeServiceClient client = new GeocodeServiceClient(binding, address);
return client;
}
}
}
Implement the Service Metadata Class
The service metadata class provides details about the service to the AppFabric Application Designer. This includes the name and description of the service and also the list of assemblies that contain the external service.
%u00b7 Derive the GeocodeServiceMetadata class from ExternalServiceMetadata, adding a using for the Microsoft.VisualStudio.ApplicationServer.ExternalServicesMetadata namespace.

%u00b7 Use [Ctrl] + [.] to provide the implementation of the FriendlyName property.

%u00b7 Add the ExternalServiceExport attribute to the class as follows:

[ExternalServiceExport(typeof(GeocodeServiceExportDefinition))]
class GeocodeServiceMetadata : ExternalServiceMetadata
{
public override string FriendlyName
{
get { throw new NotImplementedException(); }
}
}
%u00b7 Implement the FriendlyName property as follows:

public override string FriendlyName
{
get
{
return “Bing Maps Geocode Service”;
}
}
%u00b7 Override the Description property and implement it as follows:

public override string Description
{
get
{
return “This will call the Bing Maps Geocode Service.”;
}
}
%u00b7 Override the ProxyTypeName property and implement it as follows, adding a using for Company.BingMapsExternalService.GeocodeServiceReference.

public override string ProxyTypeName
{
get
{
return typeof(GeocodeServiceClient).AssemblyQualifiedName;
}
}
%u00b7 Add member variables for lists of proxy and reference artifacts:

[ExternalServiceExport(typeof(GeocodeServiceExportDefinition))]
class GeocodeServiceMetadata : ExternalServiceMetadata
{
List<string> m_ProxyArtifacts = new List<string>();
List<string> m_ReferenceAssemblies = new List<string>();
%u00b7 Override the ProxyArtifacts property as follows:

public override List<string> ProxyArtifacts
{
get
{
if (m_ProxyArtifacts.Count == 0)
{
m_ProxyArtifacts.Add(typeof(GeocodeServiceExportDefinition).Assembly.Location);
}
return m_ProxyArtifacts;
}
}
%u00b7 Override the ReferenceAssemblies property as follows:

public override List<string> ReferenceAssemblies
{
get
{
if (m_ReferenceAssemblies.Count == 0)
{
m_ReferenceAssemblies.Add(typeof(GeocodeServiceExportDefinition).Assembly.Location);
}
return m_ReferenceAssemblies;
}
}
%u00b7 Build the project and fix any errors.

%u00b7 The complete class should look like this:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.VisualStudio.ApplicationServer.ExternalServicesMetadata;
using Company.BingMapsExternalService.GeocodeServiceReference;
namespace Company.BingMapsExternalService.BingMaps
{
[ExternalServiceExport(typeof(GeocodeServiceExportDefinition))]
class GeocodeServiceMetadata : ExternalServiceMetadata
{
List<string> m_ProxyArtifacts = new List<string>();
List<string> m_ReferenceAssemblies = new List<string>();
public override string FriendlyName
{
get
{
return “Bing Maps Geocode Service”;
}
}
public override string Description
{
get
{
return “This will call the Bing Maps Geocode Service.”;
}
}
public override string ProxyTypeName
{
get
{
return typeof(GeocodeServiceClient).AssemblyQualifiedName;
}
}
public override List<string> ProxyArtifacts
{
get
{
if (m_ProxyArtifacts.Count == 0)
{
m_ProxyArtifacts.Add(typeof(GeocodeServiceExportDefinition).Assembly.Location);
}
return m_ProxyArtifacts;
}
}
public override List<string> ReferenceAssemblies
{
get
{
if (m_ReferenceAssemblies.Count == 0)
{
m_ReferenceAssemblies.Add(typeof(GeocodeServiceExportDefinition).Assembly.Location);
}
return m_ReferenceAssemblies;
}
}
}
}
Testing a Bing Maps External Service
To test the external service a simple AppFabric application will be created with an ASP.NET service that makes a call to the Bing Maps Geocode service to search for a location. The results from the search will be displayed on the web page.
Install the Visual Studio Package
Before the external service can be used in the AppFabric designer it must be installed in Visual Studio.
%u00b7 Build the BingMapsExternalService project.

%u00b7 Navigate to the output folder for the extension project.
o ..\BingMapsExternalService\BingMapsExternalService\bin\Debug

%u00b7 Double-click BingMapsExternalService.vsix and follow the instructions to install the MEF Component.

%u00b7 Close all instances of Visual Studio.
Create an AppFabric Application
A new application can now be created to test the external service.
%u00b7 Start Visual Studio and create a new AppFabric Application, named BingMapsExternalServiceTest.
%u00b7 Select Tools %u00e0 Extension manager and notice that the BingMapsExternalService extension appears in the list of installed extensions.
Note: You can uninstall the extension with this dialog box.

%u00b7 Add an ASP.NET service named TestWeb.

%u00b7 Add a Bing Maps Geocode Service service named GeocodeTest.
Note: The external service name and description is listed in the New Service dialog box.

%u00b7 In the Service References section of TestWeb, add a service reference to the GeocodeTest service, and change the name the reference from Import1 to GeocodeTestImport.
Note: The Uri property of the external service is configurable in theGeocodeTest properties window.

%u00b7 Right-click App.cs and select View Diagram.
Note: The Geocode external service appears on the application diagram with a default icon.

%u00b7 Open ServiceReferences.g.cs.
Note: This class provides two static methods to return client proxies for the Bing Maps Geocode service.
Add Code to Call the External Service
%u00b7 Implement the BodyContent section of Default.aspx as follows:
Note: You can copy-paste the code to save time.

<%@ Page Title=”Home Page” Language=”C#” MasterPageFile=”~/Site.master” AutoEventWireup=”true”
CodeBehind=”Default.aspx.cs” Inherits=”GeocodeWeb._Default” %>
<asp:Content ID=”HeaderContent” runat=”server” ContentPlaceHolderID=”HeadContent”>
</asp:Content>
<asp:Content ID=”BodyContent” runat=”server” ContentPlaceHolderID=”MainContent”>
<h2>
Welcome to Custom AppFabric Services!
</h2>
<table>
<tr>
<td>Street</td>
<td><asp:TextBox ID=”txtStreet” runat=”server” /></td>
</tr>
<tr>
<td>Town</td>
<td><asp:TextBox ID=”txtTown” runat=”server” /></td>
</tr>
<tr>
<td>Country</td>
<td><asp:TextBox ID=”txtCountry” runat=”server” /></td>
</tr>
<tr>
<td></td>
<td><asp:Button ID=”btnGeocode” Text=”Geocode Me!” OnClick=”btnGeocode_Click” runat=”server” /></td>
</tr>
</table>
<asp:Repeater ID=”rptLocations” runat=”server”>
<HeaderTemplate>
<table>
<tr>
<td><b>Address</b></td>
<td><b>Confidence</b></td>
<td><b>Coordinates</b></td>
</tr>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td><%# DataBinder.Eval(Container.DataItem, “DisplayName”)%></td>
<td><%# DataBinder.Eval(Container.DataItem, “Confidence”)%></td>
<td><%# DataBinder.Eval(Container.DataItem, “Locations[0].Latitude”)%>, <%# DataBinder.Eval(Container.DataItem, “Locations[0].Longitude”)%></td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
</asp:Content>
%u00b7 In Default.aspx.cs add a button click event for btnGeocode and implement it as follows, using your own Bing Maps key:
Note: You will need to add the relevant using declarations.

protected void btnGeocode_Click(object sender, EventArgs e)
{
GeocodeServiceClient geoClient = ServiceReferences.CreateGeocodeTestImport();
GeocodeRequest geoReq = new GeocodeRequest()
{
Credentials = new Credentials()
{
ApplicationId = “{Your Bing Maps Key}”
},
Address = new Address()
{
AddressLine = txtStreet.Text,
Locality = txtTown.Text,
CountryRegion = txtCountry.Text
}
};
GeocodeResponse geoResp = geoClient.Geocode(geoReq);
rptLocations.DataSource = geoResp.Results;
rptLocations.DataBind();
}
Note: The ServiceReferences class can now be used to return the client proxy for the Bing Maps Geocode service.

%u00b7 Build the solution, there will be errors

%u00b7 In the TestWeb project, add references to System.ServiceModel and System.Runtime.Serialization.

%u00b7 Build the solution, fix any remaining errors.
Test the Application in the AppFabric Emulator
The application can now be tested in the AppFabric Emulator.
%u00b7 Start the application without debugging.

%u00b7 When the web page appears, enter an address and click “Geocode Me!”

%u00b7 You can test the search by copy-pasting the coordinates into the search box for the Bing Maps website:
Test the Application in the AppFabric Hosting Environment
If you have an account for the AppFabric Labs portal you can test the application in the hosting environment. I’m assuming you know how to publish an application.
%u00b7 Publish, deploy and start the application in the AppFabric hosting environment.

%u00b7 Navigate to the GeocodeTest service and note the configuration for the service URI is available.
%u00b7 Test the application by navigating to the TestWeb endpoint.
Summary
Creating a custom external service for the AppFabric Application Designer requires a bit of work, but provides an implementation that follows the development model for AppFabric applications. The Bing Maps Geocode example used in this tutorial is one of the most basic implementations of an external service, the implementation could be improved to provide a configuration for the Bing Maps key, provide a custom icon, implement other Bing Maps services, and provide custom monitoring.
The CustomServices tutorial in the AppFabric samples provides some other examples of custom external services. The ReadMe document provides some explanation on creating custom external services.
If you have any questions or comments, feel free to ping me using the comments section on my blog.
Event Processing in the Cloud with StreamInsight Austin: Part II-Deploying to Windows Azure

Event Processing in the Cloud with StreamInsight Austin: Part II-Deploying to Windows Azure

In my previous post, I showed how to build StreamInsight adapters that receive Azure AppFabric messages and send Azure AppFabric messages. In this post, we see how to use these adapters to push events into a cloud-hosted StreamInsight application and send events back out. As a reminder, our final solution contains an on-premises consumer of […]
Blog Post by: Richard Seroter

What’s New in ASP.NET MVC 3 – Part 4 (screencast series 2.0)

I’ve posted the final installment of my What’s New in ASP.NET MVC3 screencast series (version 2.0)
Part 4 explores the following topics:

Extensibility
Scaffolding

This is a big one folks!
Note: I recommend watching this video in HD Mode, full screen.
(Video: Watch this video on the post page)
Screencast Download Link:
High Definition (.mp4) (85MB)

Blog Post by: Michael Gerety

What’s New in ASP.NET MVC 3 – Part 4 (screencast series 2)

I’ve posted the final installment of my What’s New in ASP.NET MVC3 screencast series (version 2.0)
Part 4 explores the following topics:

Extensibility
Scaffolding

This is a big one folks!
Note: I recommend watching this video in HD Mode, full screen.
(Video: Watch this video on the post page)
Screencast Download Link:
High Definition (.mp4) (85MB)

Blog Post by: Michael Gerety

Sample Chapter available for upcoming BizTalk LOB Book

I see that Packt Publishing has included a link to a sample chapter in our upcoming book called Microsoft BizTalk 2010: Line of Business Systems Integration.  The sample chapter selected  is: Integrating with Dynamics 2009.  You can read more about the book here and can find the sample chapter download here.

I don’t have a publish date but I expect it to be imminent.  The content has been provided to the printer.  I will update this post once a publish date is available.