April 2007 - Posts

Orcas Beta 1 samples include a RSS feeder for C#, but there isn't one for VB, so I thought I'd slap one together.  Some things to note compared to the C# one is the use of XML literals an expressions.  Also note the use of LINQ expressions rather than using yield and custom enumerators.. the result is the same in terms of delayed evaluation even though this example doesn’t actually show that ;)
 
Option Strict On : Option Explicit On : Option Infer On
 
Imports System
Imports System.Collections.Generic
Imports System.Linq
Imports System.Xml
Imports System.Xml.Linq
 
 
Module Module1
 
   Const feedURL As String = "http://+:8086/vbfeeds/"
   Const feedURI As String = "http://localhost:8086/vbfeeds/"
 
   Function GetItems() As IEnumerable(Of XElement)
      Dim feeds() As String = {"http://msmvps.com/blogs/bill/rss.aspx", _
      "http://blogs.msdn.com/vbteam/rss.aspx", _
     "http://www.panopticoncentral.net/Rss.aspx", _
      "http://blogs.msdn.com/xmlteam/rss.aspx", _
      "http://blogs.msdn.com/aconrad/rss.aspx"}
 
      Return From feed In feeds _
         From item In XDocument.Load(feed).Root.<channel>.<item> _
         Select item
 
   End Function
 
 
   Function GetReplyBody() As XElement
      Return <rss version="2.0">
               <channel>
                  <title>VB Geeks</title>
                  <link><%= feedURL %></link>
                  <description>VB bloggers</description>
                  <generator>XLinq-based RSS aggregator</generator>
                  <%= GetItems.ToArray %>
               </channel>
            </rss>
   End Function
 
 
   Sub Main()
      Dim listener As New Net.HttpListener()
      Console.WriteLine("starting server")
      listener.Prefixes.Add(feedURL)
      listener.Start()
 
      Console.WriteLine("opening browser pointed at this server")
      Diagnostics.Process.Start("iexplore.exe", feedURI)
 
      While True
         Dim response = listener.GetContext.Response
         response.ContentType = "text/xml"
         Using writer As New XmlTextWriter(response.OutputStream, Text.Encoding.UTF8)
            GetReplyBody.WriteTo(writer)
         End Using
      End While
 
   End Sub
 
 
End Module
 
 
' for those interested this is the original C# source :
 
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Xml;
using System.Linq;
using System.Xml.Linq;
using System.Net;
 
// See the ReadMe.html for additional information
class app
{
   const string feedUrl = "http://+:8086/csharpfeeds/";
 
   static IEnumerable<XElement> GetItems()
   {
      string[] feeds = {
            "http://blogs.msdn.com/ericlippert/rss.aspx",
            "http://blogs.msdn.com/wesdyer/rss.aspx",
            "http://blogs.msdn.com/charlie/rss.aspx",            
            "http://blogs.msdn.com/cyrusn/rss.aspx",
            "http://blogs.msdn.com/mattwar/rss.aspx",
            "http://blogs.msdn.com/lucabol/rss.aspx",
            "http://www.pluralsight.com/blogs/dbox/rss.aspx",
            "http://blogs.msdn.com/jomo_fisher/rss.aspx"
        };
      foreach (var str in feeds)
      {
         var feed = XDocument.Load(str);
         var items = feed.Root.Element("channel").Elements("item");
         foreach (var item in items)
            yield return item;
      }
   }
 
   static XElement GetReplyBody()
   {
      return new XElement("rss",
         new XAttribute("version""2.0"),
         new XElement("channel",
            new XElement("title""C# Geeks"),
            new XElement("link", feedUrl),
            new XElement("description""C# Team Members"),
            new XElement("generator""XLinq-based RSS aggregator"),
            GetItems().ToArray()
            ));
 
   }
 
   static void Main()
   {
      var listener = new HttpListener();
 
      listener.Prefixes.Add("http://+:8086/csharpfeeds/");
      listener.Start();
 
      // Open a browser pointing at the feeds being served.
      string uri = @"http://localhost:8086/csharpfeeds/";
      System.Diagnostics.Process browser = new System.Diagnostics.Process();
      browser.StartInfo.FileName = "iexplore.exe";
      browser.StartInfo.Arguments = uri;
      browser.Start();
 
      // Serve requests.
      while (true)
      {
         var context = listener.GetContext();
         var body = GetReplyBody();
         context.Response.ContentType = "text/xml";
         using (XmlWriter writer = new XmlTextWriter(context.Response.OutputStream, Encoding.UTF8))
            body.WriteTo(writer);
 
      }
   }
}
 
 
 
