Sponsors

The Lounge

Wicked Cool Jobs

Current Bloggers

Partners

 

Wikis

  • You have not yet contributed to any pages.

Avoiding Prescriptive Requirements

Posted by Jak Charlton, Thursday, February 09, 2012 (674 views)

 

Core Requirements

Requirements should be given as the Core Requirement, and avoid the common pitfall of providing Prescriptive Requirements

As an example, a core requirement in an insurance system may be:

As a user of the Broker system, I want to create a Settlement Batch of Eligible Documents across Insurance Policies

This is eminently testable, is clear and unambiguous, and has real business value, and it meets the general INVEST principle of good user stories (which is also a good maxim for any form of requirements):

 

  • It is Independent of other stories
  • It is easily Negotiated as to priority and value
  • It has real business Value
  • It is small enough to easily Estimate with some degree of certainty
  • It is of an appropriate Size for easy estimation, planning and prioritisation
  • It is able to be Tested both manually and in an automated fashion with clear and unambiguous pass or fail criteria, you can either do it or not

 

The stated requirement is not prescriptive, it does not specify how the user triggers this action, what data they need to provide, how they select the documents, nor does it specify what a "user of the Broker System" is within this context, nor what a Settlement Batch is, nor what an Eligible Document is. This means the requirement can be documented very early on, with little analysis work needed, allowing very quick comparison with other requirements, and very quick verification from the business as to the validity of the story.

Later this placeholder can be expanded in discussions between the technical teams and the business to include the actual definitions and scenarios that define its acceptance criteria:

 

  • The user must have the “Batch Creation” permission
  • Eligible Documents are those which are awaiting Settlement
  • A Settlement Batch is a group of Documents that will be dealt with together by the Claims Settlement system, so as to save managing on an individual policy level

 

This would lead to a requirement with maybe a dozen test scenarios giving all the variations of user and statuses that would allow or not allow the story to pass the test. All of these stories and scenarios are now easily tested with automated and repeatable testing.

At this point it would probably be obvious where within the UI this functionality should surface, and the design of the UI interaction can be worked out. This UI work is actually a very specific development skill within its own right - there is significant complexity in designing UI interactions that mirror both the technical system and the user’s mental model.

Through all of these steps, the original core requirement has not been changed, though its implementation and business logic may have evolved, changed and adapted to line up with other functionality.

Good requirements are merely a placeholder for a later conversation. Their level of completeness or accuracy only dictates your certainty in implementing them accurately and efficiently, but does not preclude moving forwards, and does not hold development up waiting on “complete requirements”.

As granularity increases, so does complexity required to understand, verify and implement, but oddly so does instability. By starting with core stories, you maintain a fairly stable set of requirements, and only deal with complexity when you need to, and suffer the instability only on individual scenarios.

Which brings us neatly to development

It is fairly well established now that development must be iterative within short cycles to increase its chance of being successful. Early feedback and revision saves massive amounts of time and effort correcting incorrect assumptions and poor translation.

The sooner a story enters development, the sooner a basic version of it can be demonstrated to business users, to verify against their assumptions, the faster it can be revised and the more accurately it will reflect the actual requirements. In addition it will expose underlying technical constraints and limitations earlier on.

 

Discuss (1)

Finding Out When Something Happened in Your Git Repo

Posted by Christopher Bennage, Wednesday, February 08, 2012 (292 views)

Acknowledgment: This is meant to be the Windows equivalent of Anders Janmyr’s excellent post on the subject of finding stuff with Git. Essentially, I’m translating some of Anders’ examples to Powershell and providing explanations for things that many Windows devs might not be familiar with.

This is the third in a series of posts providing a set of recipes for locating sundry and diverse thingies in a Git repository.

Determining when a file was added, deleted, modified, or renamed

You can include the --diff-filter argument with git log to find commits that include specific operations. For example:

git log --diff-filter=D # delete

git log --diff-filter=A # add

git log --diff-filter=M # modified

git log --diff-filter=R # rename

There are additional flags as well. Check the documentation. By default, git log just returns the commit id, author, date, and message. When using these filters I like to include --summary so that the list of operations in the commit are included as well.

N.B. If you run a git log command and your prompt turns into a : simply press q to exit.

I don’t think that you would ever want to return all of the operations of a specific type in the log however. Instead, you will probably want to find out when a specific file was operated on.

Let’s say that something was deleted and you need to find out when and by whom. You can pass a path to git log, though you’ll need to preced it with -- and a space to disambiguate it from other arguments. Armed with this and following Ander’s post you would expect to be able to do this:

git log --diff-filter=D --summary -- /path/to/deleted/file

And if you aren’t using Powershell this works as expected. I tested it with Git Bash (included with msysgit) and good ol’ cmd as well. Both work as expected.

However, when you attempt this in Powershell, git complains that the path is an ambiguous arugment. I was able to, um, “work around” it by creating an empty placeholder file at the location. Fortunately, Jay Hill heard my anguish on Twitter and dug up this post from Ethan Brown. In a nutshell, Powershell strips out the --. You can force it to be recognized by wrapping the argument in double qoutes:

git log --diff-filter=D --summary "--" /path/to/deleted/file

That works!

I’m guessing that Powershell considers -- to be an empty arugment and therefore something to be ignored. I also assume that when the file actually exists at the path that git is smart enough to recognize the argument as a path. (Indeed, the official documentations says that “paths may need to be prefixed”).

While we’re here, I also want to point out that you can use wild cards in the path. Perhaps you don’t know the exact path to the file, but you know that it was named monkey.js:

git log --diff-filter=D --summary -- **/monkey.js

Happy hunting!

Comment on this post at dev.bennage.com
Discuss ()

Submit a patch

Posted by Hadi Hariri, Monday, February 06, 2012 (5,916 views)

We love to complain, and Twitter has just made is so much easier. By merely including a handle or keyword of some company or product, we can attract the attention of those we’re moaning about and have them run to try and solve our problem. The speed at which they run is proportionally direct to the number of followers we have or the ‘people we know’ (I have 10 followers but my best friend is a celebrity with 300K followers and RT’s anything I ask him to). Apparently it’s called Social Media Damage Control.

When it comes to software products, we’re quite good at it too. After all, that’s why we pay for software, to have someone to hear our roar on the other end of a phone, a forum or a twitter handle.

But that only applies to commercial software.

When it comes to OSS however, it seems different rules apply. Specially when it's free. Complaining about OSS is often viewed as ungrateful behavior. Numerous times I’ve seen reactions from OSS developers, contributors or merely a simple passer by, responding to a complaint with: submit a patch or well if you can do better, write your own framework. In other words, put up or shut up.

We’re not all Einstein's

It’s not always a patch they are after. At times, when you find a bug, an OSS team member can ask you for a failing unit test. Now granted that we all strive to unit test and promote unit testing, feeling that every developer should know, understand and practice unit testing, the reality of the matter is that it’s not all green pastures out there. For one reason or another, not everyone has that knowledge, the ability or the opportunity to. So often, sending a failing unit test can seem daunting.

Of course, coming back to patches, there’s the added issue of figuring out how to work with the given source control the project is using, get the right unit testing frameworks to run, creating new unit tests, making the necessary changes, submit them and wait for your pull request to be accepted.  And that’s if the project is using a DVCS and you can figure out what Pull, Push, Clone, Fork and Checkout mean. All this doesn’t even take into account that you need to figure out how the actual code-base works. And we all know understanding other people’s code isn’t easy.

