Fabrice's weblog
Tools and Source
-
Sandcastle, Microsoft's replacement for NDoc
Microsoft listened to our requests. It has announced its upcoming tool for generating MSDN-like documentation from your .NET code. The codename is Sandcastle and the tool is presented as a "Documentation Compiler". It should work the same way NDoc does, except it will support .NET 2.
The first release has been delayed and is now planned for August, as part of the next CTP release of the Visual Studio SDK. -
Library of free data models
The Library of Free Data Models provides "kick-start" database models for free. It can be useful to build examples or quickly start new database schemas.
-
Another series of Linq introductory posts
If you want to learn more about Linq, Bill Wagner has a great series over at his blog. Here is a link to the latest post, which includes links to all the other parts. Enjoy!
Cross-posted from http://linqinaction.net -
Strongly-typed reflection redux
As a followup to my last post, you can read Daniel Cazzulino's post in which he presents a solution for strongly-typed reflection that complements ayende's approach. Of course this implementation has limitations of its own, the major one being that it's based on lambda expressions and expression trees, two features that won't see the light of day before the next version of C# (sometime in 2007?).
-
Static method reflection
.NET reflection features are powerful and this is really what makes it a powerful platform. We don't use reflection everyday, but when we do it's really useful.
Don't you hate it though when you have to write code like this?:
MethodInfo method = typeof(MyClass).GetMethod("MyMethod");
The problem with this code is that we use a string to identify the method, which means that we don't get compile-time validation.
Ayende has an interesting approach to this problem. He gives you a solution that allows writing the following code instead:
MethodInfo method = GetMethod<int, string>(MyClass.MyMethod);
In this case, everything is strongly-typed and checked by the compiler.
Of course, nothing is perfect and this solution suffers from a number of limitations, but it's an interesting approach anyway. The limitations:- it works only with static methods,
- the methods need to be accessible (public or in your code's reach),
- we can't use a similar approach for properties.
Update: Daniel Cazzulino has another option that is more complete.
-
Tools galore
How many tools do you think we can use for .NET development?
Well, more than 905 tools (including 292 libraries) according to what I have referenced in SharpToolbox so far! How many do you actually know? ;-)
I started collecting this information more than three years ago now... It's been a while since I've taken a look at the counters.
If I remember well, the latest categories that I've added are Grid computing, Workflow, Rich-client UI. The categories with the most tools are IDE - IDE-addins, Persistence - Data-tier, Reporting, Object-relational mapping, and ASP.NET.
JavaToolbox is in good shape too with 558 tools including 196 libraries!
Searching for a tool? Keep digging, I have most of them in store :-)
-
Linq to Amazon implementation fore steps
On Monday, I have announced an implementation of Linq for Amazon Web Services, that allows to query for books using the following syntax:
var query =
from book in new Amazon.BookSearch()
where
book.Title.Contains("ajax") &&
(book.Publisher == "Manning") &&
(book.Price <= 25) &&
(book.Condition == BookCondition.New)
select book;
Before getting to the details of the implementation code, I'd like to describe what we need to do in order to be able to use such code.
First, as you can see we work with book objects. So, let's defined a Book class:
public class Book
{
public IList<String> Authors;
public BookCondition Condition;
public String Publisher;
public Decimal Price;
public String Title;
public UInt32 Year;
}
Here I use public fields for the sake of simplicity, but properties and private fields would be better.
You can see that this class defines the members we use in our query: Title, Publisher, Price and Condition, as well as others we'll use later for display. Condition is of type BookCondition, which is just an enumeration defined like this:
public enum BookCondition {All, New, Used, Refurbished, Collectible}
The next and main thing we have to do is define this BookSearch class we use to perform the query. This class implements System.Query.IQueryable<T> to receive and process query expressions. IQueryable<T> is defined like this:
interface IQueryable<T> : IEnumerable<T>, IQueryable
which means that we have to implement the members of the following interfaces:
interface IEnumerable<T> : IEnumerable
{
IEnumerator<T> GetEnumerator();
}
interface IEnumerable
{
IEnumerator GetEnumerator();
}
interface IQueryable : IEnumerable
{
Type ElementType { get; }
Expression Expression { get; }
IQueryable CreateQuery(Expression expression);
object Execute(Expression expression);
}
and finally the IQueryable<T> interface itself of course:
interface IQueryable<T> : IEnumerable<T>, IQueryable, IEnumerable
{
IQueryable<S> CreateQuery<S>(Expression expression);
S Execute<S>(Expression expression);
}
It may look like a lot of work... I will try to describe it simply so that you can create your own implementation of IQueryable without too much difficulty once you get to know how the mechanics work.
In order to be able to implement IQueryable, you need to understand what happens behind the scenes. The from..where..select query expression you write in your code is just syntactic sugar that the compiler converts quietly into something else! In fact, when you write:
var query =
from book in new Amazon.BookSearch()
where
book.Title.Contains("ajax") &&
(book.Publisher == "Manning") &&
(book.Price <= 25) &&
(book.Condition == BookCondition.New)
select book;
the compiler translates this into:
IQueryable<Book> query = Queryable.Where<Book>(new BookSearch(), <expression tree>);
Queryable .Where is a static method that takes as arguments an IQueryable followed by an expression tree.
I can hear you crying out loud: "What the hell is an expression tree?!".
Well, an expression tree is just a way to describe what you wrote after where as data instead of code. And what's the point?- To defer the execution of the query
- To be able to analyze the query to do whatever we want in response
And why is it called a "tree"? Because it's a hierarchy of expressions. Here is the complete expression tree in our case:
Expression.Lambda<Func<Book, Boolean>>(
Expression.AndAlso(
Expression.AndAlso(
Expression.AndAlso(
Expression.CallVirtual(
typeof(String).GetMethod("Contains"),
Expression.Field(book, typeof(Book).GetField("Title")),
new Expression[] { Expression.Constant("ajax") }),
Expression.Call(
typeof(String).GetMethod("op_Equality"),
null,
new Expression[] {
Expression.Field(book, typeof(Book).GetField("Publisher")),
Expression.Constant("Manning") })),
Expression.Call(
typeof(Decimal).GetMethod("op_LessThanOrEqual"),
null,
new Expression[] {
Expression.Field(book, typeof(Book).GetField("Price")),
Expression.Constant(new Decimal(25), typeof(Decimal)) })),
Expression.EQ(
Expression.Convert(
Expression.Field(book, typeof(Book).GetField("Condition")),
typeof(BookCondition)),
Expression.Constant(BookCondition.New))),
new ParameterExpression[] { book }));
If you look at this tree, you should be able to locate the criteria we have specified in our query. What we will do in the next step is see how all this combines and how we will extract the information from the expression tree to be able to construct a web query to Amazon.
We'll keep that for another post... Stay tuned!
Cross-posted from http://linqinaction.net - To defer the execution of the query
-
Introducing Linq to Amazon
As an example that will be included in the Linq in Action book, I've created an example that shows how Linq can be extended to query anything.
This example introduces Linq to Amazon, which allows querying Amazon for books using Linq! It uses Linq's extensibility to allow for language-integrated queries against a book catalog. The Linq query gets converted to REST URLs supported by Amazon's web services. These services return XML. The results are converted from XML to .NET objects using Linq to XML.
For the moment, let's look at the client code:
var query =
from book in new Amazon.BookSearch()
where
book.Title.Contains("ajax") &&
(book.Publisher == "Manning") &&
(book.Price <= 25) &&
(book.Condition == BookCondition.New)
select book;
I think this code speaks for itself! This is Linq to Amazon code. It expresses a query against Amazon, but does not execute it... The query will be executed when we start enumerating the results.
The following piece of code converts from Linq to Amazon to Linq to Objects:
var sequence = query.ToSequence();
The query gets executed this time and an enumeration of the resulting books is created.
The next steps could be to use Linq to Objects to perform grouping operations on the results. e.g.:
var groups =
from book in query.ToSequence()
group book by book.Year into years
orderby years.Key descending
select new {
Year = years.Key,
Books =
from book in years
select new { book.Title, book.Authors }
};
This allows to display the results like this:
Published in 2006
Title=Ruby for Rails : Ruby Techniques for Rails Developers Authors=...
Title=Wxpython in Action Authors=...
Published in 2005
Title=Ajax in Action Authors=...
Title=Spring in Action (In Action series) Authors=...
Published in 2004
Title=Hibernate in Action (In Action series) Authors=...
Title=Lucene in Action (In Action series) Authors=...
using the following code:
foreach (var group in groups)
{
Console.WriteLine("Published in "+group.Year);
foreach (var book in group.Books)
{
Console.Write(" ");
ObjectDumper.Write(book);
}
Console.WriteLine();
}
What a great way to query a catalog of books! Don't you think that this code is very legible and clearly expresses the intention?
Linq to XML can also be used to display the results as XHTML, and Linq to SQL can be used to persist the results in a database.
Over the coming days, I'll publish more details and the complete source code for this example.
Update: The next part of this series is available: Linq to Amazon implementation fore steps
Cross-posted from http://linqinaction.net -
Linq rebranding
Soma announced that the naming scheme for the Linq technologies has been simplified:
LINQ to ADO.NET includes:
So long DLinq and XLinq... Welcome Linq to Whatever!
LINQ to DataSet
LINQ to Entities
LINQ to SQL (formerly DLinq)
LINQ support for other data types includes:
LINQ to XML (formerly XLinq)
LINQ to Objects
I agree that this will make things a bit more explicit, especially the separation between what is related to ADO.NET and what is not. It will also help implementors find names for their products using Linq. We can expect to see more LINQ to Something in the future...
Cross-posted from http://linqinaction.net -
20-06-2006 20:06
As pointed out by Frank Arrigo, this is a fun date. Will this post make it to the right time?