oreilly.comSafari Books Online.Conferences.


AddThis Social Bookmark Button

Creating an Application from Scratch, Part 3
Pages: 1, 2, 3, 4, 5

Implementation Overview

The two key methods are FindBooks and FindReviewers.

FindReviewers after the AllReviewers collection has been filled with just my ReviewerID. To keep this clear, I differentiate between myReviewerID (my own Amazon CustomerID) and the ReviewerID for all the other reviewers I'll find who also reviewed the books I've reviewed.

To begin, I clear out the table of my reviews. This is simpler than looking for changes and updating the table; I simply start clean each time.

The FindReviewers method then retrieves all my reviews from Amazon and inserts them into the Reviews table, and adds the book to my type-safe list of Book objects (which holds my rating of the book).

When I've found all my reviews I call FindBookInfo.

FindBookInfo iterates through the MyBooks collection, and for each book requests an ItemLookup from Amazon. It gets back a list of the CustomerIDs of everyone who has ever reviewed that book. I add an entry to the Books database table for each book found, by calling InsertBook() which in turn calls the InsertBook method we added to the booksTableAdapter (listing 3, above).

For more about this decisioin to store this book information in the database, see the sidebar "Book Table Design Question" below.

In any case, the reviewer's ID is added to the AllReviewers dictionary, along with a score computed by finding the difference in our reviews, and subtracting that number from 5 (a simple working algorithm that may well be adjusted in subsequent builds).

Once all the books I've reviewed have been traversed, we return to FindReviewers. This time, however, the AllReviewers collection has all the CustomerIDs of all the customers who have reviewed all the books I've reviewed. For each reviewer, we make a call to Amazon to get all their reviews, and enter their rating. In addition, if the review corresponds to a book I've reviewed, their score is incremented based on how closely our reviews match.

It is worth noting that FindReviewers is thus called twice: once just to find my reviews, and a second time to find all the reviews of all those who have reviewed any of the books I've reviewed. This makes for more code reuse, and less redundancy, at the cost of having more conditional code (e.g., if ( reviewerID == myReviewerID ) ).

Book Table Design Question

It isn't yet clear to me whether I should store the data on each book (author, title, etc.) at this point, or just get that data as needed from Amazon.

My compromise for now is that since I have to get the book information for every book I've reviewed, I might as well store it away, but for the books reviewed by other reviewers, I plan to get it on demand from Amazon.

Interacting with Amazon

We make two types of calls to the Amazon E-Commerce Web Service . The first is in FindReviews in which we execute a call to CustomerContentLookup that returns a collection of customers and all the reviews by that customer.

The interaction is not completely intuitive, so let's walk through it step by step.

First, as described in the previous article, we add AWSECommerce.cs which is the proxy code generated from the Amazon WSDL, and which is available ready-to-use from Amazon as part of their web services kit. An short excerpt of this file is shown in listing 4 to give you a flavor of what it contains.

 public class AWSECommerceService : System.Web.Services.Protocols.SoapHttpClientProtocol 
    /// <remarks/>
    public AWSECommerceService() {
        this.Url = "";
         [System.Web.Services.Protocols.SoapDocumentMethodAttribute("", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Bare)]
    [return: System.Xml.Serialization.XmlElementAttribute("CustomerContentLookupResponse", Namespace="")]
    public CustomerContentLookupResponse CustomerContentLookup([System.Xml.Serialization.XmlElementAttribute("CustomerContentLookup", Namespace="")] CustomerContentLookup CustomerContentLookup1) {
        object[] results = this.Invoke("CustomerContentLookup", new object[] {
        return ((CustomerContentLookupResponse)(results[0]));
    }Listing 4

We will use the object-oriented wrapper classes created by the proxy to interact with Amazon. For example, we'll declare a set of objects for making a CustomerContentLookup call:

CustomerContentLookup customerLookup = new CustomerContentLookup();
CustomerContentLookupRequest customerLookupRequest =
    new CustomerContentLookupRequest();
CustomerContentLookupResponse customerLookupResponse;

Pages: 1, 2, 3, 4, 5

Next Pagearrow