Nick's .NET Travels

Continually looking for the yellow brick road so I can catch me a wizard....

VB.NET Meets the DebuggerDisplay Attribute in VS2008

One of the most annoying things I find about working with the Guid class is that in order to see what the value is you have to go into a watch window and query myguid.tostring(), this doesn't sound like too much work but if you are used to relying on datatips it can quickly be quite annoying.  For a while I've thought about writing a debugger visualiser or type proxy to add my own datatip for the Guid class and today I got off my backside and did it.....

The steps for doing this are relatively simple:

  • New Project (VB.NET or C#, doesn't really matter - at this stage anyhow)
  • Add Reference: C:\Program Files\Microsoft Visual Studio 8.0\Common7\IDE\PublicAssemblies\Microsoft.VisualStudio.DebuggerVisualizers.dll
  • Add the following attribute to any code file (most likely assemblyinfo.vb)
  • Imports Microsoft.VisualStudio.DebuggerVisualizers
    <Assembly: DebuggerDisplay("Guid {ToString()}", Target:=GetType(Guid))>

Now build this assembly and drop it into Documents\Visual Studio 2005\Visualizers.  Open up a new instance of Visual Studio, open an existing or new project that uses the Guid class.  Run the project with a breakpoint set so you have an instance of a Guid that you can mouse over:

image

And hey presto you have a useful datatip for the Guid class...... WRONG.  What you see here is the datatip in Visual Studio 2008 for VB.NET.  In Visual Studio 2005 this only seems to work properly for C#, VB.NET doesn't seem to properly support the DebuggerDisplay attribute (Note you can still follow the above steps in either VB.NET or C# to create the implementing assembly, it's just the executing code that needs to be in C# in VS2005). 

Perth .NET Community of Practice: Nick Wienholt on Code Generation

Next week Nick Wienholt will be in town to present his session on Code Generation.  The details are (full details on the user group site here):

Real-World Code Generation with Nick Wienholt

  • Topic:            Real-world Code Generation with Nick Wienholt
  • Venue:          Excom, Level 2, 23 Barrack Street, Perth
  • Date/Time:  Sept 6th, 5:30pm
  • Cost:           Free. All Welcome.

The user group is also organising a geek dinner at Arirang (Korean BBQ) on Barrack street.  As this will be my last user group before I head off to Sydney it would be great to catch up with as many of you as possible.  If you feel like coming please email Mitch and let him know (btw it's pay-your-own) 

.NET Compact Framework Answers Here

Well actually not quite here - you will have to wait for the .NET Compact Framework Chat to be hosted by Neil Cowburn, of OpenNETCF fame, on the 29th August.

If you have some burning .NET CF, or other mobile development, questions then you should book mark this chat as there will be a swag of MVPs, Microsofties and of course the OpenNETCF team there to answer them.

You can enter the chat here: http://chat.opennetcf.com/
August 29, 6pm - 7pm (London), 10am - 11am (Redmond)

Neil has also committed to making a transcript of the chat available via his blog for those people, such as myself, who might prefer to get some sleep at that time of day.

Perth .NET - Introducing Graeme Foster

Despite being a relatively new import into the Perth .NET community, Graeme Foster has already volunteered to present at the next meeting of the Perth .NET Community of Practice.  Whilst the last session was dedicated to all the new coolness that Microsoft is bringing us in the UX space there are still a lot of fundamentals that most organisations don't do well.  Graeme is ambitiously going to cover CAB, MVP and TDD all in one session.

Most people have heard or the Composite Application Block (CAB), the Model-View-Presenter (MVP) pattern and Test Driven Development, but few can really say that they can use them together.  Luckily some of the larger development shops around Perth are starting to use these to build a real world applications.

Check out Graeme's session on the 2nd of August!

Perth .NET User Group gets Jobs Board

In addition to our expanding library the Perth .NET Community of Practice has recently put together an aggregate feed that allows recruiters to post Perth based job notices.  You can subscribe to this feed from here or using the RSS button on your web browser when visiting the user group website (http://www.perthdotnet.org).

Congratulations to Robert Walters who are the first to make use of this resource by placing a 1Yr C# .NET Application Developer contract on the feed!

.NET Compact Framework 3.5 Redistributables

Anyone working with Visual Studio "Orcas" to build mobile applications should be aware that the v3.5 Beta 1 Redistributable are now available from MS Downloads.  There is also a good list of the new features that have been added to v3.5 of the .NET CF.

If you have been following Mark's blog and have been wondering why the WCF over Email sample doesn't work you will be relieved to know it's not just you!  The redistributables are NOT the same binaries as what comes with the Orcas B1 installation/VPC. The redistributables actually contain a fix as documented on the download site.

Bug Fix
The beta1 build of the .NET Compact Framework which shipped in Visual Studio ‘Orcas’ Beta1 does not allow for any project referencing Microsoft.ServiceModel.Channels.Mail* dlls to be compiled. If you’re using Orcas Beta1 and you need to build using these dll’s, first uninstall .NET Compact Framework v3.5 beta1 then download and install this version of NETCFSetupv35.msi.

Secret .NET Developer Business....

Ok, there are rumors starting to emerge that someone special has been oganised for next months [PerthCoP] meeting, which btw is Thursday June 7th.  My sources have informed me that the presenter is:

  • A former Microsoft employee
  • Recently ranked the #2 presenter at CodeCamp
  • Can do 2 things at a time, despite being Male....
  • Is traveling interstate to come and present

I think there should be enough clues the for you to work out who it is!

You might want to paste this into your calendar as the meeting will apparently start a little earlier than usual and be held at a yet to be disclosed venue.  This will then be followed by a community dinner where you get to throw curved balls at our guest.

Keep your eyes on the user group announcements feed for more information.

What .NET Framework Version am I running?

Someone on the Stanski mailing list recently asked about a particular version of the .NET Framework (v1.1.4322.2379 which seems to almost be MIA and almost no useful information on Google).  What came out of the conversation are a couple of applications/tools. 

The first is a free .NET version checking utility which the guys across at TMG Development have built.  On their download site they also have a quite comprehensive list of the different framework versions (although the mysterious version is missing from that list too).

Early this afternoon I also came across a Microsoft site that will inspect the current version of a dll and provide you with information about what the dll is, when it was shipped and in which packages it was included - this might some day be useful so I figured I'd keep a reference to it here.

C# v's VB.NET v's others

This sounds like I'm trying to start a food-fight.  In fact, courtesy of Steve, Development Manager here at [Intilecta], I thought I'd share an interesting article that talks about the Language V's Tool divide (Full article available here).  Just as an aside, the author of this article seems to be involved with the OpenLaszlo project which strikes me as "just another web technology" (it might ease the pain of doing web development but it won't make it go away....)

Ok, so back onto the topic of this post - the article points out that if you have $100 to spend on improving a language you have to choose between spending money on improving the language itself (thus increasing the power and efficiency with which developers can write code) or tool support (which can also improve the efficiency of the developer).  Try as you might you are not a magician and you can't make $100 into $200 and thus be able to do both. 

Now apply this logic to the C# v's VB.NET debate and the decisions the teams make about priorities.  Clearly with C#'s background in C, C++, Java and other languages there has always been a strong focus here on extending the language.  That said, with [VS2005] C# made considerable improvements around intellisense and refactoring. 

On the converse VB.NET has always been the leader when it comes to tool support for the language.  Whilst the language did get most of the features of C# (such as generics, nullable types etc) there were a few things which were left out -> iterators and anonymous methods to name just two.  So where did the VB.NET team spend their $100 - the My Namespace?  Agreed My does provide significant savings when it comes to doing common task but I must admit I was sorely disappointed that the VB.NET team decided not to give us feature parity w.r.t. the language.  Further more our complaints seem to be going unnoticed with iterators and anonymous methods still missing the cut for the Orcas release.

The argument keeps coming out from Microsoft that they need to differentiate the two languages to justify the cost of maintaining two languages, compilers etc.  Quite frankly I think this is a silly response and that if this is their primary concern, then they should just get on with it and axe one of the languages. This would not only free up resources to be more innovative it would also stop this continual need for developers wasting valuable resources deciding which language to code in (after all if we only had feature parity there would be no discussion....)

Logging options for .NET Compact Framework

Since the first coffee meeting I have been hassling Alan to start blogging.  After migrating the user group's website across to Community Server I was able to set a blog up for him and he just submitted his first post.  One of the pain points for a number of mobile developers is what to use for logging.  Most developers end up doing their own custom solution.  At Intilecta we ripped out most of the useful bits from the Patterns and Practices Enterprise Library.  Based on what Alan has to say in his post I think I would definitely look at log4net as it seems to be quite comprehensive and it runs on the .NET Compact Framework.

Java is no more open source than .NET

This afternoon I found myself reading an article at The Spot 4 SAP entitled SAP Mobile Engine.  Leaving aside the fact that the article hasn't been written very well at all I want to comment on their continual reference to the Java platform as an "open source technology".  Now the last time I checked Sun still owned the rights to the language and it was their decision as to the changes that are made (please correct me if I'm wrong as I haven't worked in the Java space for quite some time). 

I would like to make the comment that it is possible to write open source software with either Java or .NET and that they choice of technology should in no way affect the identification of the software as open-source.  It really annoys me when journalists just don't get it and claim that just because Java is a "standard" that can be implemented by different vendors it is in any way more open-source than .NET.

Updated: I was pointed to the Open-Source Java Project which is the process by which Sun has announced that it will release its implementation source/details to the community.  At it points out the role of the JCP will not change.  I guess this shows my first point up as being a little inaccurate.  I still hold by my second (and IMHO more important) point which is that you can write open-source software on any technology.  And further I don't believe that by choosing an open-source technology on which your commercial application is necessarily a sound business decision.

.NET Compact Framework v1 revisited

It's always amazing what you find when you trawl through your unread emails.  Normally I'm pretty good at reading and processing those emails that need immediate attention, which is why this email got passed over until now (only a week or so old).  The innovative team over at Red FIVE Labs have ported a version of the .NET Compact Framework v1 to the Symbian OS.  How cool is that! You can now run your applications, apparently "without change".  Although there are a number of conditions that are layed out in the FAQ - such as in v1 they are really only targeting smartphone style devices and there is no support for SQL Server CE (since this is clearly a native win mobile application)

Perth .NET Community of Practice - meeting this thursday

As Brian points out Code Camp Oz is just around the corner but if you can't make it to Wagga Wagga to see my session on the Microsoft Sync Services then head along to the Perth .NET Community of Practice meeting this thursday.  Details as follows: 

Details are

Date:         Thursday 1st March 2007
Time:         5:30 PM
Topic:        Building applications you can take on the road - A guide to Microsoft Synchronisation Technologies
Location:   Excom Education - Level 2, 23 Barrack St, Perth
Cost:          FREE
Presenter:  Nick Randolph (which would be me!)

Hidden amongst the mass of recent technology is an underlying trend away from traditional web or windows forms applications. In a world where most of us carry a mobile phone and enterprises that are looking to mobilise their work force there is an increasing number of applications that are built to be occasionally connected. Microsoft have a number of synchronisation technologies that form the basis of any application that is to be network aware - in otherwords, applications that don't care whether they are connected or disconnected from the server.  In this session we cover three of these technologies: RDA, Merge replication and the latest, the Microsoft Sync Services.  We will also cover the recently released SQL Server Compact Edition which can now be used to build both mobile and desktop applications alike.

Support for VB.NET still sux

Following a post I noticed regarding the new version of Reflector I decided to see whether support for VB.NET had been improved.  Well the sad news it that it might well have been improved but the first thing I tried - disassembling a custom event failed badly.  Instead of giving something similar to:

Public Custom Event MyEvent As EventHandler(Of EventArgs)
 
AddHandler(ByVal value As EventHandler(Of EventArgs))
  End AddHandler
  RemoveHandler(ByVal value As EventHandler(Of EventArgs))
  End RemoveHandler
  RaiseEvent(ByVal sender As Object, ByVal e As System.EventArgs)
  End RaiseEvent
End Event

Reflector gives:

Public Event MyEvent As EventHandler(Of EventArgs)
 
AddHandler(ByVal value As EventHandler(Of EventArgs))
  End AddHandler
  RemoveEvent(ByVal value As EventHandler(Of EventArgs))
  End RemoveEvent
End Event

When is someone going to build a good disassembler for VB.NET?  In the meantime grab Reflector if you aren't already using it cause all in all it is a brilliant tool and gives you an opportunity to explore the way that other developers write code!

.NET User Group Caffeine Hit

Sorry about the late post about this, but tomorrow will be the first gathering of the Perth Caffeine Addicts - only kidding (well except for the Perth and the Caffeine bits).  One of the best things I did when I was in NZ was attend Mauricio's Geekzone weekly coffee group and I thought the concept could work well here in Perth.  So tomorrow, with support from Mitch and Alastair of the Perth .NET Community of Practice, we are inviting anyone who has an interest in developer technologies to join us for an informal chat at Tiger Tiger which is located here in the heart of the Perth CBD (opposite Star Surf Shop) from 1:30pm tomorrow.

Although this event is put together by the co-ordinators of the .NET user group I would like to take this opportunity to invite anyone who is doing application (be it web, smart client or otherwise) development here in Perth using any piece of technology to join us and talk shop.  We will be meeting each week, same time, same place, so if you can't make it this week, why not join us next week. 

If you want to attend you have a couple of options - you could just turn up or, if you want a reminder each week, you can email me here and I will send you a calendar invite. 

If you aren't doing anything better (and no, work doesn't count) tomorrow around 1:30pm it would be great to see you!

.NET v2 Configuration Sections

Anyone who has written a custom configuration section handler for .NET v1 will appreciate the headaches and the painful process of parsing an xml block.  Well .NET v2 has a much better model for building custom configuration sections.  In this post I will walk you through the basics:

Getting Started: You need to make sure that your application has a reference to System.Configuration.  While by default there is a System.Configuration namespace it is quite limited and doesn't include the classes you need to build your own custom sections.

We will start with a simple scenario and build it up.  In this case the scenario is that you want to store information about a Person in the configuration file.  Initially you only need to track a single person and you are only really interested in their name.  The easiest way to do this would of course just to add an entry to the appSettings section of the configuration file (alternatively you could use the Application Settings area using the UI designer in Visual Studio 2005 - but we will leave this discussion for another time when we look at application settings):

<appSettings>
   <
add key="Person" value="Fred"/>
</
appSettings>

While this serves the purpose it might mean that this setting gets mixed up with the other settings you might have defined for your application.  It also means that in code you have to do a by-name lookup for that value:

MsgBox(ConfigurationManager.AppSettings("Person"))

This is where we can define our custom configuration section.  The first thing you need to do is define what the custom section is going to be called and the name of the .NET type that is going to be used to access the section information.  This is done with an entry into the configSections area of the configuration file:

<configSections>
   <
section name="CustomConfig" type="ConfigurationSample.MySection,ConfigurationSample"/>
</
configSections>

In this case the name of the configuration section in the configuration file will be CustomConfig and this will be loaded using the class MySection in the ConfigurationSample namespace.  This class is located in the ConfigurationSample assembly.  The next thing to do is to create the custom section in the configuration file.  Initially the entry will just be an entry section:

<CustomConfig/>

Now that we have set up the configuration file we need to create the MySection class that will be used to load this information at runtime.  Again initially this class will be very basic as there is no information to load:

Public Class MySection
   Inherits ConfigurationSection
End Class

To access this section in code you simply use the ConfigurationManager (as will the appSettings information) but this time you use the GetSection method to retrieve the MySection object:

Dim sect As MySection = TryCast(System.Configuration.ConfigurationManager.GetSection("CustomConfig"), MySection)

Now that we have the basics it is time to go back and gradually add information to the custom section.  We will start with including a Name attribute in the section itself:

<CustomConfig Name="Fred" />

In the MySection class you simply define a property through which you can access this information:

Public Class MySection
  
Inherits ConfigurationSection
   <ConfigurationProperty("Name", IsRequired:=True)> _
  
Public Property Name() As String
     
Get
        
Return TryCast(Me("Name"), String)
     
End Get
     
Set(ByVal value As String)
        
Me("Name") = value
     
End Set
  
End Property
End Class

Accessing this in code is as simple as making a call to the Name property of the MySection object:

Dim sect As MySection = TryCast(System.Configuration.ConfigurationManager.GetSection("CustomConfig"), MySection)
MsgBox(sect.Name)

Clearly this doesn't read particularly well as it isn't really the Name of the section you are after.  What would be good is to be able to access sect.Person.Name.  This can be done using a class that inherits from ConfigurationElement.  The configuration file would be:

<CustomConfig>
   <
Person Name="Fred"/>
</CustomConfig>

And the MySection class now looks like:

Public Class MySection
  
Inherits ConfigurationSection
  
<ConfigurationProperty("Person")> _
  
Public Property Person() As Person
     
Get
        
Return TryCast(Me("Person"), Person)
     
End Get
     
Set(ByVal value As Person)
        
Me("Person") = value
     
End Set
  
End Property
End Class

Public Class Person
  
Inherits ConfigurationElement
   <ConfigurationProperty("Name", IsRequired:=True)> _
  
Public Property Name() As String
     
Get
        
Return TryCast(Me("Name"), String)
     
End Get
     
Set(ByVal value As String)
        
Me("Name") = value
     
End Set
  
End Property
End Class

And of course the code to access this information is now:

Dim sect As MySection = TryCast(System.Configuration.ConfigurationManager.GetSection("CustomConfig"), MySection)
MsgBox(sect.Person.Name)
 

But what happens if we want to store multiple people in this section.  Well there is a built in solution - all we need to do is inherit from the ConfigurationElementCollection.  This would give us a configuration section as follows:

<CustomConfig>
  
<People>
      <
add Name="Joe"/>
   </
People>
</
CustomConfig>

And the MySection now looks like (I haven't included the Person class again as it is the same as before):

Public Class MySection
  
Inherits ConfigurationSection
  
<ConfigurationProperty("People")> _
  
Public ReadOnly Property People() As PersonCollection
     
Get
        
Return TryCast(Me("People"), PersonCollection)
     
End Get
   End Property
End Class

Public Class PersonCollection
  
Inherits ConfigurationElementCollection
   Protected Overloads Overrides Function CreateNewElement() As ConfigurationElement
      Return New Person
   End Function
   Protected Overrides Function GetElementKey(ByVal element As ConfigurationElement) As Object 
      Return TryCast(element, Person).Name
   End Function
End
Class

Now the access code would be:

Dim sect As MySection = TryCast(System.Configuration.ConfigurationManager.GetSection("CustomConfig"), MySection)
For Each p As Person In sect.People
   MsgBox(p.Name)

Next

I hope that gives you an overview of how you can build your own custom configuration sections.  Of course your custom section is likely to be much more complex and make further use of the built in configuration support.  If you are interested in using this on the mobile device you will have to look to the Mobile Client Software Factory for a configuration implementation as the .NET Compact Framework doesn't have configuration support.

If you want more information on building custom sections, take a look at Professional Visual Studio 2005

SQL Server CE as ASP.NET Database

Champion of occasionally connected (aka smart client) data, Steve Lasker, has posted on how to configure SQL Server CE to run as a database for your ASP.NET website.  Essentially it is a simple as adding the following line of code:

AppDomain.CurrentDomain.SetData("SQLServerEverywhereUnderWebHosting", true)

As Steve points out the scenario that this was originally added for was building sdf files (ie SQL Server CE database files) on the server side before being shipped out to the device.  Although merge replication is great for synchronising changes.  Unfortunately it is not particularly good for the initial download of data to the device.  I recently synchronised (from scratch) a 20Mb datafile to my K-Jam and it took over an hour (requiring continuous connectivity during this time).  The actual download of data took only a fraction of that time; it appears that a significant amount of time is taken applying the data to the database.  As such it is preferable, for the initial setup, to build this file on the server and just download it to the device.

In my previous post I have started to put together some tools for working and debugging merge replication.  Unfortunately I'm still having issues with the ClickOnce deployment of the SyncTester app.  The second app to be put together is going to be a webservice that can be used to prebuild a SQL Server CE database with specific publications.  The scenario goes a bit like this:  Your application starts up, determines that it doesn't have a database, makes a call to the webservice (passing through the details of the publications that it wants the database to be subscribed to), the webservice communicates to the server database and builds the sdf file, the webservice passes back the download location for the sdf file (or you could actually pass back the sdf from the webservice), the sdf file is downloaded and the application continues to load.  More info on this app when I get time to build it ;-)