For someone that is merely using an OSS project, all this can be overwhelming, not to mention intimidating at times.

Lowering the barrier to adoption

The OSS community often complain how big “Enterprise” and “Microsoft” shops don’t buy into OSS. It seems they go for commercial software in order for their legal departments to have someone to sue in case things go wrong. A little far-fetched of course, but nonetheless something you hear often. These shops also go for commercial software because it provides them with someone to call, someone that won’t tell them to submit a patch or provide a unit test. Someone they can call when they need support and not be judged (or at least not humiliated publicly on a forum or mailing list). Of course, the somewhat sad irony of this is that often, the support provided on OSS projects outdoes commercial products by a long shot, and that’s not to mention OSS projects that offer the possibility of commercial support.

However, we need to look at ourselves and see how much of this low adoption of OSS that we’re so passionately fighting for is our fault. If we expect all the users of our projects to know how to work with our source control or compile the source and deal with dependencies, submit patches or work with our testing framework, all we’re doing is raising the entry barrier to OSS.

Before shouting that I’m stereotyping OSS projects, I’m not. I’m well aware that there are amazing projects out there with beautiful and thoughtful teams and communities around them that make many commercial support alternative envious. However, I’ve seen the submit a patch attitude often enough, over the many years I’ve been involved in OSS to warrant mentioning it.

What about me? What about my time?

Now there is the opposite side to all this. You. The Project Lead. The Core Contributor. The guy that has spent several years of his life giving to the community, contributing to OSS projects, helping others. Why should you, despite having given so much, take more of your time to help others. The minimum, that someone that is using your project (for free might you add), owes you, is a failing unit test. No? Not just some lousy steps to reproduce…

Here’s the thing. If you’re working on OSS, you’re doing it because you are benefiting from it. You benefit because you enjoy it. You benefit because you learn. You benefit because you potentially can rise to fame (albeit a micro-celebrity), and you benefit because it can ultimately provide you with potential consulting and training opportunities.

Nobody owes you anything for working on OSS!

Filed under:
Discuss (5)

PSake and building Silverlight solutions

Posted by Derik Whittaker, Saturday, February 04, 2012 (434 views)

If you are using PSake to build .net projects and your project has a silverlight project in it you may get the following error.

C:\Program Files (x86)\MSBuild\Microsoft\Silverlight\v4.0\Microsoft.Silverlight.Common.targets(104,9): error : The Silverlight 4 SDK is not installed. [C:\Development\Source\Main\Libraries\SilverlightShared\Silverlight.csproj]

When I encountered this I was not sure what to do since I was telling PSake that I was building with the ‘–framework 4.0; option.  However it appears that PSake does not look in the right path for the CORRECT MSBuild version.  The way that I found to solve this problem was to fully qualify the version of MSBuild that I wanted to use.  I did the following

C:\Windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe /verbosity:m $SolutionFileWithPath

I have spoken with James (the author of PSake and he thinks he can have a fix for this) but just incase he does not get it or you have this problem now at least you know how to solve it.

Till next time,

Filed under: ,
Discuss (0)

From 0 to doing solution builds w/ PSake–Part 1 of N

Posted by Derik Whittaker, Saturday, February 04, 2012 (640 views)

Recently I decided I would kill two birds with one stone, I figured I would learn a bit of Powershell and setup some build scripts for our project.  I have been wanting to play around with Powershell for the longest time but could never really either find the time or the reason to play with it.  So I figured that setting up build scripts would be a perfect use of my time (I know I could have choose any other build language/framework but PSake meet my need).

In this post I will walk you though how to setup a build from scratch.  I will warn that because I am a COMPLETE NOOB with powershell it is very likely that my powershell code is less than optimal but it meets my needs.

In my script we are going to accomplish 3 things:

  1. Setup a PSake Task to perform a clean on our solution
  2. Setup a PSake Task to perform a build on our solution
  3. Setup a PSake Task to run Tests in our solution

Before you continue I would suggest you download PSake and read the Readme.markdown script because this will tell you how to setup PSake to be run via Poweshell.  Once you have read the markdown file you can continue.

Creating your shell ps1 file.

You will want to create a build file to put the following code into.  Call it build.ps1 for our purposes.

Adding the Clean Task

The raw PSake ‘Task’ for the clean. 

task Clean {
  Invoke-Clean "My Solution" "..\Subfolder\MySolution.sln"  
}

As you can see from the task above this is just a pass through call into another method called Invoke-Clean.  I have done this because over time I expect to build out multiple build scripts, one per application, and I don’t want to duplicate the code which does a clean in each script.

Here is the actual Invoke-Clean function

function Invoke-Clean
{  [CmdletBinding()]
    param(
        [Parameter(Position=0,Mandatory=1)] [string]$BuildName = $null,
        [Parameter(Position=1,Mandatory=1)] [string]$SolutionFileWithPath = $null
        )
    
    Write-Host "Running Clean for" $BuildName "on Solution @" $SolutionFileWithPath
    
    C:\Windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe /verbosity:m /t:Clean $SolutionFileWithPath
}

The code above is doing 2 things. 

  1. I an writing to the host (aka console) that I am running a clean for the given build
  2. I am directly referencing the msbuild.exe from the folder.  Now with PSake you don’t always have to do this because it just ‘knows’ where msbuild is located.  However, I am building a silverlight app and the version of msbuild that PSake was finding was wrong and this was my solution for this.

Adding the Compile Tasks

When doing a compile we are going to simply call out to MSBuild and allow it to do its thing.  Below is the PSake task for doing a compile

task Compile -depends Clean {
  
  Invoke-Build "My solution" "..\Subfolder\MySolution.sln"  
    
}

Again the task above is just wrapper call around the Invoke-Build function.  It is the Invoke-Build function which is doing all the heavy lifting.  Below is our function.

It is important to point out that our Compile task depends on the Clean task.  This means that the Clean task will be run prior to the actual compile.

function Invoke-Build
{  
    [CmdletBinding()]
    param(
        [Parameter(Position=0,Mandatory=1)] [string]$BuildName = $null,
        [Parameter(Position=1,Mandatory=1)] [string]$SolutionFileWithPath = $null
        )
    
    Write-Host "Running Build for" $BuildName "on Solution @" $SolutionFileWithPath
    
    C:\Windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe /verbosity:m $SolutionFileWithPath
}

The Invoke-Build above is also calling to a specific version of the MSBuild but this time rather than doing a clean it is doing a compile.  Of course if you want to perform more actions via MSBuild you can find the full list of command line switches on MSDN.

Adding the Test Tasks

The last task I want to build is the testing task.  Because our team is using MSTest the code below is for this.  if you are using NUnit or any other testing framework the code should be close to this but of course calling the correct runner exe.

task Test -depends Compile, Clean {
  
  Invoke-MSTest "MyTestDll.dll" "..\Subfolder\UnitTests\bin\Debug\MyUnitTests.dll" "MyUnitTests.dll.trx"     
  
}

Our Test task above is pretty simple.  We are passing in 3 values, Display name, the dll to test and because this is MSTest I am providing the name of the output file I want generated with the test results.

Below is the implementation for Invoke-MSTest.

