Thursday, May 31, 2007

There are not too many things I hate in the world.  Popcorn is one (no joke) another is the feeling you get when you discover something cool in the .NET Framework or Visual Studio and think: Damn!  Why didn't I find this sooner. I call it the Last one to the party Feeling.

Today, I'm talking about the SuppressMessageAttribute class (MSDN Link).

This attribute can decorate a class where you would like explicitly exclude a module matching a rule in FxCop due to a false positive.  Really it is no different to excluding the message in the FxCop project, but I think this is better because of how visible it is. 

When you exclude a message in the FxCop project it gets sucked into a black hole and you never see them again.  What if they are just a short term exclusion, like the old fav Microsoft.Design.AvoidNamespacesWithFewTypes - which may apply at the start of a project but not once it is off the ground.  Who is going to go and un-Exclude it from the FxCop project?

Also, this attribute takes named parameters, like Justification.  Again, FxCop lets you put a note in when excluding in the FxCop project but it gets lost to all but the most determined eyes.  Having the reason for the exclusion right there in the code means it has a better chance of getting on-going attention as it may not always be as valid as it is today through circumstance or refactoring.

This attribute requires you to define a symbol - CODE_ANALYSIS.  In NAnt you can add define = "CODE_ANALYSIS" on your CSC or VBC Task and/or define the symbol in your Project properties, depending on how you build:

Thursday, May 31, 2007 6:04:38 PM (AUS Eastern Standard Time, UTC+10:00)  #    Disclaimer  |  Comments [0]  | 
 Tuesday, May 29, 2007

I've just got a couple of lessons from the last week to share around developing Office 2003 (and specifically Visio 2003) Add-Ins

I'm also trying to saturate this post with links because I have come up with a good size folder in my bookmarks for what started out to be a simple task.

  • Grab the PIA'sAnyone who wants to run the Add-In will need them.  Alternatively they can be installed from the Office Add/Remove/Repair under the guise of .NET Programmability Support, but in reality the user may not have the media or security access to do this.  Do NOT however ship the PIA's in your bits.  Ship the PIA's with your bits:  This means 2x MSI's.
  • Using NAant to automate the build with csc.exe & vbc.exe is suboptimal.  I'm keeping my project to one small assembly that depends on the PIAs, and also depends on another assembly that does the heavy lifting but has no ref to the PIA's.
  • Strong Name everything.  Well, strong name everything anyway, but when trying to pass of managed code as COM it is essential.
  • You cannot load a .NET DLL, even one with the ComVisibleAttribute on the Assembly or Classes, via the Office UI.  You just can't.  KB316723 gives an explanation.  This is because Office will try and register it the old regsvr32 way, which of course won't work.  To get a .NET DLL into the Macros -> Add-Ins list, you must write the registry entry under: HKEY_CURRENT_USER\Software\Microsoft\<office program name>\Addins\
  • This brings me to my next point.  KB316723 hints at it, but your setup must write a HKCU key not a HKLM key.  The Shared Add-In Wizard in Studio is ambiguous when it shows you this choice:

  • I know this may be contentious, but consider using VB.NET over C#.  This depends of course, but some parts of the Office object model make heavy use of Optional Parameters which C# does not support.  It has been noted elsewhere what Type.Missing can do for readability.  Having said that, it does vary greatly depending on where in the Office Object Model you are.
  • Spend some time with the Setup project that the Shared Add-In Wizard makes and test it.  Once you like it, reverse engineer it to a WiX script and feed that to your automated build.  For the record, you do that with:

Dark.exe –x path Debug/msi My.wxs
Candle My.wxs
Light My.Wixobj

  • To extra points when dealing with WiX-ified MSI's
    1. It's useful to note that the extracted (-x) resources take many forms.  DefBannerBitmap.ibd for example is just a bitmap.  I think it is easier to rename it to .bmp & tweak it in Photoshop than to add a new banner in Visual Studio.
    2. The Add-in reg setting mentioned in point #4 above references an assembly version.  Visual Studio tweeks this for you but your WiX script will be frozen at the time your Dark.exe'd it.  So don't auto-increment your assembly version numbers, or tweak you WiX script.  The choice is yours but your MSI must write the version of the Add-In DLL to the target machine's registry.

Listening To: Leftfield, Leftism

Tuesday, May 29, 2007 12:53:56 PM (AUS Eastern Standard Time, UTC+10:00)  #    Disclaimer  |  Comments [0]  | 
 Monday, May 21, 2007

