Logo
CAR REVIEW
Windows Vista
Windows 7
Windows Azure
Windows Server
Windows Phone
PREGNANCY
 
 
Windows Server

BizTalk 2009 : WCF LOB Adapter SDK (part 4) - Implementing the Metadata Handlers

6/26/2011 4:39:55 PM

4. Step 4: Implementing the Metadata Handlers

The metadata support is probably the most distinguishing feature of the adapters written using the WCF LOB Adapter SDK. In this step, you will implement the interfaces that turn that magic into realty. Table 11 lists the interfaces.

Table 11. Metadata Interfaces
InterfaceDescription
IMetadataBrowseHandlerThis interface represents the browse capability of the WCF LOB Adapters. You must implement this interface regardless of your adapter functionality.
IMetadataSearchHandlerOptional. This interface represents the search capability of the WCF LOB Adapters.
IMetadataResolverHandlerThis interface is used when the WCF LOB Adapter SDK needs to generate the proxy files in case of .NET applications or XSD specifications in case of BizTalk applications.

4.1. Implementing the IMetadataBrowseHandler Interface

To enable the browse capability of the adapter, you have to implement the IMetadataBrowse Handler[] interface from the Microsoft.ServiceModel.Channels.Common namespace. The WCF LOB Adapter Development Wizard generated the derived HotelAdapterMetadataBrowseHandler skeleton class for you.

[] http://msdn.microsoft.com/en-us/library/microsoft.servicemodel.channels.common.imetadatabrowsehandler_methods.aspx

The IMetadataBrowseHandler interface is located in the Microsoft.ServiceModel.Channels. dll assembly and is defined as follows:

public interface IMetadataBrowseHandler : IConnectionHandler, IDisposable
{
MetadataRetrievalNode[] Browse(string nodeId,
int childStartIndex,
int maxChildNodes,
TimeSpan timeout);
}

We've put a description of the parameters accepted by the Browse method in Table 12.

Table 12. IMetadataBrowseHandler.Browse Method Parameter
ParameterDescription
nodeIdThe node identifier. Browse method evaluates the nodeId and returns either a collection of child nodes, if any, or a collection of operations associated with the given nodeId.
childStartIndexThe index of the first child to return.
maxChildNodesThe maximum number of child nodes to return.
TimeoutThe maximum time to wait to complete the operation.

The Browse method returns an array of the MetadataRetrievalNode[] objects representing either the operation or category type. Table 13 lists the public properties of the MetadataRetrievalNode class.

[] http://msdn.microsoft.com/en-us/library/microsoft.servicemodel.channels.metadataretrievalnode.aspx

Table 13. MetadataRetrievalNode Public Properties
PropertyDescription
DescriptionGets or sets the node description.
DirectionGets or sets the direction (inbound or outbound) in which the node is being retrieved.
DisplayNameGets or sets the node name to be displayed by UI.
IsOperationGets or sets the value indicating that the node is operation.
NodeIdGets or sets the NodeId, which uniquely identifies the node. The NodeId is usually a concatenation of the node path and node name. The node name is not necessarily the same as the DisplayName.
RootRead-only. Gets the root node.

When you finish implementation and deploy the project, you will be able to explore the operations supported by the adapter using the Add Adapter Service Reference or Consume Adapter Server reference tools, as shown in Figure 12.

Figure 12. HotelAdapter metadata