function Invoke-MSTest
{
  [CmdletBinding()]
    param(
        [Parameter(Position=0,Mandatory=1)] [string]$TestName = $null,
        [Parameter(Position=1,Mandatory=1)] [string]$TestDll = $null,
        [Parameter(Position=2,Mandatory=1)] [string]$ResultTrx = $null
        )
        
    Write-Host "Running Tests for" $TestName "Located @" $TestDll " Output to:" $ResultTrx
    
    
    if ( Test-Path $ResultTrx )       
    {
        Write-Host "Found" $ResultTrx "it will be deleted prior to running the test"
        Remove-Item $ResultTrx
    }       
    
    $result = mstest /testcontainer:$TestDll /resultsfile:$ResultTrx
       
    foreach( $line in $result )
    {
        if ( $line -ne $null )
        {
            if ( $line.StartsWith("Passed") -ne $true )
            {
                $line
            }
        }
    }
}

Looking at the Invoke-MSTest function above you can see I am doing more than simply making a call out to MSTest. I am doing 2 specific things.

  1. I am checking to see if there is an existing output file and if there is I am deleting it
  2. I am only outputting the failure test results to the console.  This allows me to remove all the extra noise of passed tests.

As you can see from above getting up and running w/ PSake is not that hard and does not take much effort.

Till next time,

Filed under: ,
Discuss (2)

Finding Content in Files With Git

Posted by Christopher Bennage, Friday, February 03, 2012 (376 views)

Acknowledgment: This is meant to be the Windows equivalent of Anders Janmyr’s excellent post on the subject of finding stuff with Git. Essentially, I’m translating some of Anders’ examples to Powershell and providing explanations for things that many Windows devs might not be familiar with.

This is the second in a series of posts providing a set of recipes for locating sundry and diverse thingies in a Git repository.

Finding content in files

Let’s say that there are hidden monkeys inside your files and you need to find. You can search the content of files in a Git repositor by using git grep. (For all you Windows devs, grep is a kind of magical pony from Unixland whose special talent is finding things.)

# find all files whose content contains the string 'monkey'

PS:\> git grep monkey

There several arguments you can pass to grep to modify the behavior. These special arguments make the pony do different tricks.

# return the line number where the match was found

PS:\> git grep -n monkey



# return just the file names

PS:\> git grep -l monkey



# count the number of matches in each file

PS:\> git grep -c monkey

You can pass an arbitrary number of references after the pattern you’re trying to match. By reference I mean something that’s commit-ish. That is, it can be the id (or SHA) of a commit, the name of a branch, a tag, or one of the special identifier like HEAD.

# search the master branch, and two commits by id, 

# and also the commit two before the HEAD

PS:\> git grep monkey master d0fb0d 032086 HEAD~2

The SHA is the 40-digit id of a commit. We only need enough of the SHA for Git to uniquely identify the commit. Six or eight characters is generally enough.

Here’s an example using the RavenDB repo.

PS:\> git grep -n monkey master f45c08bb8 HEAD~2



master:Raven.Tests/Storage/CreateIndexes.cs:83:         db.PutIndex("monkey", new IndexDefinition { Map = unimportantIndexMap });

master:Raven.Tests/Storage/CreateIndexes.cs:90:         Assert.Equal("monkey", indexNames[1]);

f45c08bb8:Raven.Tests/Storage/CreateIndexes.cs:82:          db.PutIndex("monkey", new IndexDefinition { Map = unimportantIndexMap });

f45c08bb8:Raven.Tests/Storage/CreateIndexes.cs:89:          Assert.Equal("monkey", indexNames[1]);

HEAD~2:Raven.Tests/Storage/CreateIndexes.cs:83:         db.PutIndex("monkey", new IndexDefinition { Map = unimportantIndexMap });

HEAD~2:Raven.Tests/Storage/CreateIndexes.cs:90:         Assert.Equal("monkey", indexNames[1]);

Notice that each line begins with the name of the commit where the match was found. In the example above where we asked for the line numbers, the results were in the pattern:

[commit ref]:[file path]:[line no]:[matching content]

N.B. I had one repository that did not work with git grep. It was because my ‘text’ files were encoded UTF-16 and git interpretted them as binary. I converted them to UTF-8 and the world became a happy place. Thanks to Keith Dahlby and Adam Dymitruk for helping me to figure out the problem.

References

Comment on this post at dev.bennage.com

Next, searching for specific operations (add, delete, modify, and rename).

Discuss ()

How to force Nuget not to update log4net to 1.2.11

Posted by Krzysztof Koźmic, Tuesday, January 31, 2012 (1,649 views)

That’s a quick one. There’s been a new release of log4net recently that’s signed with a new key, and therefore is incompatible with old version 1.2.10.

Therefore, due to near-ubiquity of the library in .NET space, it may cause some problems if you happen to have a dependency (direct or indirect) on it.

The matters are made worse by Nuget’s default of getting the latest available version of the package. I dealt with this problem the other day, and I saw a few people in my twitter stream struggling with the same issue.

The solution is quite simple. It’s not specific to log4net and I’m not picking on log4net here. Here’s how you can restrict Nuget’s package to specific version in your solution.

 

So imagine you install a package that has a dependency on log4net. In this case, the dependency is specified as specifically version 1.2.10 (as opposed to Nuget’s default: this version of newer).

nuget_core

If after that we install another package that also depends on log4net but doesn’t restrict the version, we’ll have a problem.

nuget_log4net_fail

The package we were trying to install doesn’t get installed. Actually, even if it did, we would have a problem since it most likely was compiled against log4net 1.2.10 anyway, and if Nuget updated log4net to version 1.2.11 the app would throw an exception at runtime due to mismatched assembly.

So there is a solution to restrict version of the package to specific version (in this case 1.2.10) as specified in the documentation.

nuget_log4net_fail_solution

After adding allowedVersions=”[1.2.10]” we can try again and this time the package will install properly.

nuget_log4net_fail_avoided

Notice it says it installed log4net 1.2.11. I checked my packages folder, and project dependencies and the version referenced was 1.2.10 so all is good.

Hope that helps

Filed under:
Discuss (3)

Finding Files by Name With Git

Posted by Christopher Bennage, Monday, January 30, 2012 (485 views)

Acknowledgment: This is meant to be the Windows equivalent of Anders Janmyr’s excellent post on the subject of finding stuff with Git. Essentially, I’m translating some of Anders’ examples to Powershell and providing explanations for things that many Windows devs might not be familiar with.

This is the first in a series of posts providing a set of recipes for locating sundry and diverse thingies in a Git repository.

Finding files by name

Let’s say that you want locate all the files in a git repository that contain ‘monkey’ in the file name. (Finding monkeys is a very common task.)

# find all files whose name matches 'monkey'

PS:\> git ls-files | Select-String monkey

This pipes the output of git ls-files into the Powershell cmdlet Select-String which filters the output line-by-line. To better understand what this means, run just git ls-files.

Of course, you can also pass a regular expression toSelect-String (that is, if you hate yourself.)

References

Comment on this post at dev.bennage.com

Next, searching for files with specific content.

Discuss ()

Software Release Management - Why You Can’t And Shouldn’t Force People to Use the Latest Version

Posted by Rob Reynolds, Wednesday, January 25, 2012 (2,766 views)

As software creators we don't get to decide what version of our tools / libraries that people use. If we try to force them, our users will go somewhere else.

Update: What Type of Software This Applies To

This post talks of tools, applications and libraries. Things that end up in the users hands. This does not apply to SaaS or websites. These do not end up in the hands of the users in the same sense.

For those of you who immediately think of Chrome or Firefox, which are applications that end up in the users hands, those apply to this post as well. They have nearly perfected a silent upgrade experience, but if they ever mess up that experience, users can choose to use something else. And I believe there is a way to opt out as well (not easily achieved but possible).

