Linq to Amazon source code
A while ago, I
announced Linq to Amazon
and
started to describe how it's implemented. Actually producing some content for the book and summer
holidays kept me busy for a while, but here is finally the
last part of this series of posts.
In the
previous post, I said that what had to be done to create the
Linq extension is to implement the
IQueryable<T> interface, and write the code
that converts an expression tree into an Amazon query.
What
I have done is just a quick and dirty implementation. The
goal is not to provide a complete solution to query Amazon
using Linq, but instead to create an example to give you an
idea of how the Linq extensibility stuff works. As you will
see by looking at the source code, a lot of work would be
required for a complete implementation.
Let's
describe what you'll find in the source code.
The
BookSearch class implements
IQueryable<Book>. This interface speaks for
itself. An object that implements it can be queried for
Book objects! A BookSearch instance is what
we'll query. Our queries start with code like the
following:
var query =
from book in new
Amazon.BookSearch()
...
The important method to look for in the
BookSearch class is CreateQuery<S>. This method receives an argument of type
Expression. This is our expression tree. All that the
CreateQuery<S> method does is creating and
returning a new instance of the BookQuery class,
passing the expression tree to its constructor.
The BookQuery class also implements
IQueryable<Book>, but doesn't handle the same
methods. First, an important thing to understand is that a
BookQuery object keeps the expression tree it
receives in its constructor as a private field. This will
allow the BookQuery object to analyze the expression
later on, when needed. The key point here is that a
BookQuery instance represents a given query, which is
defined by the expression tree. A different query produces a
different expression tree of course.
The method to look
at in the BookQuery class is
IEnumerable.GetEnumerator. This is where everything happens: we parse the expression
tree, we convert the Linq query into a web query, perform
the web query, create a collection of the resulting books
and return the book enumeration.
The other pieces of
code you'll want to look at are the methods that visit the
expression tree to extract the query criteria (the
ProcessXXX methods), and the method that
performs the web query using Linq to XML (the
PerformWebQuery method).
I won't
provide you with more details at this point. The source code
(see below) is free for you to look at. Of course feel free
to ask any question, and I'll do my best to help you.
Again,
this is a straightforward implementation. This
implementation supports only simple queries and is likely to
fail if you try to use it with different queries... This
code has been written without help from Microsoft. There is
no documentation on expression trees or on how to implement
IQueryable.
By the time the
LINQ in Action book is out, we should have
more information from Microsoft and I'll adapt this sample
as needed.
In the meantime, feel free to play
with Linq's extensibility and to give a try to creating your
own implementations! I'd be really happy if you let me know
what you are up to :-)Linq to Amazon source code
=>
The source code has been updated for .NET 3.5 and VS
2008. It is available for download as part of the
complete source code in C# and VB for the LINQ in
Action book.
Note: In order to use the Amazon.com web services and test
this example fully, you need to register with the
Amazon Web Services program. After registering with Amazon you will be assigned an
access key. Edit the BookQuery.cs file and replace INSERT
YOUR AWS ACCESS KEY HERE by your access key.
Cross-posted from
http://linqinaction.net