Now let's get to the code and implement the IMetadataBrowseHandler interface. Here is the process to follow:

  1. In Visual Studio, open the HotelAdapterMetadataBrowserHandler.cs file.

  2. Find the IMetadataBrowseHandler region, and replace it with the following code:

    /// <summary>
    /// Retrieves an array of MetadataRetrievalNodes from the target
    /// system. The browse will return nodes starting from the
    /// childStartIndex in the path provided in absoluteName, and
    /// the number of nodes returned is limited by maxChildNodes.
    /// The method should complete within the specified timespan or
    /// throw a timeout exception.
    /// If absoluteName is null or an empty string, return nodes starting
    /// from the root + childStartIndex.
    /// If childStartIndex is zero, then return starting at the node
    /// indicated by absoluteName (or the root node if
    ///absoluteName is null or empty).
    /// </summary>

    public MetadataRetrievalNode[] Browse(string nodeId
    , int childStartIndex
    , int maxChildNodes, TimeSpan timeout)
    {
    //WCF LOB SDK UI tools by deafult start with the root "\" node.
    //for the root node there is only one category "Hotel Operations"
    if (MetadataRetrievalNode.Root.NodeId.CompareTo(nodeId) == 0)
    {
    // Create an inbound and outbound category
    //under the root node
    MetadataRetrievalNode node = new
    MetadataRetrievalNode("HotelOperations");
    node.NodeId = "HotelOperations";
    node.DisplayName = "Hotel Operations";
    node.Description = @"This category contains inbound and
    outbound operations supported by the HotelAdapter.";
    node.Direction = MetadataRetrievalNodeDirections.Inbound |
    MetadataRetrievalNodeDirections.Outbound;
    node.IsOperation = false;
    return new MetadataRetrievalNode[] { node };
    }
    // if user selected "HotelOperations" in
    //the "Select Category" control populated
    //return two operations
    //OnGuestArrived in Inbound scenario
    //GetRooms in outbound
    else if ("HotelOperations".CompareTo(nodeId) == 0)
    {
    // Create outbound operation
    MetadataRetrievalNode nodeOutbound =
    new MetadataRetrievalNode("Hotel/GetRooms");
    nodeOutbound.NodeId = "Hotel/GetRooms";
    nodeOutbound.DisplayName = "GetRooms";
    nodeOutbound.Description =
    "This operation returns the number of available rooms.";
    nodeOutbound.Direction =
    MetadataRetrievalNodeDirections.Outbound;
    nodeOutbound.IsOperation = true;
    // Create inbound operation
    MetadataRetrievalNode nodeInbound =
    new MetadataRetrievalNode("Hotel/OnGuestArrived");
    nodeInbound.NodeId = "Hotel/OnGuestArrived";
    nodeInbound.DisplayName = "OnGuestArrived";
    nodeInbound.Description =
    "This operation notifies of client arrival.";

    nodeInbound.Direction =
                MetadataRetrievalNodeDirections.Inbound;
    nodeInbound.IsOperation = true;
    return new MetadataRetrievalNode[]
    { nodeOutbound, nodeInbound };
    }
    return null;
    }
    #endregion IMetadataBrowseHandler Members

  3. In Visual Studio, open the HotelAdapterHandlerBase.cs file.

  4. Find the Dispose method, and comment out the NotImplementedException exception.

  5. Save and build the project.

As you can see, the code is not complicated, but it indeed requires accuracy. Although the sample adapter deals with only two operations, adapters for the real-life LOB systems will likely have to provide dozens if not hundreds or even thousands of operations. Imagine if you as an adapter developer had to add an if-else block every time you wanted to expose a new operation. If this is the case, then the very idea of "automatic metadata discovery" turns into "manual metadata discovery" with very little advantages over classic WCF services if at all.

To decide whether your LOB system is a good candidate for being front-ended by the WCF LOB Adapters, you have to take into account how the metadata is organized and whether new operations will be accessible by the previously written code, ideally with no changes (the "write-code-once" concept). If getting to new metadata requires serious modifications of the existing code, this should probably be taken as an alarm bell, because it indicates that the system is not optimally designed. Please note that the "write-code-once" concept applies not only to the browse handler but also to the search and resolve handlers that we will discuss in the next two sections. All three metadata interfaces constitute the metadata capabilities of the WCF LOB Adapters and have to be written according to the concept. To see the "write-code-once" concept in action, we recommend you take a close look at the Contoso Adapter supplied with the WCF LOB Adapter SDK. This adapter is a good example of how metadata in the form of SQL Server stored procedures can be accessed in a unified manner.

4.2. Implementing the IMetadataSearchHandler interface

To enable the optional "search" capability of the adapter, you have to implement the IMetadataSearchHandler[] interface from the Microsoft.ServiceModel.Channels.Common namespace. The WCF LOB Adapter Development Wizard generated the derived Hotel AdapterMetadataSearchHandler skeleton class for you.

[] http://msdn.microsoft.com/en-us/library/microsoft.servicemodel.channels.common.imetadatasearchhandler_members.aspx

