A Brief Introduction to Error Logging Modules And Handlers (ELMAH)

Overview
ELMAH is an open source project used to add error logging capabilities to an ASP.NET Web application. ELMAH essentially provides a means for logging and reporting unhandled exceptions in applications. I came across this very nifty tool while working with the MASS LEG team to create the Legislative Automated Workflow System (LAWS) application for […]

FabrikamShipping sample updated to include Access Control December CTP Release

Check out the latest updates to the FabrikamShipping SaaS sample application. This sample provides a great example on how the Access Control service helps solve real-life identity federation requirements.

You can find more details in Vittorio Bertocci’s blog post.

If you want to learn more on the Access Control service please visit our website or the MSDN developers website.

If you haven’t started checking out Windows Azure AppFabric already make sure to take advantage of our free trial offer. Click the link below and get started!

As always, feel free to leave us feedback on the comments section of this blog.

Apprenticeship : A Journey Begins

Writing great software is an immense joy in my life.  I truly enjoy working with business users and other developers to craft software which can make a marked and immediate difference for a business, something that presents real value.  There isn’t a lot of rocket science here, it goes to the fundamental desire of all humans to make a difference in our world.

Fortunately for those who are looking for ways to do so, our world is full of situations that need to be adjusted.  One of them, with all due respect to those in our industry who cling to their cherished degrees from universities, is that you do not need a four year degree to craft great software.  Now certainly we all know people who have been successful without a traditional education, in fact you’re reading the blog of one right now.  And I will be the first to tell anyone leaving High School that a four year degree is your most certain path to success in software development.  But for some, that ship has sailed.

For some, the reality of life is such that leaving work is beyond their reach because of the need to support themselves.  One such person as this is Christopher Jackson, a good friend of mine that has exceptional analytic skills but who also finds himself functionally unemployed currently, having lost his last job to a downsize from the economy, he now acts as a substitute teacher in the Fort Worth Independent School District for the incredible sum of $73 dollars per day.  Compare that to the average salary for an entry level developer, approximately $56K/year, and I believe you will agree that cultivating his interest into a marketable skill set should have an impact on his life.  Chris has always had an interest in writing software, but it is hard to find time to go back to school while working.

As such, Chris and I have come to arrangement, one that is an experiment for me but which I firmly believe in.  Effective today, January 9th 2011, Chris has begun an unpaid internship with my company TimRayburn.net LLC which puts on Dallas TechFest and other projects of mine.  During the internship, he will be working with me to increase his basic skills in development, and learn how to craft software from the ground up.  Initially, he will be working on assignments with little real-world application, but eventually he will be assisting me on actual projects that deliver real world value.  As I’m sure some will be curious on how I have structured this plan, I will lay out at a high level what is involved:

  • A commitment to dedicate time to the effort.  Chris will be spending time with my at least three days a week for multiple hours.
  • A commitment from his spouse to support him in this effort.  Chris is newly married, and his spouse needs to be on board if he is to have the support he will need at home.
  • A time boxed commitment, for us initially of six months.  This will allow Chris to commit, while also knowing that it has an end point, and that if he chooses to continue than changes can occur at that time.
  • A penalty for not meeting the commitment.  The details of which will not be public, but which are notable enough to impact his life should he decide to walk away from the commitment.
  • A reasonable third party arbiter, trusted by both myself and Chris who will be able to settle any disagreements around the penalty should that need arise.  My wife Kate will be serving that role, which for Chris and I who have been friends for over 15 years is agreeable.

I do not know how this will go, but I am certain it will generate blog posts as I learn while I teach.  Any suggestions?

 

Average Entry Level Developer Salaries in Arlington, TX

entry level developer

$56,000

 

BizTalk: Next Hotrod issue available

I hope you’ve all been well over the break and enjoying the ’thinking time’ – I’ve
been keeping one ear to the ground and just on the lookout for new bits. Here’s one.

The BizTalk team have been busily working hard over the break and produced another
issue of BizTalk at it’s best – BizTalk Hotrod.

http://biztalkhotrod.com/Documents/BizTalkHotrod11_Q4_2010.pdf

 

Specifically this issues talks about:

  • Async communication with BizTalk across WCF-Duplex messaging.

  • Calling SAP RFCs from BizTalk – all you need to know.