I think it is fair to say CruiseControl.NET has become synonymous with Continuous Integration in the .NET space.  In the recent DNR on CI* with Eric Sink and Martin Woodward it was the defacto choice for the discussion and with good reason.  CCNet is a great tool.

I just wanted to give a quick shout-out to Draco.NET which is also a CI server for .NET and while not having the broad featureset of CCNet I recommend it for smaller shops getting their first Continuous/Automated build together.  My two reasons are:

  • Supports Visual Source Safe, which like it or not is the Gateway Drug for source code control.  (To hear what I think of that go grab DNR #221 about 5min16sec in ;)  It also supports PVCS, Subversion and Vault.
  • It is so much easier to configure.  You have no options for reporting or postbuild steps, or overriding the build ID or RSS add-ons for.  CCNetConfig is essential for configuring CruiseControl.NET.  Draco.NET offers a pit of success for the folks new to CI.

The most compelling reason for CCNet over Draco.NET is Everyone else is using CCNet :-)

On the topic of DNR show #238 - Eric talks about Vault, but doesn't mention that you don't need to purchase a license when used for a single developer.  It is licensed by named accounts, so go get it and give it a go all you VSS folks!

*the best bit of the show is 11min45sec in... ;-)

Listening To: Ani Difranco - Revelling and Reckoning

Monday, May 21, 2007 8:06:12 PM (AUS Eastern Standard Time, UTC+10:00)  #    Disclaimer  |  Comments [2]  | 
 Tuesday, May 08, 2007

I was looking today at options for finishing a build with something other than an MSI or folder full of files:  An ISO file.

I am a fan of DaemonTools and associated add-ons.  Even if you're not planning to burn to disc, an ISO file can be a useful way of getting a bunch of files around the place.

First step was to grab a Windows binary of mkisofs from one of the various sources of cdrtools on the webNB:  It comes linked with Cygwin binaries.

This is a util that has its roots in the Linux/Unix world, so be prepared to scratch your head a bit if you are not familiar with the world of Linux/Unix command line tools.  Also if you are, don't be fooled by mkisofs following the naming convention of the other mk*fs tools.  It is really quite different.

In the *nix world, the online help is by the man ("manual") page system.  Basically, at your prompt you type man mkisofs for help with mkisofs.   This works in Google too!  The man page will be a useful reference, as will the less informative usage info you can get from mkisofs.exe -help

Having said all that, the following options are a really good place to start: 

Option Note
-J Enable Joilet (you want this)
-R Enable Rock Ridge (you want this)
-V diskname Set a volume label
-o filename.iso Set the output ISO file name
-graft-points allows "=" syntax in pathspec.  More on this below...
-m "*.tmp" Exclude files from the image by pattern

mkisofs takes paths to add to the ISO file as parameters, and by default all these are stacked under the root of the disk image.  If this is not what you want then you should enable graft points.  This option will allow you to make folders in your ISO image for each of the folders you are adding to the disk.

For example, the following pathspec will create two folders on the CD, one called Windows for the contents of the bin folder, and one called Documentation for the contents of the doco folder:

Windows=D:\build\windows\bin\ Documentation=D:\build\doco\

So the complete command line for mkisofs will be something like:

"C:\Program Files\cdrtools-latest\mkisofs.exe" -J -R -graft-points -quiet -o f:\backup.iso -V backup -m "*.tmp" Windows=D:\build\windows\bin\ Documentation=D:\build\doco\

For extra points, you can automatically burn the ISO to a disk using the cdburn / dvdburn tool that ships with the Windows Server 2003 Resource Kit Tools.

A couple of reasons I'll suggest using this over using cdrecord.exe that comes with the cdrtools package:

  • The cygwin-based tools don't work as well with later Win32 like Windows Server 2003, they seem to not deal with the tighter security well.
  • The syntax of cdburn/dvdburn is much much easier!

An example of the syntax to burn f:\backup.iso to the blank disc in the burner g:\ is:

C:\Program Files\Windows Resource Kits\Tools>cdburn.exe g: f:\backup.iso -speed max

Also note that the cdburn will eject the disk once it has been burnt!  Keep that in mind if your CD drive is normally behind a door or cage or something!

UPDATE:  This technique is also has some utility for backup-to-disk scenarios.  For example a backup batch file that made an ISO then burnt it to disk.

Listening to: Bend to Squares by Death Cab for Cutie

Tuesday, May 08, 2007 2:53:13 PM (AUS Eastern Standard Time, UTC+10:00)  #    Disclaimer  |  Comments [2]  | 
 Monday, February 26, 2007