Software Release Management

I write software. Much of it is open source. I have multiple versions of my products out there. Even with newer versions available that fix bugs and bring about new features, I still find people using older versions. Even though I have a better newer version that fixes some of the bugs they are dealing with, they are still using an older version. Think about that for a second. There must be a good reason right? Let’s state this in an official sense.

As a software creator you release software. You put a release out there and people use that release. You delineate different releases by a concept of versioning. People use a particular version of your release. You release newer versions of your software that has fixes and enhancements. You hope users upgrade to the latest release when it is available.

I’ve stated five facts and finished with a hope. If you can accept those as facts, we can move on. If we can’t, then you might want to stop reading now because we are never going to agree. If you are a developer like me, you really want people to always use the latest version of your software, so you might be able to accept the last statement as a fact for you. I really want people to always use the latest release of my software as I have went through the trouble of testing it and making it better.

Now let me change some terms for you. Software release management is really a fancy way of saying package management. A software release could be better termed a package. So to restate, as a software creator, you release packages. You put a package out there and people use that package. You delineate different packages by a concept of versioning. People use a particular version of your package. You release newer versions of your package that has fixes and enhancements. You hope users upgrade to the latest package when it is available.

The Hope Versus The Force

I say “hope they upgrade” because you really can’t control that aspect. You can try. You can delete the older versions. You can refuse to have older versions available. You can tell users that they should and need to upgrade. But you put it out there once and it is now out there forever. People will find a way to get to the particular version they need. Or they will go elsewhere. Users speak with their feet.

I find attempting to force a user to do something is both an exercise in futility and a great way to guarantee that you have less users overall.

So people must want to use a particular version of a product. Let’s examine this a little more. Why on earth would someone use an older version of a product when a newer, better, less buggier version is available?

Why Do Users Use Older Versions?

Users use older versions of our packages and they have great fundamental reasons for doing so:

  • It reduces their risk.
  • It guarantees that users of their library (that has a dependency on your library) have a good experience.
  • It guarantees that the product that they have tested is the same product that gets into the hands of consumers.
  • It guarantee their product builds successfully and the same way each time.

In fixing a product and making it better and less buggier, you may actually be breaking someone’s ability to use a newer version. And you have no guarantee to the user that this version doesn’t have flaws of it’s own. Right? Otherwise there would only be one version that ever had fixes in it. We wouldn’t need to release newer versions with fixes, only enhancements. But we don’t. We fix things we thought worked and we fix things we tested but missed some crazy edge case. This is why we go down this path of release management. This is software development.

So people get a certain version and they use it. Users upgrade to the latest version of software when they are ready, not when the software creator is ready. People depend on certain versions or on a range of versions. In reality I can't force someone to use the latest version. If I try, they will find the version they need through the powers of the internet or find another way. Accepting that, I can give them a way to see it and help them fall into the pit of success.

From the User Perspective

Shifting to the perspective of the user, I might use your library in my own software. Being able to build my product, even if it means it is using an older version of your package that has bugs, is worlds more important to me and my users. We'll get to your latest version when we can test that it doesn't break our product. But don't try to force me to upgrade to your latest version or I will find another way. I'm not saying that with your package but in all packages the newer version may be buggier than the current buggy version we are using. We don't know and you can’t guarantee that it doesn’t, even with extensive testing. Testing doesn’t prove the absence of bugs, only the absence of errors that you know. I digress.

It’s an evil that we know versus and evil that we don’t. Or put another way, it's a buggy version we know versus a buggy version we don't.

If it’s a tool, we need to ensure that our usage of your product still meets our expectations. We need to test it even though you did and make sure it still works for our needs and scenarios. Where it doesn’t we need to decide if that means we can shift our expectations and upgrade. But we are not going to blindly upgrade and just use the latest version because the software creator believes that is best.

Can you cover the millions of dollars that we might lose by taking on a newer version of your product? If you can give me that guarantee, as a user I will gladly pass that risk on to you.

Final Thoughts

Whether you agree or not, as software creators we don't get to decide what version of our tools / libraries that people use. We just don’t have that luxury. If we try to our users will go somewhere else. So we make it easy for them to upgrade so they will want to. We make the upgrade experience painless so they will want to. We need to be good stewards.

Filed under: , , , ,
Discuss (7)

Missing Silverlight Resources and ASP.Net security

Posted by Derik Whittaker, Wednesday, January 25, 2012 (994 views)

Have you ever had an error crop up when debugging an application which has made you simply want to pull each hair out of your head one by one with a pair of tweezers because that would be less painful than debugging the error? Today I had just this happen to me.

Today when I hit F5 to launch our Silverlight application I received the following exception :

image

The body of this error message is

Line: 56
Error: Unhandled Error in Silverlight Application
Code: 2108   
Category: InitializeError      
Message: Failed to download the splash screen    

Of course since I have the debugger I was going to attach to it, but sadly that was NO HELP.  When reading error you notice it says that it failed to download the splash screen. This is really odd because when looking in the source it is there…  In an effort to ‘remove the problem’ I removed the line of code from our ASPX page which setup the splash screen as a resource, the line below.

<param name='splashscreensource' value='SplashScreen.xaml' />

Thinking that this would solve my issue, at least for now, I hit F5 again.  Things were different this time, but sadly not for the better.  Now in place of getting the error message I simply got the default ‘blue dots’ from silverlight indicating that the xap was trying to load.  This was really odd.  I did what any developer would do, I hit F5 3-4 more times thinking that the problem would just magically go away, hey it does happen, but as you can guess it did not go away.

Because I had been making a bit of changes in the code and it was possible that I could have accidently really FUBARED my code base I shelved my code, blew away my ENTIRE branch and did a fresh pull.  Yea, that did not either.

So my on branch was dead, but my co-worker who is in the same branch was able to launch and run the app just fine.  In another effort to see if it was my branch code or my machine I decided to pull down the trunk (the parent of this particular branch) to see if I had the issue there… Yea no, that code worked just fine.

Because I knew it was not my machine it had to be code.  I decided to start diffing the files I thought were causing the issues such as our default.aspx page, our login page along with a few other files.  As you may have guessed NONE of these files were different.

Because I had been beating my head against this for greater than an hour I decided that I should move on to something else and come back to this later (I guess I was still holding out for the code fairy to magically fix my stuff while I was away).

Well later came and I had to go back to my branch to fix a production issue and this issue was still there.  This time however things were a bit different, no the code fairy did not do her magic, my co-worker said ‘hey I got that a few minutes ago’.  I was both elated and pissed at the same time.  I was elated because maybe NOW I could solve my issue.  I was pissed because this was the same co-worker I had talked to about this issue a few hours back and NOW they knew how to solve the issue.

So what was the issue?  My co-worker was playing around with some security settings in our web.config file and had accidently committed is changes.  It was these changes that was causing my issue.  What did he change?  He did 2 things

1) He setup a deny ALL authorization rule
image

 

 

2) He setup other rules to only allow a few pages to be open as such
image

The 2nd change was not a huge issue, it was the 1st one that was killing me.  Because he had turned off anon access to the site my xap could not load and because my xap could not load the splash screen could not be presented to the user and for what ever reason Silverlight decided that in place of providing a meaningful message it would simply say it could not find my splash screen resource.