Guys – the biztalk hotrod mag set is some of the best technical biztalk discussions
around, grab the previous issues and add them to your internal networks. A must.

Enjoy and talk to you soon.

Mick.

WF4 Activity Versioning Solution

In my last post I showed you how the _XamlStaticHelper class uses different semantics when loading assemblies referenced by XAML files.

Today I’m going to show you a solution I’ve built into the Microsoft.Activities library that can help you apply standard CLR behavior when loading referenced assemblies.

Strict Assembly Resolution for Compiled Workflows

Step 1: Download and reference Microsoft.Activities.dll

Download the latest version

Step 2: Create a partial class definition for your compiled workflow

In my example project, I have a compiled workflow named WorkflowCompiled.xaml.  I have added a partial class with the same name and .cs extension

Step 3: Create a ReferencedAssemblies static property in your partial class

Add the FullName of any assemblies that you are referencing from your XAML

/// <summary>
///   Gets the referenced assemblies.
/// </summary>
/// <remarks>
/// The XamlAppDef build task generates a list of referenced assemblies automatically in the (XamlName).g.cs file 
/// You can find the list of assemblies and version that need to be referenced there.
/// This property returns a simple string list of the assemblies that will cause them to be loaded using the 
/// standard Assembly.Load method
/// </remarks>
public static IList<string> ReferencedAssemblies
{
    get
    {
        // Create a list of activities you want to reference here
        var list = new List<string> {
                "ActivityLibrary1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=c18b97d2d48a43ab", 
            };

        // Add the standard list of references
        list.AddRange(StrictXamlHelper.StandardReferencedAssemblies);
        return list;
    }
}

Step 4: Create a Constructor in your partial class with a XamlAssemblyResolutionOption argument

The default constructor in your partial class will use the loose assembly loading behavior.  You must supply an alternate constructor to get the strict behavior

/// <summary>
/// Initializes a new instance of the <see cref="WorkflowCompiled"/> class.
/// </summary>
/// <param name="assemblyResolutionOption">
/// The assembly Resolution Option.
/// </param>
public WorkflowCompiled(XamlAssemblyResolutionOption assemblyResolutionOption)
{
    switch (assemblyResolutionOption)
    {
        case XamlAssemblyResolutionOption.Loose:
            this.InitializeComponent();
            break;
        case XamlAssemblyResolutionOption.Strict:
            StrictXamlHelper.InitializeComponent(this, this.FindResource(), ReferencedAssemblies);
            break;
        default:
            throw new ArgumentOutOfRangeException("assemblyResolutionOption");
    }
}

Step 5: Construct your workflow using the new constructor passing XamlAssemblyResolutionOption.Strict

WorkflowInvoker.Invoke(new WorkflowCompiled(XamlAssemblyResolutionOption.Strict));

Result

Your compiled workflow will now behave like any other CLR object and construct successfully if and only if it can resolve the specific version of all referenced assemblies.  If it cannot locate the assembly file it will throw a FileNotFoundException and if it can locate the file but it is not the correct version or public key token it will throw a FileLoadException.

Strict Assembly Resolution for Loose XAML

Loose XAML is an activity loaded from a XAML file using ActivityXamlServices.Load().  Unless the XAML file has FullName references (which it does not by default) ActivityXamlServices.Load will load with a partial name.  This means it could load any assembly it finds with a matching name without regard to the version or public key token.

There are two ways to fix this. 

  1. You can use the <qualifiedAssembly>configuration element to specify the FullName of the assembly you want to use
  2. Use Microsoft.Activities.StrictXamlHelper.ActivityLoad()

Step 1: Download and reference Microsoft.Activities.dll

Download the latest version

Step 2: Create a list of referenced assemblies

public static IList<string> GetWorkflowLooseReferencedAssemblies()
{
    // Create a list of activities you want to reference here
    var list = new List<string> { "ActivityLibrary1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=c18b97d2d48a43ab", };

    // Add the standard list of references
    list.AddRange(StrictXamlHelper.StandardReferencedAssemblies);
    return list;
}

Step 3: Load the activity using StrictXamlHelper.ActivityLoad()

// This will ensure the correct assemblies are loaded prior to loading loose XAML
var activity = StrictXamlHelper.ActivityLoad(
    "WorkflowLoose.xaml", GetWorkflowLooseReferencedAssemblies());