This one came up in discussion last week and could be worth mentioning.

Consider the following property:

private List<SchemaAttribute> _attributes = new List<SchemaAttribute>();
public List<SchemaAttribute> Attributes
{
   get
   {
      return _attributes;
   }
   set
   {
      _attributes = value;
   }
}

NCover/NCoverExplorer reliably inform me that this property has only 50% coverage
in my tests.

By hereto unexplored forces of nature, every consumer of this class calls
.Attributes.Add()

or, itterates over it as so:
foreach (SchemaAttribute element in instance.Attributes)
{
   // ...
}

The keen eye will notice that neither of these ways to access the property actually hit the setter! 

Two possible paths present themselves:

  1. Write a test that just exercises the setter.  This seems to me pointless. 
    If we are to consider that our tests can serve to express our intention
    in a repeatable fashion, what is our intent?  To see if a Generic List still works?
  2. Consider makeing the property read-only.  Including braces I could own three lines less code.  Yay!
    And also now I have had cause to think about it, it's not my intention that the
    List be set as a list, for this class it just dosen't make sense right now.

Next step?  Consult Francesco & Giuseppe!

Sleep.  The best 10 hours of the week.

Listening to:  Nick Cave and the Bad Seeds - Abattoir Blues

Monday, February 26, 2007 1:02:40 PM (AUS Eastern Standard Time, UTC+10:00)  #    Disclaimer  |  Comments [0]  | 
 Monday, February 19, 2007

In my commute this morning I was listening to my weekly dose of DotNetRocks - Show 214 with guest Billy Hollis and Billy mentioned something on Agile to illustrate a point, and it has stuck with me all day.

He was referring to a presentation he attended where an advocate said he was writing 2 or 3 lines of unit test code for each line of production code.  Billy's objection to this is hardly a challenge to intuition: Are we getting 4x the value for 4x the code?

One of my metrics for the unit tests that I write is that they don't hurt.  Some can be a couple of lines long, some can be heavily copied-n-paste'd.  Customizing a CodeRush template is time well spent.  There are no wrong answers, however you get them in there is really OK.

It makes sense:  You're writing a unit test.  The aim is to isolate a gizmo of your choosing in your code and exercise it.  The cumulative weight of the unit tests should really function as an expression of your intent for the gizmo.  I outlined what I think of the high importance of naming your tests in a prior post.

Monday, February 19, 2007 3:48:15 PM (AUS Eastern Standard Time, UTC+10:00)  #    Disclaimer  |  Comments [0]  | 
 Wednesday, February 07, 2007

with apologies and thanks to Sir Winston for giving me the courage to continue on with WiX :-)

The two links that make my WiX world turn are:

Wednesday, February 07, 2007 5:11:45 PM (AUS Eastern Standard Time, UTC+10:00)  #    Disclaimer  |  Comments [0]  | 
 Monday, February 05, 2007

An easy one, but anyway... When building a target in NAnt that depends on a Web Service, the only change to your <vbc> or <csc> task is to make sure your sources include the Reference file that Visual Studio generated when you added/updated the Web Reference, as so:

<sources>
    <include name="MyProject\*.vb"/>
    <include name="MyProject\Web References\RemoteInterfaceWS\Reference.vb"/>
</sources>

I was also pleased to note that in cases where the wsdl imports a typed dataset (ie the remote Web Method takes or returns a typed dataset), Reference.[vb|cs] includes the dataset definition.  No need to add a step to execute xsd.exe!

Monday, February 05, 2007 3:11:53 PM (AUS Eastern Standard Time, UTC+10:00)  #    Disclaimer  |  Comments [0]  | 
 Friday, February 02, 2007

Got Build?

(sprint pending ;)

Friday, February 02, 2007 7:22:44 AM (AUS Eastern Standard Time, UTC+10:00)  #    Disclaimer  |  Comments [0]  | 
 Friday, November 24, 2006

This was meant as a "Part II" to my prior post on generating Text, HTML & more XML with XSLT.  The point for today's post is that source code files are text files.  The example I am thinking of is generating a library of VB.NET wrapper classes for the stored procedures in a SQL Server database.

(I've also ticked the Continuous Integration category for this post.  It wouldn't be hard to think of a scenario where a build process would generate a library from a reference database on the check-in of a stored proc script, then deliver the latest rev of the library to the developers, anyway...)

Step one would be fetch the meta data about the stored procedures, for example: 