Since I knew the issue I was able to change my rule from deny to allow (in #1) and re-run the application…. finally I could fix bugs I created Smile

The moral of the story here is that if you get an error saying you cannot access a resource in your xap file double check that IIS has access to the xap because if it does not you may get this issue.

The other moral of the story is that it should be 100% legal to cane a co-worker who commits a change that breaks you and does not even realize it. Ok caning may be harsh, at least they should buy you a beer.

Till next time,

Filed under:
Discuss (0)

Boo-yah!!! Caliburn.Micro v1.3 RTW is Here

Posted by Rob Eisenberg, Friday, January 20, 2012 (4,199 views)

I’m extremely pleased to announce the release of Caliburn.Micro v1.3.  This is a great release with many bug fixes and several API improvements. We also support several new platforms. Here’s the highlights:

  • Support for WP7 Mango
  • Support for Silverlight 5
  • Basic MVVM Support for WinRT/Metro
  • Awesome improvements to ViewModelLocator/ViewLocator which allow easier customization of conventions.
  • Improved Design-Time Support for Conventions

Thanks to the great community who provided awesome feedback during this release cycle. Thanks also to those who spent time to provide fixes and pull requests for bugs as well as for API improvements. I’d like to add a special thanks to Chin Bae for excellent work on making our ViewLocator and ViewModelLocator both more extensible and more accessible for common customizations.

We’re still just getting started. Enjoy the new bits and see what you can build!

Testing framework is not just for writing… tests

Posted by Krzysztof Koźmic, Wednesday, January 18, 2012 (2,368 views)

Quick question – from the top of your head, without running the code, what is the result of:

var foo = -00.053200000m; 
 
var result = foo.ToString("##.##");

Or a different one:

var foo = "foo"; 
var bar = "bar"; 
var foobar = "foo" + "bar"; 
var concaternated = new StringBuilder(foo).Append(bar).ToString(); 
 
var result1 = AreEqual(foobar, concaternated); 
var result2 = Equals(foobar, concaternated);
 
 
 
public static bool AreEqual(object one, object two) 
{ 
    return one == two; 
}

How about this one from NHibernate?

var parent = session.Get<Parent>(1); 
 
DoSomething(parent.Child.Id); 
 
var result = NHibernateUtil.IsInitialized(parent.Child);

The point being?

Well, if you can answer all of the above without running the code, we’re hiring. I don’t, and I suspect most people don’t either. That’s fine. Question is – what are you going to do about it? What do you do when some 3rd party library, or part of standard library exhibits unexpected behaviour? How do you go about learning if what you think should happen, is really what does happen?

Scratchpad

I’ve seen people open up Visual Studio, create ConsoleApplication38, write some code using the API in question including plenty of Console.WriteLine along the way (curse whoever decided Client Profile should be the default for Console applications, switch to full .NET profile) compile, run and discard the code. And then repeat the process with ConsoleApplication39 next time.

 

The solution I’m using feels a bit more lightweight, and has worked for me well over the years. It is very simple – I leverage my existing test framework and test runner. I create an empty test fixture called Scratchpad.

scratchpad

scratchpad_fixture

 

This class gets committed to the VCS repository. That way every member of the team gets their own scratchpad to play with and validate their theories, ideas and assumptions. However, as the name implies, this all is a one-off throwaway code. After all, you don’t really need to test the BCL. One would hope Microsoft already did a good job at that.

If you’re using git, you can easily tell it not to track changes to the file, by running the following command (after you commit the file):

git update-index --assume-unchanged Scratchpad.cs

scratchpad_git

With this simple set up you will have quick place to validate your assumptions (and answer questions about API behaviour) with little friction.

scratchpad_test

 

 

So there you have it, a new, useful technique in your toolbelt.

Discuss (8)

Approval testing – value for the money

Posted by Krzysztof Koźmic, Monday, January 16, 2012 (1,908 views)

I am a believer in the value of testing. However not all tests are equal, and actually not all tests provide value at all. Raise your hand if you’ve ever seen (unit) tests that tested every corner case of trivial piece of code that’s used once in a blue moon in an obscure part of the system. Raise your other hand if that test code was not written by human but generated.

 

As with any type of code, test code is a liability. It takes time to write it, and then it takes even more time to read it and maintain it. Considering time is money, rather then blindly unit testing everything we need to constantly ask ourselves how do we get the best value for the money – what’s the best way to spend time writing code, to write the least amount of it, to best cover the widest range of possible failures in the most maintainable fashion.

Notice we’re optimising quite a few variables here. We don’t want to blindly write plenty of code, we don’t want to write sloppy code, and we want the test code to properly fulfil its role as our safety net, alarming us early when things are about to go belly up.

Testing conventions

What many people seem to find challenging to test is conventions in their code. When all you have is a hammer (unit testing) it’s hard to hit a nail, that not only isn’t really a nail, but isn’t really explicitly there to being with. To make matters worse the compiler is not going to help you really either. How would it know that LoginController not implementing IController is a problem? How would it know that the new dependency you introduced onto the controller is not registered in your IoC container? How would it know that the public method on your NHibernate entity needs to be virtual?

 

In some cases the tool you’re using will provide some level of validation itself. NHibernate knows the methods ought to be virtual and will give you quite good exception message when you set it up. You can verify that quite easily in a simple test. Not everything is so black and white however. One of diagnostics provided by Castle Windsor is called “Potentially misconfigured components”. Notice the vagueness of the first word. They might be misconfigured, but not necessarily are – it all depends on how you’re using them and the tool itself cannot know that. How do you test that efficiently?

Enter approval testing

One possible solution to that, which we’ve been quite successfully using on my current project is approval testing. The concept is very simple. You write a test that runs producing an output. Then the output is reviewed by someone, and assuming it’s correct, it’s marked as approved and committed to the VCS repository. On subsequent runs the output is generated again, and compared against approved version. If they are different the test fails, at which point someone needs to review the change and either mark the new version as approved (when the change is legitimate) or fix the code, if the change is a bug.

 

If the explanation above seems dry and abstract let’s go through an example. Windsor 3 introduced way to programmatically access its diagnostics. We can therefore write a test looking through the potentially misconfigured components, so that we get notified if something on the list changes. I’ll be using ApprovalTests library for that.

[Test]
public void Approved_potentially_misconfigured_components()
{
    var container = new WindsorContainer();
    container.Install(FromAssembly.Containing<HomeController>()); 
 
    var handlers = GetPotentiallyMisconfiguredComponents(container);
    var message = new StringBuilder();
    var inspector = new DependencyInspector(message);
    foreach (IExposeDependencyInfo handler in handlers)
    {
        handler.ObtainDependencyDetails(inspector);
    }
    Approvals.Approve(message.ToString());
}
 
private static IHandler[] GetPotentiallyMisconfiguredComponents(WindsorContainer container)
{
    var host = container.Kernel.GetSubSystem(SubSystemConstants.DiagnosticsKey) as IDiagnosticsHost;
    var diagnostic = host.GetDiagnostic<IPotentiallyMisconfiguredComponentsDiagnostic>();
    var handlers = diagnostic.Inspect();
    return handlers;
}

 

What’s important here is we’re setting up the container, getting the misconfigured components out of it, produce readable output from the list and passing it down to the approval framework to do the rest of the job.

Now if you’ve set up the framework to pup-up a diff tool when the approval fails you will be greeted with something like this:

approval_diff

You have all the power of your diff tool to inspect the change. In this case we have one new misconfigured component (HomeController) which has a new parameter, appropriately named missingParameter that the container doesn’t know how to provide to it. Now you either slap yourself in the forehead and fix the issue, if that really is an issue, or approve that dependency, by copying the diff chunk from the left pane to the right, approved pane. By doing the latter you’re notifying the testing framework and your teammates that you do know what’s going on and you know it’s not an issue the way things are going to work. Coupled with a sensible commit message explaining why you chose to approve this difference you get a pretty good trail of exception to the rule and reasons behind them.

 

That’s quite an elegant approach to a quite hard problem. We’re using it for quite a few things, and it’s been giving us really good value for little effort it took to write those tests, and maintain them as we keep developing the app, and the approved files change.

 

So there you have it, a new, useful tool in your toolbelt.

Discuss (3)

How to Show a deleted List Item with a Strike Through in XAML

Posted by Derik Whittaker, Sunday, January 08, 2012 (1,450 views)

When building applications it is very common to have a set of screens which are basically list/edit screens.  And when having these list/edit screens it is also common to allow users to delete a row.  In this post I am going to show how you can add a neat little UI wrinkle to your deleting action which will be visually appealing but will also allow users to undo their changes with ease.

If you take a look at the screen shot below you will notice that I have a data grid with 2 line items.  You should also notice that at the far right of each row is a ‘Red X’ which can be used to delete that selected row.  Commonly when you have this type of delete action the row will be removed from the UI in real time.  Having the row removed in real time is ok but it does give the user an easy way to undo their actions prior to committing their changes.  What I would like to do is change this.

image

In the screen shot below you can see how we have accomplished the ability to mark a row as being deleted yet still give the user the ability to undo a given deletion.  What we have done is 2 things.

  1. In place of actually removing the row from the grid we implemented the strike through to show the user that row will be removed when the save their changes.
  2. We removed the delete icon and replaced it with the add icon

image

Since we know what we want to accomplish how do we actually do it.

  1. Setting up your model to have Deleted bool property
    In order for this whole thing to work you will need to have some sort of bool property on your underlying model which stored the Deleted state of a given row.

    	private bool _deleted;
            public bool Deleted
            {
                get
                {
                    return _deleted;
                }
                set
                {
                    _deleted = value;
    
                    OnPropertyChanged(() => Deleted);
                }
            }
  2. Setting up your XAML to have the strike through
    In my XAML we are using the stock DataGrid for Silverlight and we are templating each column in the grid.  For the columns which we want to implement the strike though we need to add some xaml which will only be visible WHEN Deleted flag of the given row is true.  Here is snapshot of our XAML

    image

    Things to pay attention to in the above XAML are
    1) We have both a TextBlock and a Rectangle element in our cell, however the Rectangle’s visibility is being set based on the Deleted flag.  To set this visibility we are using a BooleanToVisiblity converter (will put that code at the end of this post)
    2) In the above case the margin on the Rectangle is Margin=”4,0,0,0” and this is because it is far left column in our grid and we don’t want the line to butt up against the edge.  In the middle columns we don’t want a margin in order to appear to be a complete line.  However in our far right column we want to setup the margin as Margin=”0,0,4,0” in order to not butt up against the right hand edge.

  3. Setting up your XAML to swap action buttons based on the deleted state
    To enable the swapping of our buttons based on the Deleted flag we basically will do the same as above w/ the strike through lines but in place of the visibility being swapped on a Rectangle we will do it on a Button element.

 