The IMetadataSearchHandler interface is located in the Microsoft.ServiceModel.Channels. dll and is defined as follows:

public interface IMetadataSearchHandler : IConnectionHandler, IDisposable
{
MetadataRetrievalNode[] Search(string nodeId, string searchCriteria,
int maxChildNodes, TimeSpan timeout);
}


The Search method returns an array of the MetadataRetrievelNode objects that satisfy specified search criteria. We introduced this class earlier in the "Implementing IMetadataBrowseHandler" section.

We've listed the parameters accepted by the Search method in Table 14.

Table 14. IMetadataSearchHandler.Search Method Parameters
ParameterDescription
nodeIdThe node identifier to start the search from. If nodeId is null or an empty string, then the adapter will start evaluating nodes from the root node (/).
searchCriteriaSearch criteria. If not specified, the adapter should return all nodes.
maxChildNodesMaximum number of the child elements to return. To return all matching nodes, use the Int.Max32 value.
TimeoutMaximum time to wait to complete the operation.

Here is the process to implement the IMetadataSearchHandler interface:

  1. In Visual Studio, open the HotelAdapterMetadataSearchHandler.cs file.

  2. Find the IMetadataSearchHandler Members region, and replace it with the following code:

    #region IMetadataSearchHandler Members
    /// <summary>
    /// Retrieves an array of MetadataRetrievalNodes
    /// (see Microsoft.ServiceModel.Channels) from the target system.
    /// The search will begin at the path provided in absoluteName,
    /// which points to a location in the tree of metadata nodes.
    /// The contents of the array are filtered by SearchCriteria and the
    /// number of nodes returned is limited by maxChildNodes.
    /// The method should complete within the specified timespan or
    /// throw a timeout exception. If absoluteName is null or an
    /// empty string, return nodes starting from the root.
    /// If SearchCriteria is null or an empty string, return all nodes.
    /// </summary>
    public MetadataRetrievalNode[] Search(string nodeId
    , string searchCriteria
    , int maxChildNodes, TimeSpan timeout)
    {
    List<MetadataRetrievalNode> searchResult =
    new List<MetadataRetrievalNode>();

    searchCriteria = searchCriteria.ToLower();
    //we have only two operations
    // check them one by one
    if ("OnClientArrived".ToLower().Contains(searchCriteria))
    {
    MetadataRetrievalNode nodeInbound =
    new MetadataRetrievalNode("Hotel/OnClientArrived");
    nodeInbound.DisplayName = "OnClientArrived";
    nodeInbound.Description = @"This operation notifies
    external clients of client arrival.";
    nodeInbound.Direction =
    MetadataRetrievalNodeDirections.Inbound;
    nodeInbound.IsOperation = true;
    searchResult.Add(nodeInbound);
    }
    if ("GetRooms".ToLower().Contains(searchCriteria))
    {
    MetadataRetrievalNode nodeOutbound =
    new MetadataRetrievalNode("Hotel/GetRooms");
    nodeOutbound.DisplayName = "GetRooms";
    nodeOutbound.Description = @"This operation returns the
    number of available rooms.";
    nodeOutbound.Direction =
    MetadataRetrievalNodeDirections.Outbound;
    nodeOutbound.IsOperation = true;
    searchResult.Add(nodeOutbound);
    }
    return searchResult.ToArray();
    }
    #endregion IMetadataSearchHandler Members


  3. Save and build the project.

4.3. Implementing the IMetadataResolverHandler Interface

To provide ASDK with information on the operations and data types supported by the HotelAdapter, you have to implement the IMetadataResolverHandler[] interface from the Microsoft.ServiceModel.Channels.Common namespace. As we mentioned earlier, the IMetadataResolverHandler interface is used by ASDK when it generates proxy files or message type specifications.

[] http://msdn.microsoft.com/en-us/library/microsoft.servicemodel.channels.common.imetadataresolverhandler_members.aspx

The WCF LOB Adapter Development Wizard generated the derived HotelAdapterMetadata ResolverHandler skeleton class for you.

The IMetadataResolverHandler interface is located in the Microsoft.ServiceModel. Channels.dll and is defined as follows:

