Archive for February, 2008
It’s been a long, long time
It’s been years since a new technology actually got me to the point of being “excited”. .NET 2.0 almost did it, but I think the day I finally ‘got’ .NET 1.0 was the last time I was truly excited about a new technology for its own sake. I think I feel it happening again. Between the sheer joy LINQ is inspiring into my daily work (“the data, it just is, it’s just there, it’s… wow!”) and my newfound love of the web that’s arriving through studying the concepts of the semantic web (Check out “Microformats” by John Allsopp) it’s been getting better and better. Earlier this year I was able to spend a lot of time working with WPF and had a GREAT time with that. Now, I see Scott’s two posts on Silverlight 2 and get more and more excited about the potential for the web.
It’s a good time to be coding, that’s for sure. And, I have to say, I wouldn’t be using _ANY_ of this if I didn’t have the focus for ongoing learning like I have had for the last few years. If I wasn’t learning, I’d be sitting somewhere doing .NET 1.1 maintenance work and being excited that I’m learning a bit of .NET 2.0 from the architects.
Linq to XML follow up – how the magic works
If you’re curious how the XNamespace works, just do a “Go to Definition” in VS and you’ll see the declarations, the key aspects are:
public static bool operator !=(XNamespace left, XNamespace right);
public static XName operator +(XNamespace ns, string localName);
public static bool operator ==(XNamespace left, XNamespace right);
public static implicit operator XNamespace(string namespaceName);
The last one is what allows me to write code like this and have it compile… note the lack of a constructor:
XNamespace ns = “http://schemas.microsoft.com/winfx/2006/xaml”;
More LINQ (to XML) happiness
Namespace handling is much improved! Yay for easy namespaces!
Anybody who has worked with XML in .NET 1.x or 2.0 knows how much of a pain XML namespaces can be in extracting data, yet they fill a very important part of the XML technology. Now, for linq.
Let’s say you’ve got a document on disk and you need to pull out the namespace of the root element. I’m messing with XAML, and here’s the code to open the file and extract the namespace.
XElement xamlCanvas;
using( StreamReader sr = new StreamReader( path ) )
{
xamlCanvas = XElement.Load(sr);
}
XNamespace ns = xamlCanvas.Name.Namespace;
The next thing I want to do is pull out a List<XElement> all of the child elements with an element name of “Canvas” and a “Tag” attribute of “Text”. Easy!
IList< XElement > matchingElements =
xamlCanvas.Descendants( ns + “Canvas”)
.Where<XElement>(xe => xe.HasAttributeWithValue( “Tag”, “Text”))
.ToList<XElement>();
templateContentMap.Add(ct, matchingElements );
The key element to notice is the one in bold – I just ADDED the tag name to the name of the element! How does that work? Well, first, “Canvas” is actually being implicitly converted to an XName instance, and XNamespace + XName is a perfectly valid expression of a node’s XName (can I XUse any more X’s?) This implicit conversion is making life easier throughout Linq to Xml, to the point it’s happening without me evening needing to be aware of it most of the time. Also, for completeness, that same thing could have been xamlCanvas.Descendants( “{http://schemas.microsoft.com/client/2007}Canvas” ) just as correctly, but I wanted to limit what was hard coded.
As an aside, HasAttributeWithValue is an extension method I wrote to clean up the lambda – it’s implemented as such:
public static class XElementExtensions
{
public static bool HasAttributeWithValue(this XElement element, string name, string value)
{
if ( element.Attribute(name) == null )
return false;
return element.Attribute(name).Value == value;
}
}
IIS logs and TFS
A caution – you probably want to turn off the IIS logging on your TFS services if it happens to be on. Our server has all the data on the D drive, so the C drive is rather small. It causes some problems when the 5 gigs of logs for access to the version control service maxes out the available drive space. Our 20 person team was generating around 100MB of logs every day. (I could tell when people worked the weekends, too, because the build server’s periodic pings only account for about 500K per day, so I could see activity levels as a graph of log size )
Sanity check: is your process doing what it needs to?
I rarely repost, but this single, fairly short article seems to hit many of the high points in a very condensed format. If I were in a southern church hearing this read i would expect a constant stream of “Amen” echoing around me. Read it. Think about it. Read it again. Then, compare this to what you’re doing.
http://epistemologic.com/2008/02/23/a-project-delivery-sanity-test/
Difference between setting InnerText and InnerHtml
What’s the difference between these two lines?
scriptInit.InnerHtml = string.Format(creationFormat, outerDiv.ClientID, someOtherString);
scriptInit.InnerText = string.Format(creationFormat, outerDiv.ClientID, someOtherString);
Answer: The first one doesn’t do special character escaping, the second one does.
With a format string that looks like “createSilverlight(‘{0}’, ‘/{1}.xaml?x=233&y=300&m=1\’ );” it got a bit ugly with the &’s coming out as &, especially when it came back around to the server with the query string mangled.
Test Driven Book Reading
http://blogs.msdn.com/jmeier/archive/2008/02/19/5-keys-to-improving-your-reading-speed.aspx
I like it – I use a lot of these techniques when I’m reading technical books for specifics… less so when I’m looking for an overall introduction to a new technology, since I don’t know what all the questions are when I start. I do tend to shift half-way through to the question-based approach.
This is just a specialization of defining success criteria, and then executing a repeatable (yet flexible) procedure to fulfill those criteria. Thus, Test Driven Development Book Reading (not to be confused with what I did right before taking my MCPD exam, which was read the chapters that correlated to what I failed in the sample test, which again could be considered Test Driven Book Reading)
Linq is GREATNESS!
Freaking amazing.
Scenario: I need to load the contents of a table into a dictionary of objects keyed by one of the fields.
Before: Write the ORM code to load the entire table. (3 lines) Initialize the dictionary (1 line). Write the for each loop to move each instance from the ORM’s collection type into the dictionary (3 lines).
After: Write the link query to get the day, then use an extension method + lambda to build the keyed dictionary and assign the result to the dictionary field (1 line).
Wow!
myDictionary = db.UsageTypes.ToDictionary<UsageType, int>( t => t.UsageTypeID);
The only thing I can’t find is the basic extension method that would serve as essentially a foreach. All of the ones I’ve investigated on the IList<> extension list seem to be filtering and grouping… the .All<> seems like it SHOULD work, but it still expects a boolean return for filtering. I want something where I can do an operation with a simple side effect, like call add on another list (I know there’s better ways, but I’m trying to generalize a bit). I want something like:
myListOfT.Apply<T>( t => otherThing.SomeMethod(t));
[EDIT]
The concept I’m looking for is myListOfT.Action<T>( lambda ), but I still don’t see it in the library… it’s just implied from some things I was reading on the Parallel Development forums on MSDN.
[EDIT2]
DUH! List.ForEach<T>(Action<T>()). Just only exists on the list, not on the interface.
Linq is Goodness
I’m almost beyond words in a geeky technical sort of way. The ease and simplicity of accomplishing my desires is releasing a sense of joy that I have not felt professionally for quite some time. My desire is made manifest, and I don’t have to fight the constraints of the environment to make it happen.
I’ll let you know when the honeymoon is over, but this is a good start to a long, happy technical marriage
Brilliant!
My boss had the phrase of they day “Beer drinking SIG”… so, how about it Indy bloggers and Indy NDA’ers… do we need a Beer SIG where we can meet once a month? I know Hacker’s been wanting to do something like this too…