WorkflowInvoker.Invoke(activity);

Summary

Loading the correct version of a referenced assembly is vital.  The default behavior of both compiled workflows and loading loose XAML may result in unexpected behavior due to loading a newer version of the referenced assembly.

I recommend that you use StrictXamlHelper to ensure that you load the expected version of referenced assemblies.

WF4 Spike: Activity Versioning, GAC and Loose XAML

A spike is a short project where you investigate how something works and report back to the team with your results.

For this spike I want to answer the following questions

  • What happens when a V1 workflow loads a V2 activity?
  • What happens when a V2 workflow cannot find a V2 activity but a V1 activity is available?
  • What difference if any does it make if the activity is deployed in the GAC?
  • What difference does it make if you use Compiled or Loose XAML

I will run through a number of scenarios with various options. For each scenario the format is Activity (version), Host (version), Deploy (option), XAML option (which one runs first)

Deployment options
Application Base Deploy the activity assembly to the same directory as the workflow application
GAC Deploy the activity assembly in the GAC
XAML options
Compiled XAML A .XAML file that has a XamlAppDef build task in Visual Studio and is deployed in the assembly – this is the default setting for XAML
Loose XAML .XAML file that is deployed as a file and loaded by ActivityXamlServices.Load
Project artifacts
Host XamlAssemblyResolution.exe Workflow Console Application with WorkflowCompiled.xaml and WorkflowLoose.xaml
Activity AcvitityLibrary1.dll Contains a custom activity named GetTypeInfo

Scenario 1: Activity V1, Host V1, Deploy Application Base, Compiled/Loose

Expected: Both Compiled and Loose should use V1

Scenario 2: Activity V1, Host V1, Deploy GAC (V1), Compiled/Loose

Expected: Both Compiled and Loose should use V1 from the GAC even though the Activity DLL is in the Application Base

Actual: The activity was loaded from the GAC.  For more info see How the Runtime Locates Assemblies.

Scenario 3: Activity V2, Host V1, Deploy Application Base, Loose

Expected: Activity V1 from the GAC will be used for both loose and compiled

Actual: Not Expected! When you run the Loose XAML first, it will load V2 from the file and the Compiled XAML will load V1. 
Why does Loose XAML load a different activity version when run before compiled XAML?

Scenario 4: Activity V2, Host V1, Deploy Application Base, Compiled

Expected: Activity V1 from the GAC will be used for both loose and compiled

Actual: Behaves as expected

Scenario 5: Activity V2, Host V1, Deploy GAC (V1/V2), Loose

Expected: Activity V1 from the GAC will be used for both loose and compiled because the host was built for V1

Actual: Not Expected! When you run the Loose XAML first, it will load V2 from the GAC and the Compiled XAML will load V1. 
Why does Loose XAML load a different activity version when run before compiled XAML?

Scenario 6: Activity V2, Host V1, Deploy GAC (V1/V2), Compiled

Expected: Activity V1 from the GAC will be used for both loose and compiled because the host was built for V1

Actual: Behaves as expected

Scenario 7: Activity V2, Host V1, Deploy GAC (V2), Loose/Compiled

Expected: Compiled and Loose will fail because V1 is not available

Actual: Not Expected! Both Compiled and Loose loaded V2 from the GAC even though they were not built for V2 of the activity 
Why do both Compiled and Loose XAML load versions of the activity than what they were built with?

Scenario 8: Activity V2, Host V1, Deploy Application Base, Loose/Compiled

Expected: Compiled and Loose will fail because V1 is not available

Actual: Not Expected! Both Compiled and Loose loaded V2 from the application base
Why do both Compiled and Loose XAML load versions of the activity than what they were built with?

Scenario 9: Activity V1, Host V2, Deploy Application Base, Loose/Compiled

Expected: Compiled and Loose will fail because V2 is not available

Actual: Not Expected! Both Compiled and Loose loaded V1 from the application base
Why do both Compiled and Loose XAML load versions of the activity than what they were built with?

Scenario 10: Activity V1, Host V2, Deploy GAC (V1), Loose/Compiled

Expected: Compiled and Loose will fail because V2 is not available

Actual: Not Expected! Both Compiled and Loose loaded V1 from the GAC
Why do both Compiled and Loose XAML load versions of the activity than what they were built with?