with 1 comment(s)
Filed under: , ,
well so much for the early morning "LIVE" web cast.  The web cast ended up being cancelled after 40 minutes of them trying to get the sound going.  Absolutely terrible, and I'm certainly not in any hurry to stay up till 2 AM to sit through that again.  What's worse is I feel really bad for pinging friends on IM to join the web cast only to have them sit through 40 minutes of elevator music and no visuals, broken up with the occasional "testing 1, 2, 3".
 
Will I recommend anyone watch the live web-casts… absolutely NOT.
 
What I do recommend is waiting till they become available on demand :)  You can search for all VB.NET web-casts here.  Or subscribe to the RSS feed for all on demand web casts.
 
 
with no comments
Filed under: , ,
 
 
Start Date: 4/18/2007
Start Time: 9:00 AM (GMT-08:00) Pacific Time (US & Canada)
End Date: 4/18/2007
End Time: 10:00 AM (GMT-08:00) Pacific Time (US & Canada)
 
which translated to local time is Thursday April 19th, 2007 2 AM to 3 AM.. d'oh ….. ;)
 
 
with no comments
Filed under: ,

Earlier today I got asked about routed events for WPF in VB.  Unfortunately the only examples in msdn library are in C#.  So to help out I posted a simple routed event declaration and some associated declarations. All good ? Well not really.  As always with cut and paste code there's pieces that need to be replaced that get easily overlooked.  That's why snippets are so good, because you can indicate the pieces that need to be replaced.

 

So, in case anyone else wants a sample of routed event declaration for WPF in VB, here's a snippet to help you out. Enjoy :)

 

 

with no comments
Filed under: ,
I've seen a couple of people have had problems with application property pages and the March CTP.  Although I never bothered to try to isolate the problem properly, I can say I too had that and solved it by installing just the March CTP (no TSFS) on a windows XP image.  Previously I had it installed on a Vista image and the problem occurred, and I think it also occurred on the downloaded image from MS that was windows 2003 with TSFS.
 
So try installing the CTP on a windows XP image. :)
with 2 comment(s)
Filed under: ,
Saw this article today about images of a nebular and computer modelling to show how the 2D image relates to the proposed 3D model. News story here, image from www.space.com
 
with 2 comment(s)
Filed under:
The latest from Microsoft's Developer Marketing is hilarious !  Seems some folks at MS have way too much time on their hands… 
But then again what am I doing watching the videos there ? <g>
 
you have to watch the "Team Call" video, I'm sure we've all been to that meeting ;)
 
 
 .
 
with 1 comment(s)
Filed under: ,
Sometimes cars seem to manifest certain personas about their owners, be it the hippy volkswagen,  through to the hoon car. Well yesterday I think I noticed one I hadn't really seen before. It could be just coincidence of course …..
Yesterday morning, Easter Sunday, my pager went off to attend a car accident.  A local bloke had wrapped his car around a tree and was pinned inside. He had to be extracted and air lifted to hospital.
So a few of us got the job of diverting traffic around the scene while the SES guys did their job.  Basically people had to detour a couple of minutes out of their way.  And for the most part people were really good; some were concerned, others just happy to detour.  Most people that is.
 
Strangely enough we had two drivers who seemed to think that shouldn't apply to them, and acted as if they were so inconvenienced :s  Pretty hard to understand really. I mean there we are, a couple of dozen members of the community giving freely of our Easter Sunday morning as part of the greater community to try to help save someone's life. And then we have a couple of people who feel so put out at having to go a couple of minutes out of their way.  I mean really what did they expect , us to clear all the emergency vehicles off the road for them ? <g>
 
the one thing I realised later about these two drivers, was they both had expensive new cars (well probably the most expensive ones we saw that day).  Is there a correlation there ?  Is it they feel because the car cost so much they "own" the road. Does new expensive car equate to the "arrogant" driver ?
 
 
 
with 2 comment(s)
Filed under: ,
Tim Ng has made a post about using a helper function to create a generic list for anonymous types.
The code actually needs a bit of modification, it should really be :
 
Function MakeList(Of T)(ByVal ParamArray items() As T) As List(Of T)
   Dim list As New List(Of T)
   list.AddRange(items)
   Return list
End Function
 
You can then pass to it any number of items for your anonymous type.
 
Still, that being the case, the inference could be made at a more direct level if the language supported an anonymous type placeholder, be it var, ? or some other symbol. That is, it should be possible to write code such as :
 
Dim things As ? = New List(Of ?) {New With {.Description= "meaning of life", .Age = 42}, _
                                             New With {.Description= "meaning of life sequel", .Age = 43}}
 
And hence remove the need for yet another helper function.
 