SELECT procs.Specific_Name, params.Parameter_Name, params.Data_Type, params.Parameter_Mode
FROM
INFORMATION_SCHEMA.ROUTINES procs
LEFT
JOIN INFORMATION_SCHEMA.PARAMETERS params
ON params.Specific_Name = procs.Specific_Name
WHERE
procs.Routine_Type = 'PROCEDURE' AND
procs
.Specific_Name NOT LIKE 'dt_%'
FOR
XML AUTO

Once we add a document node to this, we will have a document that contains many element sets like this one:

  <procs Specific_Name="GetContactByID">
    <params Parameter_Name="@ContactID" Data_Type="nvarchar" Parameter_Mode="IN"/>
    <params Parameter_Name="@ContactGUID" Data_Type="int" Parameter_Mode="INOUT"/>
    <params Parameter_Name="@Found" Data_Type="bit" Parameter_Mode="INOUT"/>
  </procs>

I think that's all we need to get started.

Step two is to transform this data into VB.NET code.  For today's example it suits me to generate two files: 

  1. One will contain classes that wrap ADO.NET calls to the database
  2. The other will provide types that wrap properties for passing into and out of the first

The text of the first template is as follows

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="
http://www.w3.org/1999/XSL/Transform" version="2.0">
  <xsl:output method="text" indent="yes" />
 
  <xsl:template match="/">

Imports System
Imports System.Data.SqlClient
Imports System.Data
Public Class DatabaseAccess
    Inherits ConvienientBaseClass
    Public Sub New(ByVal cn As SqlConnection, ByVal trn As SqlTransaction)
        MyBase.New(cn, trn)
    End Sub
   
    <xsl:apply-templates select="/database/procs" />
    
End Class
  </xsl:template>
 
  <xsl:template match="procs">
    '
    ' Wraps stored proc: <xsl:value-of select="@Specific_Name" />
    '
    Public Function Execute<xsl:value-of select="@Specific_Name" />(ByVal params As <xsl:value-of select="@Specific_Name" />Struct) _
                                             As <xsl:value-of select="@Specific_Name" />Struct
        Dim exec As New SqlCommand
        Dim param As SqlParameter
        With exec
            .CommandText =
"<xsl:value-of select="@Specific_Name" />"
            .CommandType = CommandType.StoredProcedure
            .Connection = MyBase.DatabaseConnection
            .Transaction = MyBase.CurrentTransaction
        End With
  <xsl:apply-templates select="params" /> 
        Try
            If Not exec.Connection.State = ConnectionState.Open Then exec.Connection.Open()
            exec.ExecuteNonQuery()
        Catch ex As Exception
            Throw
        Finally
            If Not exec Is Nothing Then exec.Dispose()
        End Try
    End Function
  </xsl:template>
 
 
  <xsl:template match="params">
        param = exec.CreateParameter
        With param
            <xsl:if test="@Parameter_Mode='INOUT'">.Direction = ParameterDirection.Output</xsl:if>
            <xsl:if test="@Parameter_Mode='IN'">.Direction = ParameterDirection.Input</xsl:if> 
            .DbType = DbType.<xsl:value-of select="@Data_Type" />
            .Value = params.<xsl:value-of select="@Parameter_Name" />
            .ParameterName =
"<xsl:value-of select="@Parameter_Name" />"
        End With
        exec.Parameters.Add(param)
 
</xsl:template>
 
</xsl:stylesheet>

And the text of the second template is as follows:

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="
http://www.w3.org/1999/XSL/Transform" version="2.0">
  <xsl:output method="text" indent="yes" />
 
  <xsl:template match="/">

Imports System
    <xsl:apply-templates select="/database/procs" /> 
  </xsl:template>

 
  <xsl:template match="procs">
'
' Parameters for method: Execute<xsl:value-of select="@Specific_Name" />
'
Public Class <xsl:value-of select="@Specific_Name" />Struct
   <xsl:apply-templates select="params" />  
End Class 
  </xsl:template>
 
  <xsl:template match="params">
   Private _<xsl:value-of select="substring(@Parameter_Name,2,string-length(@Parameter_Name)-1)" /> As Date
 Public Property <xsl:value-of select="substring(@Parameter_Name,2,string-length(@Parameter_Name)-1)" />() _
                                                                     As  <xsl:value-of select="@Data_Type" />
    Get
      Return _<xsl:value-of select="substring(@Parameter_Name,2,string-length(@Parameter_Name)-1)" />
    End Get
    Set(ByVal Value As <xsl:value-of select="@Data_Type" />)
      _<xsl:value-of select="substring(@Parameter_Name,2,string-length(@Parameter_Name)-1)" /> = Value
    End Set
   End Property
 