Scenario 11: Activity V1/V2, Host V2, Deploy GAC (V2), Application Base (V1), Compiled

Expected: Workflow will run V2 from GAC

Actual: Compiled and Loose loaded V2 from the GAC as expected when Compiled ran first

Scenario 12: Activity V1/V2, Host V2, Deploy GAC (V2), Application Base (V1), Loose

Expected: Workflow will run V2 from GAC

Actual: Not Expected! Loose loaded V1 from Application Base and Compiled loaded V2 from the GAC
Why do both Compiled and Loose XAML load versions of the activity than what they were built with?

Investigations

Why does Loose XAML load a different activity version when run before compiled XAML?

A: Because the generated class _XamlStaticHelper specifically tried to load the version that was referenced at compile time.

When you look at the activity assembly reference in XAML you will see that it does not include the version or public key token

xmlns:a="clr-namespace:ActivityLibrary1;assembly=ActivityLibrary1"

How does the version get referenced in compiled XAML? 

The XamlAppDef build task will generate a file that creates a class which represents the compiled workflow.  My workflow is WorkflowCompiled.xaml so the generated file (located under obj\x86) is WorkflowCompiled.g.cs.  Contained in that file is a line of code that reveals where the XAML comes from

System.IO.Stream initializeXaml = typeof(WorkflowCompiled).Assembly.GetManifestResourceStream(resourceName);

When this class reads the XAML it uses a XamlSchemaContext to help it interpret the XAML and it gets the context from a generated class called _XamlStaticHelper.  Here is the line of code.

System.Xaml.XamlSchemaContext schemaContext = XamlStaticHelperNamespace._XamlStaticHelper.SchemaContext;

So what?  Well if we open the host assembly with Reflector and look at the _XamlStaticHelper.SchemaContext property we can see what is going on

if (AssemblyList.Count > 0)
{
   target = new XamlSchemaContext(AssemblyList);
}

There is an AssemblyList property! And what does it contain? We see from the LoadAssemblies method that the XamlAppDef build task has generated a fully qualified reference to ActivityLibrary1 (version 1)

private static IList LoadAssemblies()
{
    IList list = new List();
    list.Add(Load("ActivityLibrary1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=c18b97d2d48a43ab"));
    // (a bunch of other assemblies here)
    list.Add(Assembly.GetExecutingAssembly());
    return list;
}

Because this code is generated at build time, the Compiled XAML will first try to load the specific version of the activity it was created with.

Why do both Compiled and Loose XAML load versions of the activity than what they were built with?

In spite of the fact that the compiled host assembly specifies a version of the activity library should be loaded; our testing shows that a compiled will load older or newer versions of the activity if the specific version is not available, and loose XAML will load any assembly with a matching name (even one that does not have a strong name).

The _XamlStaticHelper.Load() method is the reason why this happens

private static Assembly Load(string assemblyNameVal)
{
    AssemblyName name = new AssemblyName(assemblyNameVal);
    byte[] publicKeyToken = name.GetPublicKeyToken();
    try
    {
        return Assembly.Load(name.FullName);
    }
    catch (Exception)
    {
        AssemblyName assemblyRef = new AssemblyName(name.Name);
        if (publicKeyToken != null)
        {
            assemblyRef.SetPublicKeyToken(publicKeyToken);
        }
        return Assembly.Load(assemblyRef);
    }
}

It first tries to load the assembly using the full name and if that fails it catches the exception and tries to load it with the name and public key token but no version.  This is different than the typical CLR behavior which requires a specific version match.

Summary

To wrap this up I have to say be careful.  WF4 workflows do not follow the same rules for assembly versioning that you might expect. 

  • Compiled XAML will try to load the specified version if available.  If not, they will do a version independent load but will respect the PublicKeyToken so they won’t load assemblies with the wrong signature
  • Loose XAML will load any matching assembly based on name alone with no respect for version or public key token.  If the AppDomain has previously loaded the type from some other mechanism (CLR or XAML) then the Loose XAML will always load the type previously loaded.
  • If you have to use Loose XAML and you want to be sure that you are loading a type of a certain version and/or PublicKeyToken you could use some code with a CLR reference to those types to cause the types to load into the AppDomain prior to calling ActivityXamlServices.Load