Jul 16 2009

CodeDom does not support the ConditionalAttribute

Category: .NetRory Primrose @ 06:31

I need to output some debug statements from a PolicyActivity as I’m having some issues with running a workflow from a unit test. Adding some Debug.WriteLine statements to the rule set seems like a good idea given that I am not getting the WF designer step through experience from MSTest. I thought about whether CodeDom checks for the Conditional attribute before it invokes a method.

CodeDom evaluates the xml rules and executes the instructions in C#. At compile time, native C# is striped of any method call that is decorated with a ConditionalAttribute that does not match the additional compilation symbols of the build configuration. For example, the Debug.WriteLine statement is decorated with Conditional(“Debug”) attribute so any calls to this method in a typical Release build configuration will get stripped out as the Debug compilation symbol is not defined. What about CodeDom though?

As expected, CodeDom does not check the ConditionalAttribute marker on methods it invokes. As such, debugging methods are evaluated and invoked at runtime regardless of the build configuration.

Tags:

Jul 13 2009

ActivityValidator passes compiler but fails in designer

Category: .NetRory Primrose @ 06:11

I have a custom WF activity that uses a type converter to convert from a source object to a destination object. I added an ActivityValidator to the activity to check that the TypeConverterType property specified to use for the conversion derives from TypeConverter.

The code originally looked like the following.

if (converterActivity.TypeConverterType != null) 
{ 
    // The type must be a type converter 
    if (typeof(TypeConverter).IsAssignableFrom(converterActivity.TypeConverterType) == false) 
    { 
        errors.Add(new ValidationError("Property 'TypeConverterType' is not a TypeConverter", TypeConverterTypeIsInvalidId));   
    } 
}

The compiler successfully passed the validation and the workflow designer that used the activity was clear of any error indicators. If I rebuild the solution then the compiler would still pass but now the workflow designer indicated the error condition from the above code. After adding other validation errors into the designer for debugging there didn’t seem to be a good reason why the Type.IsAssignableFrom method should fail. The TypeConverterType property value was a type that derived from TypeConverter. With no other options, the code was changed to the following:

if (converterActivity.TypeConverterType != null) 
{ 
    // Rebuilds of the solution will cause this error to be added 
    // The Type.IsAssignableFrom check passes the compiler but the designer still seems to fail the check 
    // We need to manually check the inheritance chain of the type converter type 
    Boolean converterFound = false; 

    for (Type converterType = converterActivity.TypeConverterType; converterType != null; converterType = converterType.BaseType ) 
    { 
        if (converterType.Equals(typeof(TypeConverter))) 
        { 
            converterFound = true; 

            break; 
        } 
    } 

    // The type must be a type converter 
    if (converterFound == false) 
    { 
        errors.Add( 
            new ValidationError( 
                "Property 'TypeConverterType' is not a TypeConverter", 
                TypeConverterTypeIsInvalidId, 
                false, 
                TypeConverterActivity.TypeConverterTypeProperty.Name)); 
    } 
}

This now works for the compiler and the workflow designer.

Tags:

Jul 12 2009

Neovolve ReSharper Plugins 1.1 Released

Category: My SoftwareRory Primrose @ 18:10

I have just released a new version of ReSharper Plugins. This version updates the identification and conversion of value types in cref xml documentation references and now supports ReSharper 4.5

Get the goods here.

Tags:

Jul 9 2009

Unit testing WF with InternalsVisibleTo

Category: .NetRory Primrose @ 11:16

I hit an interesting situation the other day. I had a WF library that I wanted to unit test and I had to add workflows to the unit test assembly to be able to test some of the activities. The unit test project template doesn’t support WF but this is easily fixed by hacking the project file. The assemblies were strong named and there were some internal classes that I was also testing using the InternalsVisibleTo attribute.

All of a sudden the compiler complains that the unit test assembly isn’t signed and the InternalsVisibleTo attribute is not valid. The compiler message clearly indicates that the unit test assembly has not been signed and has null public token. The compiler error looks like this:

Friend access was granted to 'MyAssembly.UnitTests, PublicKey=0024000004800000940000000945000000240000525341310004000001000100E5D06B6A34E0EBE7386CA8C177B3EEDA66802357F74D8F5D419BF3623C9CE4F7EF2D9081418529E63A6B4C287C3941E1113543C7AF93E1ABE96A1511B3ED3B93F36DB193146BDC932EDB2A03C3CF511C1A798FF3130AD9ABB5044E1F67049878D3CE4686A2E3E5EEA3A098B71778CD8B73651CD5AFC320CDC4F315F7666659B5', but the output assembly is named 'MyAssembly.UnitTests, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. Try adding a reference to 'MyAssembly.UnitTests, PublicKey=0024000004800000940000000945000000240000525341310004000001000100E5D06B6A34E0EBE7386CA8C177B3EEDA66802357F74D8F5D419BF3623C9CE4F7EF2D9081418529E63A6B4C287C3941E1113543C7AF93E1ABE96A1511B3ED3B93F36DB193146BDC932EDB2A03C3CF511C1A798FF3130AD9ABB5044E1F67049878D3CE4686A2E3E5EEA3A098B71778CD8B73651CD5AFC320CDC4F315F7666659B5' or changing the output assembly name to match.

I checked and rechecked the signing configuration for the unit test assembly and tried various other actions to try and get a successful compilation. Nothing would work. I figured this was some weird incompatibility with hacking the unit test assembly to also support WF (which is actually partially correct). I had to split my source and unit test projects into projects that contain WF and projects that don’t.

I just hit the same problem again today at work. After a bit of Googling I came up with this Connect issue. What it boils down to is that Microsoft don’t adequately handle signing assemblies when compiling WF assemblies such that the InternalsVisibleTo attribute fails. The workaround suggested is to the use old AssemblyKeyFile attribute and uncheck “Sign the assembly” in the project properties.

I also configure my projects to treat warnings as errors. The compiler then complained with the following error:

Warning as Error: Use command line option '/keyfile' or appropriate project settings instead of 'AssemblyKeyFile'    [AssemblyPath]\Properties\AssemblyInfo.cs

The AssemblyKeyFile attribute is essentially depreciated and its use throws a compiler warning. With treat warnings as errors set, this is now a compiler error. The way around this is to put a warning suppression for 1699 into the project settings. This needs to be done for all build configurations.

Project settings now look this this.

image

Problem solved.

Tags: ,