</xsl:template>
 
</xsl:stylesheet>

To my eye, these look more like VB.NET source files than XSLT templates.  That's because they started life as .vb files.  Then I renamed them .xslt and started inserting the XSLT tags in places where I needed substitution from the XML source. 

To emphasise the hybrid-ness (is that a word) of these files, I have highlighted the VB.NET parts blue and the XSLT parts green, rather than keeping the VB.NET syntax highlighting.

Some breif thoughts: 

  • The value of this to my mind is in not having to hand code *every* one.  You hand code one, then generate the rest - in theory this reduces the opertunity for bugs which should be the focus of the exercise. 
  • Maybe this may find a home in a long-running project to have this as part of the build process, or maybe as part of some tooling focused on small one-off
  • This are commercial products that do code gen based on XSLT.  I haven't used them, but they may well be better than my home-brew sample :-)
  • Maybe useful for trainers, or producting samples for demos etc.  I'm thinking now about times where there may be a need to generate side-by-side VB.Net, C# & Java sample code for example.
  • Also include comment blocks that are readable by NDoc!

[edit: added line breaks for formatting.]

Friday, November 24, 2006 9:58:13 AM (AUS Eastern Standard Time, UTC+10:00)  #    Disclaimer  |  Comments [0]  | 
 Wednesday, September 13, 2006
I thought I'd post an update from my path to continuous integration nirvana...

Today's installment is things I have learnt about writing unit tests.  Specifically I'm all about .Net and NUnit, but these are probabbly applicable in other scenarios too.

Name your unit tests correctly

What I mean to say is, name your tests as a verbose description of what the purpose of your test is. 

A good example:

<test()> _
Public Sub FooCanGenerateValidIDWhenInputValueIsNegative()

A bad example:

<test()> _
Public Sub FooSaveMethodWorks()

Can someone who dosen't code on your project (or better still, a non-coder) understand what the designed behaviour is for the Foo class from your NUnit results? 

But the most important reason is these tests must be granular and focused.  If you can't tell me what you are testing by the name of the test it is probabbly time to step back and look at the code you are testing.

Bug fixes should have a unit test

This is in two flavours:  Forwards and Backwards.

When I fix a bug, how do I know it is fixed?  How can I prove it is fixed?  Good bug reports are focused & granular.  Add steps to reproduce and now you are talking about a good bug report. 

It is also no mistake that the words focused and granular words are in this lesson too. 

Forwards:
By the time the tests are done they should describe the desired end result of the bug report.  Again there is no need to go all TDD unless you want to, but if the bug report is in the form:

An unhandled exception is thrown under some specified bad input data

then your test should show that no exception is thrown with taht bad input data.  Instant proof that the bug was fixed!

Backwards:
Looking at a closed bug report, how do I know what was done to fix the bug?
Looking at a broken build report because some unit tests failed, how do I know what bugs that code relates to so I can retest them?

The purpose of this lesson is to remove well it worked on my PC from the developers vocabulary.

Writing unit tests is a mind-space thing

While not going as far as TDD in my current projects (caution: there are TDD fanatics out there :-) the lesson I learnt from the TDD thing is when you are writing your tests you need to put yourself in the mindspace of the client of your code.  Forget for a minute how you implemented the method and express what you aimed to do in the method with your tests.

Confession alert:  At first I thought this was a bunch of bovine compost when I read it in the Agile/unit testing/TDD echo chamber.  Then, one day, when I wasn't paying much attention, I found a bug in my code through this method as I was writing it.  Clouds parted, a little beam of sun light came down and touched my head.  All became clear.  Lay your hands on the radio, children; for we have a new believer.

Tests should be easy to write

When writing heaps of tests agains the same class or library or whatever, write a base class that does the setup etc and descend your test class from this base class as a way of making the test method only contain as little code that is not the test as possible.  This can make it easier to bang out plenty of tests. 

Or if you want to use Code Rush or Snippites in VS2k5? 
Or if you want to do absolutely anything else to make it easier to bang out unit tests?
...just do it.  There is no wrong answer.

There is no need to make this harder on yourself than it has to be! :-)

Wednesday, September 13, 2006 8:29:01 PM (AUS Eastern Standard Time, UTC+10:00)  #    Disclaimer  |  Comments [0]  | 
 Tuesday, August 15, 2006