BoolenToVisibilityConverter Code

	public class BooleanToVisibilityConverter : IValueConverter
	{
        public Visibility TrueValue { get; set; }
        public Visibility FalseValue { get; set; }

        public BooleanToVisibilityConverter()
        {
            TrueValue = Visibility.Visible;
            FalseValue = Visibility.Collapsed;
        }

		public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
		{
            if (value == null)
            {
                return Visibility.Collapsed;
            }

			return ((bool) value) ? TrueValue : FalseValue;
		}

		public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
		{
			throw new NotImplementedException();
		}
	}

As you can see you can implement a slick UI which shows the user an item has been deleted with very little effort.

Till next time,

Filed under: ,
Discuss (2)

How I Lost, Regained and then Turned Down an MVP Award

Posted by Rob Eisenberg, Wednesday, January 04, 2012 (33,865 views)

What Happened To Me

I’d say that 2011 was a pretty good year for me as a .NET open source developer. After all, Caliburn.Micro had it’s first official release in April 2011 just in time for the Mix Open Source fest. At the festival, the framework had a great showing. I had tons of people literally coming up to me and dumping *all* their voting tokens into my bucket. In fact there were so many people constantly standing around my booth that my bucket didn’t even get collected for counting in the official vote. Thankfully someone standing around realized this and helped to remedy the situation. Needless to say, it was a successful event. Over the next several months I did two additional non-trivial releases and then began work on the v1.3 release. I also added support for Silverlight 5, WP7 Mango and preliminary support for WinRT/Metro. Furthermore, I began refactoring the entire framework so that it could be modularized into “feature” packages allowing a variety of different uses of the framework via Nuget. I even tested CM’s EventAggregator and IoC container to make sure they would run without issue on iOS and Android devices via Unity3d. In addition to the actual framework development, I wrote documentation, blogged, fixed dozens of bugs and added new features. I also participate daily in the Caliburn.Micro forums which currently have about 1k discussions. Caliburn.Micro is now used as the core enabling framework for thousands of applications across WPF, Silverlight and various versions of WP7. Depending on the day, Caliburn/Caliburn.Micro is the second or third most trafficked Xaml-related open source project in existence.

I’m not trying to toot my own horn here. I’m just trying to set up a context. Considering the enormous amount of work in both creating the project and supporting the community…you can imagine my surprise when I received the “form letter” stating that my MVP was not being renewed because I hadn’t accomplished enough in the last 12 months….and what I did do did not “stand out” in the community. Here’s the actual quote:

“The MVP Award is presented to individuals for their past year’s contributions to online and offline communities, which stand out from others in the communities that focus on Microsoft technologies. Your contributions were diligently evaluated over the past year against the contributions of others in the Silverlight community.  As a result of this evaluation, you were not awarded as a MicrosoftMVP for the January 2012 award cycle.”

Now, I’m not really “attached” to being an MVP. I don’t attach a lot of self-worth or emotional satisfaction to it. It’s a nice thing to have though. So, I was really caught off guard by this and wondered how the MVP program could come to the conclusion that I hadn’t significantly contributed in the last year.

What I Did

Being surprised as I was, and not being too fond of “generic” letters , I made one simple tweet:

“Apparently Caliburn/Caliburn.Micro and my support of it is not a ‘good enough’ contribution for Microsoft. I lost my MVP this year.”

The Community Response

Immediately following this tweet, a storm of people responded with great affection for my work and general encouragement. I want to say thank you to everyone who responded so kindly. Paired with the encouragement was a general sense of befuddlement around how the MVP program could make such a conclusion. Apparently, I wasn’t the only surprised individual.

I thought to myself “mistakes happen.” But as I was surveying the twitter-verse, I also learned that Jeremy Miller (StructureMap, FubuMVC, Storyteller) and Daniel Cazzulino (Moq) also lost their MVPs; two other prominent open source developers. Now I had had some problem during the re-evaluation process indicating my new MVP Lead clearly didn’t understand the nature of open source. When I was up for renewal, he asked me to fill out a rather ridiculous spreadsheet. If you could see it, you would notice something missing? There’s no category for Open Source!!! There’s not even a way to report it. I had this problem in previous years when I was asked to update my online MVP profile (a hideously painful UX by the way). The program uses that to evaluate you as well. Guess what? There’s no way to report Open Source work!!! Do you see a trend here?

