Logo
programming4us
programming4us
programming4us
programming4us
Home
programming4us
XP
programming4us
Windows Vista
programming4us
Windows 7
programming4us
Windows Azure
programming4us
Windows Server
programming4us
Windows Phone
 
Windows Server

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

- Free product key for windows 10
- Free Product Key for Microsoft office 365
- Malwarebytes Premium 3.7.1 Serial Keys (LifeTime) 2019
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
 
 
Top 10
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 2) - Wireframes,Legends
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 1) - Swimlanes
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Formatting and sizing lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Adding shapes to lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Sizing containers
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 3) - The Other Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 2) - The Data Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 1) - The Format Properties of a Control
- Microsoft Access 2010 : Form Properties and Why Should You Use Them - Working with the Properties Window
- Microsoft Visio 2013 : Using the Organization Chart Wizard with new data
 
programming4us
Windows Vista
programming4us
Windows 7
programming4us
Windows Azure
programming4us
Windows Server