Tuesday, January 19, 2010

Silverlight DataAnnotations.Validator is not thread safe

 

I got this exception when using the Validator class with Silverlight. And yes, there is a property called ‘AProperty’ on the instance being validated :)

The type 'ClassWithValidatedProperty' does not contain a public property named 'AProperty'.
Parameter name: propertyName

at System.ComponentModel.DataAnnotations.ValidationAttributeStore.TypeStoreItem.GetPropertyStoreItem(String propertyName)
at System.ComponentModel.DataAnnotations.ValidationAttributeStore.GetPropertyType(ValidationContext validationContext)
at System.ComponentModel.DataAnnotations.Validator.ValidateProperty(Object value, ValidationContext validationContext)
at SilverlightValidationRepro.ClassWithValidatedProperty.set_AProperty(String value)
at SilverlightValidationRepro.ValidatorNotThreadSafeReproduction.<Should_be_able_to_validate_concurrently>b__1()

The exception occured only once in a while, so we suspected threading issues. However, the MSDN docs say that Any public static (Shared in Visual Basic) members of this type are thread safe. Then take a look at the following test. It reproduces with the exception above, effectively proving a concurrency bug.

TheTest

Now take a look at the following screen shot from reflector. Can you spot the threading bug? Hint: the ‘return false’ should not happen in our case.

ValidatorThreading

Oh, and the workaround is to not consider the Validator class thread safe. We dispatch the code to a single thread. Another workaround would be to ensure that the Validator is finished with its initialization phase before unleasing multiple threads on it.

Sunday, October 25, 2009

Missing Mime Types option in IIS

I’ve been playing around with Silverlight 3 recently and until just now I’ve used the Visual Studio Development Server to run and debug the code. But when I changed to using IIS I got the following error when starting the application:

Error: Unhandled Error in Silverlight
Application Code: 2103
Category: InitializeError
Message: Invalid or malformed application: Check manifest

Google gave me several suggestions. One of them was to add the correct MIME types. However, the IIS Manager didn’t provide the “MIME Types” option to let me add them:

missing_mime_option

After feeling a bit puzzled I figured out that I could enable the “MIME Types” option by turning on “Static Content” in “Turn windows features on or off”:

how_to_enable_mime_types

The option appeared in the IIS Manager and it was allready configured with the needed MIME type for Silverlight apps. Problem solved.

Monday, October 6, 2008

Undo Pending Changes in TFS

When working with TFS in Visual Studio and it’s time to do the check-in-dance, I usually browse through the pending changes to make sure I haven’t done anything stupid (which is the case more often that I’d like to believe). During that phase, files that are unchanged despite that they’re checked out are really annoying. I’m certainly not the first to blog about this, but I’ve met several fellow programmers that were unaware of the power of the Team Foundation Server Power Tools – Command Line Tool, so I figured I might as well try my best to “spread the word”. At my current project we have a .bat file in the quick launch area that does the following:

cd C:\project\workspace\folder
tfpt.exe uu /noget
pause

After navigating to the workspace root folder, we invoke the tfpt.exe command line, which will notify you of unchanged checked out files and kindly ask you if you’d like to undo the check out. Confirm, then hit the "refresh” button in Visual Studio’s "pending changed” window.

Monday, September 22, 2008

I Notify Property Changes with Boo

It's now official. I've spend to much time of my life pondering about INotifyPropertyChanged. I've went from the naive
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs("Name"));
}

to using helper methods like
FirePropertyChanged(MethodBase.GetCurrentMethod());

and even to more obscure helper methods this one (Relax, I've never used something like this in production):


MethodImpl(MethodImplOptions.NoInlining)]
protected void FirePropertyChanged()
{
var v = new StackFrame(1);
var name = v.GetMethod().Name.Substring(4);
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(name));
}
}



The best C# alternative I've come across to this point is the extension method found in the Umbrella project:


this.Notify(PropertyChanged, p => p.SomeProperty);