--Start Rant

The thing that really disturbed me was that my MVP Lead didn’t know who I was or understand the nature of my contributions. What is it that an MVP Lead does anyways? I can’t tell. I get a useless mass email every week or so telling me things about Microsoft I don’t care about. Half of the time it isn’t even readable due to bad formatting, etc. My Lead never contacted me personally during the year. When I came up for renewal, I had to *defend* why I should have my award renewed using a bad Excel spreadsheet and a really bad online form which don’t even allow me to capture my real contributions. Shouldn’t it be an MVP Lead’s job to know his MVPs and what it is they are doing? Seriously. I sat down and calculated how much time it would take me to fill out the Excel form and the online form, plus writing a custom report for everything that wasn’t able to be captured via those broken mechanisms. I took that number of hours and multiplied it by my hourly consulting rate and determined that the money I would make working exceeded the material value of the MVP award. Haven’t I given enough free work to Microsoft? This isn’t a personal attack on *my* MVP Lead. I don’t know the guy. But, I wonder whether the role of MVP Lead is improperly defined or under-defined, because I know that I’m not the only person who has had this exact problem repeatedly.

--End Rant

Microsoft Employees to the Rescue

Also following my tweet, a number of Microsoft employees stepped in to investigate.  I have to thank them here personally. Much thanks to you (in no particular order) Tim Heuer, Pete Brown, Joe Healey, Glenn Block and Scott Hanselman. At one point I heard that this issue had even been escalated internally to Scott Guthrie. It’s truly an honor that so many well known and respected individuals *inside* Microsoft stepped up to personally investigate my situation. Thank you again. This is a tremendously good thing and points out something of great importance. Over the years I’ve very rarely had negative experiences with individual Microsoft employees. But, I’ve almost always had bad experiences interacting with groups, programs, etc. It seams that somehow the opinions of the individuals are lost in the system. That’s a real shame.

If the opinion of many trusted Microsoft employees and the opinion of so many community members is not reflected in the MVP Award, then there certainly is a problem with the program…or I don’t understand what the program is.

An MVP Again…for a few hours

Thanks to the work of the gentlemen listed above, I was informed last night that I was being re-awarded an MVP for the 2012 year. I understand this sort of thing never happens. But, I’d already had several days to reflect on the MVP program and had several conversations with various people leading to several realizations listed above and several more detailed below. I was very unsettled.

Why I Turned Down the MVP

This morning I responded to the award email with a respectful decline. Below are some of the reasons I chose to no longer be a part of the program and why I doubt I will participate again, unless serious reform happens.

Becoming an MVP

One of the problems with the MVP program is that the whole thing is basically a mystery. Here’s where I first knock heads with the program. I value transparency and openness, even if it’s difficult or sometimes painful. The MVP program does not value openness. That’s why it’s basically a mystery how you get nominated for an MVP or what you have to do to get one. Let me do a little exposé here. In my case, I’m fairly sure that my local Developer Evangelist saw the work I was doing in the local community and submitted me. That’s a good thing and it’s probably fairly common. But what happens from there? It’s my understanding that it’s completely out of DPE’s hands at that point. Who knows? From what I can tell, if the MVP program is interested in you, you then have to submit proof of your accomplishments to them. I remember doing this. It’s not like a normal award where the organization does the work to investigate your contributions and then decides whether or not to give you an award. No. If you are being considered for nomination, you literally have to *sell* yourself to the MVP program…and selling is exactly what you are doing. Want to know why? Have you noticed that the MVP disciplines are strictly organized around internal product groups, regardless of how hindering to the particular MVP discipline it appears to be? An example of this is that Client AppDev, Silverlight, WP7 and Blend are all separate MVP groups even though they should be unified. Because they are different products, they are different MVPs (actually, they should all be the same product, but that’s a subject for another blog post). Do you know why this is? I’ll tell you: because each product group literally gets an MVP “budget” which they use to “purchase” MVPs for the year. Personally, I’m offended by this notion. But it would take drastic re-organization of the MVP program to fix it.

General Life as an MVP

Now you can just imagine how this division along product lines and MVP purchasing might affect things. Because Microsoft’s product teams are notorious for not only being non-communicative with one another but are often pitted against one another by the upper level management…the various product teams can develop a vastly different set of values and beliefs with respect to interaction both internally and with the outside world. Depending on what MVP discipline you are a part of…and the nature of your contributions…you may have a great experience or you may be in store for hell. If the product group you are associated with is open, such as ASP.NET, you can expect lots of interaction, incorporation of your feedback into the product and probably a deep respect of open source work. If your product team is something like WP7, you can expect much less communication, very little change to the product based on your feedback and probably…they don’t even know what open source is.

My Life as an MVP

As for myself, it’s clear that my major contribution is through an open source framework. What a fool I was…there’s a certain insanity in building an open source framework on top of a proprietary UI stack. Back when I was awarded the MVP, I was given the Client AppDev designation, which basically means WPF (but for some reason, contrary to what I’ve said above, also included WinForms..interesting how they had WPF and WinForms in the same group but not WPF and Silverlight…but I digress…or do I?). Back then Xaml tech wasn’t so secretive. When Silverlight came along, they moved me into that group. That group was different. Silverlight was kept tightly sealed. When I was a Client AppDev, I actually felt like Rob Relyea and John Gossman were my kin. When I became a Silverlight MVP, I felt like I was an outsider being graced with a little tiny window to peer in on things. I say all that because when I started on Caliburn, while I was working on a proprietary platform, it felt more open. But when Silverlight came along, things changed. WP7 was even worse than Silverlight…and WinRT/Metro…well…they didn’t talk to anyone. Now that Xaml has moved out of the Developer Division and into the Windows division, it’s only going to get worse.

Secret Societies

I’ve already mentioned how the organization of the MVP groups along product lines can be a hindrance to everyone. WPF, Silverlight, WP7, Metro and Blend…which are all used by the same group of people, are actually different MVP groups. As a Silverlight MVP…I had no access to anything happening with WP7. I had no knowledge of WinRT/Metro. I had no knowledge of Blend or any mechanism to directly interact with that product team. Now, Caliburn.Micro spans all of these technologies, but I could really only talk to Silverlight product team members…and a few of my old WPF comrades. But would it surprise you if I told you the organizational absurdity went even farther. Did you know there are “insiders” groups. “Insiders” for a particular product group have more privileged knowledge than MVPs and more opportunities for direct interaction. Some MVPs are also insiders, but not all. Some insiders are not MVPs. But wait, there’s more. There’s also the TAP program….which seams to have more privileged connections and knowledge. To this day, I don’t know how one gets in a TAP program. I was in the WP7 Tap for about two days. Some guys already in the program were talking in the TAP forums about getting Caliburn.Micro working on WP7. They yelled loud enough and the powers that be invited me, since it seamed that significant apps were likely to be built with my framework. Unfortunately, things went public very shortly after that and the TAP was closed. LOL. But it doesn’t end there. It seams, based on observation, that there are even more secretive groups…who pretty much know everything the product team knows. These guys don’t have a name and I don’t know how you get into that. Though, I’m pretty sure it has to do with being “chummy” to the right people. Childishness. The bottom line is that there are too many levels of secrecy and too many and the wrong types of divisions to enable an effective feedback loop. I don’t know if this is true of all MVP groups, but it was with Silverlight and it has got worse with each successive Xaml platform. Now that Xaml is in Windows, I don’t expect anyone to be able to provide decent feedback.