public interface IMetadataResolverHandler :
IConnectionHandler, IDisposable
{
bool IsOperationMetadataValid(string operationId,
DateTime lastUpdatedTimestamp, TimeSpan timeout);
bool IsTypeMetadataValid(string typeId,
DateTime lastUpdatedTimestamp, TimeSpan timeout);
OperationMetadata ResolveOperationMetadata(string operationId,
TimeSpan timeout,
out TypeMetadataCollection extraTypeMetadataResolved);
TypeMetadata ResolveTypeMetadata(string typeId, TimeSpan timeout,
out TypeMetadataCollection extraTypeMetadataResolved);
}

Table 15 describes what each method does.

Table 15. IMetadataResolverHandler Methods
MethodDescription
IsOperationMetadataValidReturns a Boolean value indicating whether operation metadata is valid. For the HotelAdapter, we assume that operation metadata is always valid.
IsTypeMetadataValidReturns a Boolean value indicating whether type metadata is valid. For the HotelAdapter, we assume that type metadata is always valid.
ResolveOperationMetadataMaps supplied operationId to corresponding Microsoft.ServiceModel.Channels.Common.OperationMetadata.
ResolveTypeMetadataMaps supplied typeId to corresponding Microsoft.ServiceModel.Channels.Common.TypeMetadata.