The implementation is rather neat, just take a look.


Better with Boo?

So, can we do better? I was recently introduced to Boo by a collegue, Tore Vestues. He showed how to auto-generate that boiler-plate code that goes into every property setter that needs to fire off PropertyChanged events. Simply mark the class with a [PropertyChanged] attribute and some fancy stuff happens compile time (you'll have to write that fancy stuff yourself, though). I like the approach alot, as it keeps your code cleaner. Combined with another property, [ExpandFields] that turns public fields into properties with backing fields, it gets even better. I wont go into details here and let Tore blog about it himself.


Based on the concepts he showed, I saw a nice opportunity to solve a little problem that has bothered me. It's been discussed over beer more than once, and no-one has ever managed to provide a truly good approach. Consider the following simple example:


class Presenter:

public Original as string

Dependant as string:
get:
return "Hello, ${Original}"

EventMoreDependant as string:
get:
return "${Dependant}, how are you?"



We have a field, Original, that has two properties that depend on its value. Wouldn't it be nice if changes to the field would fire off PropertyChanged events for all its dependants? The way I would handle changes to the Original field in C# is to change it into a property with a backing field. Then I'd add code to fire off the two PropertyChangedEvents.


For simple classes, I don't have a problem with that, but for more complex cases it becomes a chore to remember to fire PropertyChanged event from all the properties a certain property might depend on. And it's certainly not SoC.



So what's the point of this post anyway?

That's too much fluff before getting to the point, sorry about that. The point is, that by adding two attributes (ExpandFields, PropertyChanged) to the class, two things happen. First, all public field are converted into public properties with backing fields. Then, code is added to each property setter to fire off PropertyChanged events for all other properties that depend on it. Hard to explain, luckily Reflector does a better job at it:





And the unit test that confirms that it works:



[Test]
public void Original_WhenChanged_ShouldFirePropertyChangedForItselfAndDependants()
{
var presenter = new Presenter();

var set = new HashSet<string>();
presenter.PropertyChanged += (o, e) => set.Add(e.PropertyName);

presenter.Original = "Lars Andreas";

Assert.That(set.Contains("Original"));
Assert.That(set.Contains("Dependant"));
Assert.That(set.Contains("EventMoreDependant"));
}


If there's an interest, I'll clean up the code and put it out here. Boo is kinda cool :)

Debugging the compilation of Boo code

If you have non-trivial code that's supposed to run during the compilation Boo code (read: macros, attributes, and so on), its safe to assume that you might need to debug it when if it doesn't work the way you thought it would. Sure, the code should be covered by unit-tests, but hey, sometimes there's nothing like a good'ol debugging session ;)

One of the first questions I asked when introduced to Boo was exactly that. How can I debug my own code when that code is executed during the compilation of... err... some other of my own code? Last time I checked, there's no "Compile this code in debug mode" button anywhere.

Turns out, as a last resort, you can place a Debugger.Launch() somewhere in the code that's run compile-time. When the Debugger.Launch()is discovered during the compilation, you'll be asked to start a debug session with Visual Studio. Just remember to remove the Debugger.Launch()call afterwords :)

I'll bet the über-boo-hero himself has a much better solution, though.

Sunday, September 21, 2008

ClickOnce, Nant and Multiple Configurations

So. My first post that's NOT about troubleshooting unit testing. 'bout time, huh :) This post is about deploying applications using ClickOnce. On my current project we used to deploy the application to a network share using the 'publish' functionality in Visual Studio. It works, but there are several problems with this approach. A better idea is to deploy the application from the build server. I wont delve into the arguments, as they'are all out there. This meant extending our current build script somewhat.

We deploy a test version of the application fairly often. Obviously, it needs to be configured differently than the production version. The first differences that came to mind in our scenario was connection strings, web service URLs and the title of the main window (to make clear whether the program is the test or production version). Also, a requirement for the deployments was that users could install both the production and test version of the program side by side on the same machine. Because of that there was a few more subtle things that needed to be handled. I struggled a bit few these when creating the build script, so I write this post alot for my own reference.