Fruitlessness

Since things are so improperly organized, there are really only a few occasions where one can really provide good feedback on the product. Unfortunately, after three years as an MVP, I have to say that not a single bit of feedback I provided resulted in any sort of change to the product. With the Silverlight team..and almost always with the Blend team (when I could actually run one of them down), I would get some response like “yes, we’ll have to have a conversation about that.” And I’d be thinking…”isn’t that why I’m here at the MVP summit talking to you now?” But they never seamed to want to engage in a real discussion on *anything* that affected me, my project or my clients. I had this happen every year at the summit. I had even more outrageous things happen in email and at BUILD. On the insiders email list (when I finally got on it), I tried to start a conversation about Convention over Configuration and improvements to tooling that would help support those scenarios and generally make tool extensibility better. Somehow I managed to get into a private email thread of the Blend team where they could engage me on that. You know what they said when I tried to continue the conversation? They said “we don’t want to discuss that right now.” Ok…thanks. That made me really mad. Why am I an MVP again? But the real treat was at BUILD. I managed to track down two of the Blend PMs. I first talked to the PM in charge of the JavaScript Blend work. I told him about what I was building in JavaScript. He was really interested and wanted to follow up with me on what I was building and how it would work inside Blend. Then I took several steps to the right to talk to a Blend PM working on the Xaml side of things. I tried, once again, to discuss CoC. I know for a fact these guys either don’t understand it or don’t think it’s important in software at all. Well, they listened for a moment, then I asked about improving the tooling so I could have a plugin mechanism by which to improve that scenario for my customers. They were very not-helpful. I tried to bring up issues of developer productivity and better strategies for building applications. In a nutshell, the PM basically said to me “we don’t care about developers…they aren’t part of our use cases.” I was pretty enraged by that. See how the product team’s culture affects the effectiveness of the MVP program? My main point though is that nothing I ever said or did affected any product team’s work. Nothing. It was a waste of time and energy…and an emotional drain.

MVP Quality

Now I want to tread lightly here with how I say this….not all MVPs are created equal. I’m going to be vague here. I met an MVP once for Technology X. It turned out that she had never built anything with Technology X and wasn’t overly knowledgeable about it. She liked Technology X a lot though. Each day she would scan her RSS feeds and post about 8 - 10 links on Technology X. That’s why she had her MVP. It looks good on a review doesn’t it? I blogged 365 posts on Technology X this year!!  Now, I’ve met some MVPs in various areas that were brilliant and obviously contributing a lot. But, I’ve met a fair share of MVPs who not only were not experts on the technology, but didn’t make half the contribution that other developers I knew did, who were never awarded MVPs. Not all MVPs are equal. If you are an employer, or looking for a speaker, expert, consultant…whatever; you cannot assume that just because that person has an MVP that they know what they are talking about. It’s sad, but this describes a noticeable number of MVPs.

One more word on MVP quality with respect to division along product team lines. You should never hire a highly product-specific MVP to help advise you on technology choices. I hope you realize the built-in problem with that. I know very few Technology X MVPs who would tell you not to use Technology X, even if there was a better, cheaper, faster way to build your solution. Be wary.

Open Source

I just want to say a little more about this. As I mentioned, there’s nothing about the MVP program that explicitly allows for recognition of open source work. It’s hard to get nominated for it and it’s even harder to renew with it. MVP leads who play a major roll in the renewal process may not be technical at all and even may not understand Open Source. Since I’ve mentioned how MVPs are linked to product groups, you might guess that the effectiveness of your MVP as an OSS developer is entirely dependent on that particular product group’s understanding of and interest in OSS. In a group related to ASP.NET or JavaScript, developers on the team are likely to have run open source projects themselves. In a group like Silverlight or WP7, they are likely to have never done such a thing…and not even have a clear idea of what is involved. I really came face to face with this when my non-renewed MVP…got renewed. Why? Well, it felt like a sort of “benefit of the doubt” renewal. Here’s the advice I was given from the renewal email, elided:

EDIT: I removed this quotation because a good friend of mine was honest enough to remind me that quoting a personal email is neither professional nor polite. I repent of that.

--Start Rant

What!? I released one of the most popular Xaml-related OSS project this year. I did multiple version releases, nuget packages, podcasts, documentation, forum support…the list goes on. What more do you want from me? And what should I do next year…because Caliburn.Micro is so popular, that in order for me to do something bigger for next year…I’d have to dump it entirely….completely abandoned it and build something totally different…something even more popular for Silverlight!? How could I do that to my community? That’s not even nice. No, in 2012, I’m going to continue to fix bugs, add features, add platform support and do awesome things with Caliburn.Micro. I love my own community and I’m going to continue to work hard and support them.

--End Rant

Now this kind of comment clearly expresses a deep lack of understanding for both the value of a project like Caliburn.Micro and the amount of time and resources it takes to maintain both the project and the community. If your OSS project is successful, it’s not just something you do one year and then move on to something else the next. In fact, building the first version of Caliburn.Micro was the easy part! It’s everything that’s happened afterwards and what is happening now that is hard work and will continue to be.

Unfortunately, Microsoft just doesn’t have a way of recognizing OSS developers who improve their platform. The MVP program doesn’t do this and the product teams may not either. In fact, Balmer has explicitly said he isn’t creating any policy around OSS…he’s totally dodging it entirely. This leaves the decision up to the individual teams…which sometimes goes well, but often times does not. That’s irresponsible leadership.

Career Affects

No one ever hired me as a consultant because I had an MVP. They hired me because of my open source work and my recognized expertise in UI architecture. The company I’m working for…I don’t even think they know what an MVP is. They hired me because they know *me* and know I can help them with their particular problem. I would say the personal career benefits of having an MVP are a wash except…

With Microsoft’s less than above the bar treatment and communication about Silverlight over the last year or so, you might imagine this could effect MVPs associated with the program. I’ve heard a lot of horrible stories in the last year. I didn’t have anything terribly bad happen to my business, but I was quite embarrassed recently. I was attending a .NET user group meeting, of which I am the president. Somehow I or someone else mentioned that I was a Silverlight MVP. I don’t remember the detail about how it came up, but I do remember what happened next. Someone laughed at me. Literally, I was made fun of because my MVP had the word Silverlight attached to it. Now, I’m just not willing to endure mockery for the sake of Silverlight, especially since I understood exactly why he was laughing at me. It has got to where being a “Silverlight” MVP is bad for my career.

My Happiness

Looking over the last three years, I’ve definitely been a less happy, more frustrated developer. I’m sure it’s linked to the sort of fake “value” being a Silverlight MVP gave me. Basically, they give you a couple of cheep gifts, then they pretend to listen to your feedback, while not actually doing anything. Year after year of that and you get really unhappy. It’s demoralizing. You start to realize that you really are a commodity. You are purchased by a product group and kept around as long as they perceive they need you…your feedback is allowed, but not effective. Again, it’s probably not the case for all MVPs, it depends on the groups. I just don’t need that in my life.

Conclusion

I’m saying goodbye to the MVP program even after I was re-offered the award for 2012. If you’ve read this far, you can probably see why I made that decision. I’m really positive about the future of Caliburn.Micro and hopeful regarding my JavaScript framework. I think 2012 is going to be a wonderful year. If someone seriously reforms the MVP program or if Microsoft decides to properly recognize and reward open source efforts, then, maybe I’ll let them give me an award. But for now, I don’t need to suffer any more. I’m free and I’m going to do great things.

More Posts Next page »