So I've been battling against using the Solution task in NAnt to automate the build of a large VB.Net solution that includes heaps of libraries and a web service and all sorts :-)

I was hoping to have it done like this:

    <solution configuration="Debug"
              solutionfile="LargeProject.sln" >
      <webmap>
        <map url="http://localhost/Project/ProjectWebService/ProjectWS.vbproj"
             path="C:\Inetpub\wwwroot\Project\ProjectWebService\ProjectWS.vbproj"/>
      </webmap>
    </solution>


...but was getting lots of errors like:
error BC30002: Type 'Xml.XmlDocument' is not defined.

It turns out the source of this is all the odds and ends that VB.Net automatically includes in your project - I was only vaguely aware of them, and it seems like there is no option on the Solution task for it.

After some googling and general messing around, I added an Exec task to the build as thus:

     <exec program="C:\Program Files\Microsoft Visual Studio .NET 2003\Common7\IDE\devenv.exe">
           <arg line="EPOnline2.0.sln /build Debug"/>
     </exec>


The down side is there is no nice output from devenv.exe like you get from the Solution & VBC tasks, but my build succeeds and that makes me happy :-)

After blog mint [?]:  I didn't read the devenv.exe /? help close enough!  If you include /Out at the end of the command line (i.e. after /build Debug in the above example) you do get the pretty output.
Tuesday, August 15, 2006 7:23:47 PM (AUS Eastern Standard Time, UTC+10:00)  #    Disclaimer  |  Comments [0]  | 

This is more along the lines of the CI threads that have been occupying my thoughts of late.

I'm really impressed at the kind of technical documentation I can get from NDoc + the VBCommenter power toy, even more when it is generated and copied to my fileserver nightly as part of an NAnt script!

The next project for me on the NDoc front is to coax is to produce user documentation (rather than technical documentation) from the same sources with no extra work from me :-)

Has anyone done this before?  Is it another case of when you are holding a hammer everything looks like a nail?

Tuesday, August 15, 2006 11:24:27 AM (AUS Eastern Standard Time, UTC+10:00)  #    Disclaimer  |  Comments [0]  | 
 Wednesday, August 02, 2006
There's not much to tell since my last (vague, sleep deprived, rambling) post on continuous integartion as a development technique in .NET...

But what I have found useful is using Draco and NAnt on a VB6 project!

The problem I was looking to solve is reporting in Microsoft Visual Source Safe.  Draco.NET supports VSS, so I made an NAnt build script with one target containing no tasks and I have Draco build it every night. 

The plus is Draco includes in its post-build email the details of what checkins have happened since the last build and by who... Instant daily check-in report emailed to your door :-)

Wednesday, August 02, 2006 1:15:33 PM (AUS Eastern Standard Time, UTC+10:00)  #    Disclaimer  |  Comments [0]  | 
 Friday, June 16, 2006

A week since my last blog post!  Here's a quick summary.

  • My head has been spinning at work.  Hit a busy period and I can't seem to work fast enough.
  • Sydney is starting to get C-O-L-D cold!
  • Gates is leaving Microsoft (later rather than sooner), Scoble is leaving Microsoft (I've been the web site for half an hour and I still don't know PodTech do)... would the last one to leave Redmond please turn out the lights? :)
  • The continuous integration thing is moving along.  Draco.Net, NAnt and NUnit all rock. 
    • Here's the trick for testing database code:  have your test setup put a transaction on the wire and have your test cleanup roll back the transaction.
    • I know I have only read the doc 8 times this week, but I think I'm starting to understand the DI pattern.
  • Microsoft renamed InfoCard to now be CardSpace.  WTF?  Still no cards?  Infocard is still a good idea - identity management is still very important but please guys drop the "cards" thing.  Not everyone follows WinFX developments up to the minute and you're starting to confuse people.  And I still don't have a satisfactory answer as to why we are doing this over protocols like HTTP and SMTP.  Why not another rev of these protocols to natively include identity, encryption and authentication, and then build identity management frameworks on top of them?
  • Neofiles has been doing my head in with talk of transhumanist singularities, cognitive liberty, liberation biology and nano-biotech.  For some reason I put my strongly skeptical BS-Filter on hold for this show and I am starting to think about these things.  I'm definately not sold on some of these topics.  Maybe I'm just short on sleep.

Friday, June 16, 2006 5:29:24 PM (AUS Eastern Standard Time, UTC+10:00)  #    Disclaimer  |  Comments [0]  |