Nant + ClickOnce + msbuild

Each build is scripted using Nant and produces two deployable releases of the software (inspired by these posts by Kyle). The following Nant task can be used to invoke the msbuild 'publish' target for the project in question. The 'PublishDir' property is used to control where the resulting files should be put.


<msbuild project="${project.file}">
<arg value="/t:publish" />
<arg value="/p:PublishDir=${current.release.dir}\" />
</msbuild>

I actually provide a few more properties to msbuild, but I'll get back to that.


Multiple Configurations

I mentioned that the two versions need different configurations. The stuff that's in app.config are easily changed using Nant's xmlpoke task, but there's an important point here. Changes to any file in the clickonce deployment must be performed BEFORE the manifests are signed, or else the installation will fail. I found two options at this point. Either store a single copy of all the relevant files on disk until it's time for deployment and perform app.config changes and manifest generations on the fly using mage.exe. Or the second option, which I chose (dont't ask why), which is to generate and store two clickonce packages, both by using msbuild, but with different app.configs.


Side by side installation

The more subtle issues that i struggled with appeared when trying to install the two versions side by side on the same machine. Turns out, that the assembly names of the two versions must differ. If my application has an entry point assembly called MyApplication.exe, I had to name the test version something else. If I didn't, ClickOnce would overwrite the production version when I installed the one for test. You can tell msbuild what you want the output assembly to be called by providing a value for the 'AssemblyName' property like this:


<msbuild project="${project.file}">
<arg value="/t:publish" />
<arg value="/p:PublishDir=${current.release.dir}\;AssemblyName=${assemblyname}" />
</msbuild>

That only works if the application lives in a solution by itself, because now all the projects in the solution will get the same assembly name. I got around that issue by putting a conditional PropertyGroup inside the MyApplication.csproj file:



<PropertyGroup Condition=" '$(AssemblyNameOverride)' != '' ">
<AssemblyName>$(AssemblyNameOverride)</AssemblyName>
</PropertyGroup>

Combined with providing the AssemblyNameOverride property to msbuild instead of AssemblyName like before, only the correct assembly changes name:



<msbuild project="${project.file}">
<arg value="/t:publish" />
<arg value="/p:PublishDir=${current.release.dir}\;AssemblyNameOverride=${assemblyname}" />
</msbuild>

Now the two versions can be installed side by side without overwriting each other, except that they still overwrite each other's start menu shortcuts. To avoid that I provide the ProductName property as well. I also use the PublishUrl property to tell where to look for updates. The final msbuild task looks like this:



<msbuild project="${project.file}">
<arg value="/t:publish" />
<arg value="/p:AssemblyNameOverride=${assemblyname};PublishUrl=${clickonce.url};PublishDir=${current.release.dir}\;Configuration=Release;ApplicationVersion=${CCNetLabel};UpdateRequired=true;ProductName=${clickonce.productName}" />
</msbuild>

Conclusion


It's better to deploy stuff from the build server than from developer workstations. You can use Nant (or other build tools) to generate builds for different environments, but when using ClickOnce a few steps need to be taken. I hope this post saves someone some time, as I spent quite a while figuring this stuff out :)

UPDATE: You can download a simple example here. You need to set up some shared folder on your computer to try it out (I haven't found a way to clickonce deploy to a local folder).

Thursday, September 4, 2008

xUnit and ReSharper 4.1

I'm currently reading some of the code in the Umbrella project, and wanted to run some of the xUnit tests using the unit test runner in Resharper 4.1 (yes it's out:).

To be able to do that you must install the Resharper plugin that comes with the xUnit download (by executing xunit.installer.exe). Current, the installer does not recognize Resharper versions other than 4.0, so I was on my own.

Fortunately, this fella had a solution that worked great (but use the registry key that corresponds to your VS and R# installations).