hopefully we can elegantly make the language evolve in such a direction :)       
 
 
 
 
with no comments
Filed under: , ,
I was just catching up on some blog reading and I was really amazed to see some of the public discussions of the private NDA covered discussions people had at the MVP summit.  I was reading one comment about how an MVP felt ashamed to be a MVP or some nonsense because he didn't share the opinion of another MVP… no not me, but I was there and know exactly what was being referred to.
The thing that really annoys me about that is
(a) blog readers will never hear the full story because the meeting is supposed to be under NDA
(b) it fails to recognise that the MVP program is a **diverse** set of individuals
(c) the person dragging this into the public has failed to use the other avenues open to them to discuss this, so as there can be growth or understanding etc
(d) it's a breach of trust
 
Now I've just taken one example, but there's plenty more.  MVPs gathered to have technical discussions, on what are often sensitive issues.  We did so under NDA.  Yet a handful think that obviously doesn’t apply to them because they want to publicly cast bad assertions about other MVPs.
Sadly, this isn't the first time I've seen this, but it does it always seems, to coincide with the "opening" up of the MVP program to new folk or other people form the community.
 
Sometimes I think they just don't get it.  Imagine if at work every time you discussed something, supposedly within the group, and you then had someone go and start saying bad things about the team publicly because one person had a different point of view.
 
Anyway, me, I love to hear what others have to say.  the more passionate they are about something, then perhaps the more we should listen.. make that time.  I know my own ideas take greater shape when I listen to what others say.  Doesn't mean I have to agree with them, but the knowledge of, and perception of the different view points is, IMO, what builds great solutions.
 
 
 
 
with 1 comment(s)
Filed under: ,

I was just reading Julie Lerman's blog entry about LINQ, herself and Anders et al.  I remembered chatting with the guys at Redmond Developer News on this subject, but it wasn't till I read the article that Julie points to did I see the final quote attributed to me

:) 

 

 

with 1 comment(s)
Filed under: , ,
I forgot to mention that in the previous discussion, you could exchange the type Expando for an untyped datatable/dataset.  yes dynamic interfaces using a dictionary look up for properties would apply equally to data tables and for that matter, datasets.
 
 
 
with no comments
Filed under: , ,
A frustrating limitation of LINQ and anonymous types is that the type has to be resolved at compile time.  So "Reporting" style of queries where you can dynamically add and remove columns isn't really catered for…….
 
However, let's say you had a type which fro want of a better name, I'll call Expando.  This type stores properties in a dictionary, that is each property name is the dictionary key to the value.  The problem with this is it would be missing type information, so although you'd have the runtime dynamic nature, any design time code would be dealing with type Object and continually require field(Of t) calls or CType operations etc to gain strong typing.
 
Now consider we add to this the ability to have dynamic interfaces as what was once on the cards for VB9.  A dynamic interface would mean the type has those methods/properties, but doesn't actually need to implement an actual interface… a runtime matching that gives design time strong typing.  We'd be close, but our Expando type only has a dictionary Item property for all the properties.
But Item is also marked as Default.  So really all we'd need on is a way to tell the compiler that the dynamic interface property needs to use the Default dictionary Item, e.g.
 
Dynamic Interface Person
    <DictionaryItem>Property Name As String
    <DictionaryItem>Property DOB as Date
End Dynamic Itnerface
 
This would allow you to cast an Expando instance to a Person interface, e.g:
 
Instead of:
      If CType(myExpando("DOB"), Date) > Today.Addyears(-18) Then
          MsgBox CType(myExpando("Name"), String)  & " is under 18"
      Else
          MsgBox CType(myExpando("Name"), String)  & " is over 18"
      End If
 
 
you could cast to Person early on and use a Person interface, e.g:
 
      Dim p as Person = CType(myExpando, Person)
      If p.DOB > Today.Addyears(-18) Then
          MsgBox p.Name  & " is under 18"
      Else
          MsgBox p.Name  & " is over 18"
      End If
 
And you'd get the intellisense experience.
 
The nice thing about dynamic interfaces and a dictionary expando type is that the type could contain many other key value pairs (properties), but that won't impact on the usage as long as it has the ones you are interested in.
 
This brings us to the difficult part of such as a design.. what to do when things go wrong ?  I think it would be nice if you could tweak it to either throw an exception when a key doesn't exist, or to instead return Nothing and not throw an error. This of course could be a behaviour of the Expando, or alternatively a declaration made on the interface that the compiler would interpret.  The benefit of being on the interface is it would offer greater granularity.
 
Other parts to polish all this would be to perhaps have a DoesExist method, and rather than pass it a string for the property key, you could pass it NameOf(Person.DOB) or similar, thus allowing symbolic renaming to work throughout and avoiding the dreaded string literal issues that can occur with dynamic properties.
 
 
.
 
 
 
 
 
 
 
 
with no comments
Filed under: , ,