Here is the process to implement the IMetadataResolverHandler interface:

  1. In Visual Studio, open the HotelAdapterMetadataResolverHandler.cs file.

  2. Find the IsOperationMetadataValid method, and modify it to return true.

  3. Find the IsTypeMetadataValid method, and modify it to return true.

  4. Find the ResolveOperationMetaData method, and replace it with the following code:

    /// <summary>
    /// Returns an OperationMetadata object resolved from absolute
    /// name of the operation metadata object.
    /// The method should complete within the specified time
    /// span or throw a timeout exception.
    /// </summary>
    public OperationMetadata ResolveOperationMetadata(string operationId,
    TimeSpan timeout,
    out TypeMetadataCollection extraTypeMetadataResolved)

    {
    extraTypeMetadataResolved = null;
    ParameterizedOperationMetadata om =
    new ParameterizedOperationMetadata(operationId, operationId);
    // set this if you want this operation to belong
    // to this interface name
    // in the generated proxy, the interface name
    // will be HotelService and the client implementation name
    // will be HotelServiceClient.
    om.OperationGroup = "HotelService";
    // set the operation namespace to be same as service namespace
    om.OperationNamespace = HotelAdapter.SERVICENAMESPACE;
    switch (operationId)
    {
    case "Hotel/GetRooms":
    om.DisplayName = "GetRooms";
    om.OriginalName = "originalGetRooms";
    OperationParameter parm1 =
    new OperationParameter("hotelName",
    OperationParameterDirection.In,
    QualifiedType.StringType, false);
    parm1.Description = @"This string will
    contain hotel name for which
    number of rooms is being requested";
    OperationResult result =
    new OperationResult(new
    SimpleQualifiedType(XmlTypeCode.String), false);
    om.Parameters.Add(parm1);
    om.OperationResult = result;
    return om;
    case "Hotel/OnClientArrived":
    om.DisplayName = "OnClientArrived";
    om.OriginalName = "originalOnClientArrived";
    OperationParameter pName =
    new OperationParameter("FirstName",
    OperationParameterDirection.In,
    QualifiedType.StringType, false);
    pName.Description = "Client's first name.";
    OperationParameter pLastName=
    new OperationParameter("LastName",
    OperationParameterDirection.In,
    QualifiedType.StringType, false);


    pLastName.Description = "Client's last name.";
    om.Parameters.Add(pName);
    om.Parameters.Add(pLastName);
    om.OperationResult = null;
    return om;
    return null;
    }
Other -----------------
- SQL Server 2008 : Configuring the Instance (part 3)
- SQL Server 2008 : Configuring the Instance (part 2) - Specifying the Backup Compression Default & Enabling Login Failure Auditing
- SQL Server 2008 : Configuring the Instance (part 1) - Viewing Configuration Settings & Specifying Maximum and Minimum Server Memory
- Microsoft PowerPoint 2010 : Expanding PowerPoint Functionality - Loading and Unloading Add-ins
- Microsoft PowerPoint 2010 : Expanding PowerPoint Functionality - Viewing and Managing Add-ins
- Microsoft Dynamics CRM 2011 : Sending and Tracking Email Messages in Microsoft Dynamics CRM for Outlook
- Microsoft Dynamics CRM 2011 : Using Microsoft Dynamics CRM for Outlook - Using the Add Contacts Wizard
- Microsoft Dynamics CRM 2011 : Using Microsoft Dynamics CRM for Outlook - Creating and Tracking Contacts
- Windows Server 2008 R2 : Managing Disks and Disk Storage - Understand the Basics (part 2) - Work with Partitions & Use DiskPart
- Windows Server 2008 R2 : Managing Disks and Disk Storage - Understand the Basics (part 1) - Work with Your Storage
- SharePoint 2010 : Securing a SharePoint Farm
- SharePoint 2010 : Introducing SharePoint Security
- SQL Server 2008 : SQL Server Configuration Manager (part 2) - SQL Server Network Configuration
- SQL Server 2008 : SQL Server Configuration Manager (part 2) - SQL Server Network Configuration
- SQL Server 2008 : SQL Server Configuration Manager (part 1) - SQL Server Services
- BizTalk 2009 : WCF LOB Adapter SDK - WCF LOB Adapter Vivisected
- BizTalk 2009 : WCF LOB Adapter SDK - WCF LOB Adapters vs. WCF Services
- BizTalk 2009 : Understanding the WCF LOB Adapter
- SQL Server 2008 High Availability : Database Clustering
- SQL Server 2008 High Availability : Database Mirroring (part 2) - SharePoint and Database Mirroring
 
 
Most view of day
- Microsoft Visio 2010 : Modifying a Graphic (part 1) - Resizing a Graphic
- BizTalk 2006 : Getting Started with Pipeline Development (part 2) - Understanding Pipeline Execution, Understanding Interchanges
- Multi-Tenancy in SharePoint 2013 (part 2) - Multi-Tenant Use Cases, Partitioning in the Enterprise
- Microsoft Excel 2010 : Using Formulas - Copying a Formula, Formula Operators
- Windows Server 2003 on HP ProLiant Servers : Server Placement (part 1) - DNS Placement, Site Affinity
- Maintaining Desktop Health : Monitoring Reliability and Performance (part 5)
- Microsoft Project 2010 : Creating a Budget for Your Project (part 1) - Creating and Assigning Budget Resources
- Accessing and Using Your Network : Collaborating with Windows Meeting Space (part 2)
- Protecting Windows from Viruses and Spyware : Antimalware Strategy: Defense in Depth (part 1) - Windows Action Center
- Microsoft Word 2010 : Creating Desktop Publishing Documents - Adding Page Backgrounds (part 2) - Add or Remove a Page Border , Add Page Color
Top 10
- Windows Phone 8 : Scheduled Tasks - Scheduled Task API Limitations
- Windows Phone 8 : Scheduled Tasks - Updating Tiles Using a Scheduled Task Agent
- Windows Phone 8 : Scheduled Tasks - To-Do List Scheduled Task Sample (part 5) - Editing an Existing To-Do Item
- Windows Phone 8 : Scheduled Tasks - To-Do List Scheduled Task Sample (part 4) - Creating the To-Do Item Shell Tile, Saving a To-Do Item
- Windows Phone 8 : Scheduled Tasks - To-Do List Scheduled Task Sample (part 3) - Debugging Scheduled Tasks
- Windows Phone 8 : Scheduled Tasks - To-Do List Scheduled Task Sample (part 2) - TodoService, TodoItemViewModel
- Windows Phone 8 : Scheduled Tasks - To-Do List Scheduled Task Sample (part 1) - TodoItem,TodoDataContext
- Windows Phone 8 : Scheduled Tasks - Using Scheduled Tasks
- Windows Phone 8 : Scheduled Tasks - Background Agent Types
- Windows Phone 8 : Windows Phone Toolkit Animated Page Transitions - Reusing the Transition Attached Properties
 
 
Windows XP
Windows Vista
Windows 7
Windows Azure
Windows Server
Windows Phone
2015 Camaro