# Friday, 12 February 2010

We just caught this one this morning…  It looks like WF 4 reuses activity instances across workflow instances.  So if I have a WorkflowService that’s hosted in IIS, and I call it from two different client threads at the same time, the two workflow instances now running on the server may be using the same activity instances for child activities.  The documentation is not clear on this point, but that’s the behavior we observed. 

The implication is that you have to treat calls to your Activity’s Execute method as stateless, and not maintain any state in your activity between calls to Execute.  (Our specific problem was around EntityFramework containers.  Apparently they don’t like being called on multiple threads. :) )

Makes sense, but it’s not clear at all from the documentation that it would be the case.  You can rely on the thread safety of your InArguments and OutArguments, since they are accessed through the context, but private fields are right out unless whatever you store in them is also threadsafe.

Friday, 12 February 2010 11:14:40 (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [0]  | 
# Wednesday, 10 February 2010

This is probably one of those things that is obvious to everyone but me, but just in case it’s not…

We’re using Unity as our IoC container, and we are also using .NET 4 Workflow Services hosted in IIS, meaning .xamlx files that are served up by IIS 7.  In order to get full value out of Unity, we need one instance of the Unity container that gets properly configured somewhere that is then available to any WF activity that might need to resolve a reference.  But…since IIS is hosting, there’s no direct access to the WorkflowServiceHost to add the Unity container as an extension (which is how we do it in places where we are hosting using WorkflowApplication in WPF apps, etc.).  I suspected that the solution was a WCF Service Behavior extension, because that’s how you set up a tracking participant if you are hosted in IIS, and luckily that turned out to be the case.  I’d been putting off nailing it down because I suspected it was hard, but as luck would have it (or, rather, the cleverness of the ServiceModel team) it’s not hard at all.

First, we need a behavior extension that creates (and ultimately configures) the Unity container.  It has to implement IServiceBehavior, since we need it to be a service behavior to get access to the host.

public class UnityServiceBehavior : IServiceBehavior
{

    #region IServiceBehavior Members

    public void AddBindingParameters(ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase, System.Collections.ObjectModel.Collection<ServiceEndpoint> endpoints, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
    {
        
    }

    public void ApplyDispatchBehavior(ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase)
    {
         WorkflowServiceHost host = serviceHostBase as WorkflowServiceHost;
         if (host != null)
         {
             IUnityContainer container = new UnityContainer();
             host.WorkflowExtensions.Add<IUnityContainer>(delegate { return container; });
         }
   
    }

    public void Validate(ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase)
    {
        
    }

    #endregion
}
Secondly, we want it to be configurable through web.config, which calls for a BehaviorExtensionElement. 
public class UnityBehaviorElementExtension : BehaviorExtensionElement
{
    public override Type BehaviorType
    {
        get { return typeof(UnityServiceBehavior); }
    }

    protected override object CreateBehavior()
    {
        return new UnityServiceBehavior();
    }
}

Then, in our web.config, just register the extension, which in turn will configure and return behavior.

<system.serviceModel>
  <behaviors>
    <serviceBehaviors>
      <behavior>
        <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
        <serviceMetadata httpGetEnabled="true"/>
        <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
        <serviceDebug includeExceptionDetailInFaults="false"/>
        <unityExtension/>
      </behavior>
    </serviceBehaviors>
  </behaviors>
  <extensions>
    <behaviorExtensions>
      <add name="unityExtension" type="UnityBehavior.UnityBehaviorElementExtension, UnityBehavior, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
    </behaviorExtensions>
  </extensions>
  <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>

In this case, the fact that the behavior element doesn’t include a name means the set of behaviors it contains will be applied to any WCF service that is relying on the default configuration (one of the coolest things in .NET 4!) which is how our .xamlx file works in this example.

Once all that’s done, from any activity in my .xamlx workflow I can access the IUnityContainer interface as an extension.

public sealed class CheckForUnity : CodeActivity
{
    // Define an activity input argument of type string
    public OutArgument<bool> HasUnity { get; set; }

    // If your activity returns a value, derive from CodeActivity<TResult>
    // and return the value from the Execute method.
    protected override void Execute(CodeActivityContext context)
    {
        IUnityContainer container = context.GetExtension<IUnityContainer>();

        context.SetValue<bool>(HasUnity, (container != null));
    }
}
.NET 4 | Unity | WF
Wednesday, 10 February 2010 17:03:13 (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [0]  | 
# Wednesday, 16 December 2009

Feedburner has apparently started decorating the URLs they embed to link back to my full posts, which is causing my decrepit version of dasBlog to yak up 404’s.  I’m working on it now, and apologize for the inconvenience.

Wednesday, 16 December 2009 09:51:04 (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [1]  | 
# Tuesday, 15 December 2009

Just in case someone is googling (binging?) this later…

If you are running Visual Studio 2010 (Beta 2) on Windows 7, and you want to create a Windows Identity Foundation STS or relying party application, you need to run VS as an administrator, or it won’t create the project correctly.  I suspect it’s because it’s trying to install a cert, but there is some other stuff that fails too, probably as a result.  Once I ran VS as an admin, it all works fine. 

And, just for the record, WIF is awesome!  I’ve build an STS and relying app by hand for WCF 3, and this is SOOOOO much easier.  Excellent work guys!

Tuesday, 15 December 2009 16:16:05 (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [0]  | 
# Wednesday, 25 November 2009

I’m trying to get a handle on WF 4 (which is awesome, BTW) and currently working on persistence.  We have a need to encrypt the workflow instance data, and it took me quite some time to figure out how that might best be done.  The biggest drawback to working with WF 4 right now is that the documentation is pretty lame.  There are very few samples, and beta 2 hasn’t been around long enough to generate the “this is how you solve that problem” blog posts we’ve all come to depend upon.  I looked at PersistenceParticipant, but couldn’t see a good way to make that do what I wanted, then a bunch more time trying to figure out what was going on in the SqlWorkflowInstanceStore, etc. 

I think I’ve got a workable solution, although I’ve yet to actually try it out.  Turns out that the SqlWorkflowInstanceStore keeps all that good data in varbinary(MAX) columns, and only messes with them via a set of stored procs that get created when you create the instance store schema.  It should be an easy thing to modify said stored procs to use native SQL 2005/2008 column level encryption, without having to change the schema at all. 

I’ll let you know if it works…

Wednesday, 25 November 2009 13:30:39 (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [0]  | 

This one stumped me for a bit today, so I wanted to get it out there for the search engines to find... I created a new WCF Service Library project in VS 2010, taking all the defaults and targeting .NET 4.0. I needed to add a [WebGet] attribute so that I could make REST calls to the service. To do that, you need a reference to System.ServiceModel.Web.dll. It didn't show up on the list of .NET references in the Add Reference... dialog. OK, weird. So then I tracked down the file manually and added it. It got added to the list of references, but showed up with the yellow-triangle "I don't know how to find this reference" icon. Huh.

The problem turned out to be that for some reason, the project got created with a target framework of .NET 4.0 Client Profile, which doesn't include that assembly. Once I switched to the full .NET 4.0 target, it works just fine. The Client Profile seems like a strange choice for a WCF Service Library.

Wednesday, 25 November 2009 13:23:57 (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [0]  | 
# Monday, 09 November 2009

So I’m trying to figure out how to use WF 4 as a controller for a Prism app, and already I’m running into some interesting behavior.  First off, in anything but a very simple solution, custom activities don’t show up in the toolbox like they should.  That’s not a huge deal, but annoying.

Of greater interest (concern?) is the fact that if I put my workflow XAML file in the main WPF app solution, everything builds and runs just fine, except the workflow does absolutely nothing.  It just finished successfully, having run none of it’s activities.  If I take exactly the same XAML file and put it in another assembly, then run it from the WPF app, it works just like it should.  I’m guessing this is a byproduct of the new unified XAML engine, but I haven’t had time (or inclination really) to delve.  Mostly it just means I have to have at least one superfluous assembly, which for now isn’t too high a price to pay. 

The day I installed beta 2, I managed to crash the workflow designer about 10 times, but it seems to have settled down now.  Overall, I really appreciate the new model for WF, which seems much more composable and easy to use. 

Monday, 09 November 2009 09:09:28 (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [0]  | 
# Friday, 06 November 2009

I realize this is a bit late, but as of just about 4 weeks ago I’m now the Architect at Eid Passport.  I’m really looking forward to building some cool stuff, with a team that’s had quite a bit of experience in this space. 

In short, Eid Passport makes perimeter security systems for secure facilities, and manages access to those facilities by vendors.  For example, say you are the Coke delivery guy at a military base.  It’s a hassle to get through the gate every time you deliver, since they have to make sure it’s OK for you to be on the base.  Now the Coke guy has the option of going to our kiosk at the base and signing up for an access card that will allow him to spend much less time getting in and out.  We do some background checks, employment verification (does he still really work for Coke, etc.) and then issue a credential that he can use to get through the gate.  Now Coke delivery guy can make N more deliveries in a day because he’s not spending time at the gate.  This is a new domain for me, so there’s a lot to learn, but it’s pretty exciting stuff.  All the way from a handheld scanner that reads all kinds of cards to back end access control and data processing servers. 

If any of that sounds interesting to you, we’re looking for some additional developers.  There are instructions on the website (see above) for how to submit your resume if you are interested.

Friday, 06 November 2009 09:32:28 (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [0]  | 
# Wednesday, 17 June 2009

We’ve added some new classes to the SoftSource training calendar, including a one-day Blend 2 class, and SQL 2008 for Developers.  Other offerings coming up are “Agile in a Day”, WPF, WCF, ASP.NET 3.5, LINQ, Silverlight, and of course, C#.  Discounts available for multiple students from the same organization, and custom on-site training also.

Wednesday, 17 June 2009 10:19:27 (Pacific Daylight Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  | 
# Thursday, 11 June 2009

A month or so ago I posted on a solution for simulating “default button” semantics in a Silverlight app, meaning that if you are entering text in a text box and you hit the enter key, the “default button” for the “page” should be pressed.  Very natural for form entry, etc. 

An issue came up (discovered by John Papa) with the solution in a Prism app, because my solution depends on being able to find the “default” button in the visual tree using the FindName method.  That means that you have to be high enough up the visual tree to find the button, since it only works “down” the tree.  In a Prism app, it’s not necessarily clear where “high enough” might be.  Plus, because the solution requires unique names, and Prism modules may have nothing to do with one another, they may have duplicate names, etc.

Here’s a revision to the solution that doesn’t require unique names, and doesn’t require any static references that might interfere with proper garbage collection…

First, a new object called DefaultButtonHub that keeps track of the relationship between text boxes and buttons.  It also exposes an Attached Property that takes a DefaultButtonHub reference so we can hook up text boxes and buttons to the “hub” in XAML.

public class DefaultButtonHub
{
   ButtonAutomationPeer peer = null;

   private void Attach(DependencyObject source)
   {
       if (source is Button)
       {
           peer = new ButtonAutomationPeer(source as Button);
       }
       else if (source is TextBox)
       {
           TextBox tb = source as TextBox;
           tb.KeyUp += OnKeyUp;
       }
       else if (source is PasswordBox)
       {
           PasswordBox pb = source as PasswordBox;
           pb.KeyUp += OnKeyUp;
       }
   }

   private void OnKeyUp(object sender, KeyEventArgs arg)
   {
       if(arg.Key == Key.Enter)
           if (peer != null)
               ((IInvokeProvider)peer).Invoke();
   }

   public static DefaultButtonHub GetDefaultHub(DependencyObject obj)
   {
       return (DefaultButtonHub)obj.GetValue(DefaultHubProperty);
   }

   public static void SetDefaultHub(DependencyObject obj, DefaultButtonHub value)
   {
       obj.SetValue(DefaultHubProperty, value);
   }

   // Using a DependencyProperty as the backing store for DefaultHub.  This enables animation, styling, binding, etc...
   public static readonly DependencyProperty DefaultHubProperty =
       DependencyProperty.RegisterAttached("DefaultHub", typeof(DefaultButtonHub), typeof(DefaultButtonHub), new PropertyMetadata(OnHubAttach));

   private static void OnHubAttach(DependencyObject source, DependencyPropertyChangedEventArgs prop)
   {
       DefaultButtonHub hub = prop.NewValue as DefaultButtonHub;
       hub.Attach(source);
   }

}

Basically we’re expecting that both the text boxes and the button will register themselves with the “hub”.  If it’s a button that’s being registered, we wrap it in a ButtonAutomationPeer so we can “press” it later.  If it’s a text box, we hook up a KeyUp handler that will “press” the button if it’s there.  The requirement in the XAML is only marginally heavier than in my previous solution…we have to add a resource of type DefaultButtonHub, and point the button and text boxes at it using the {StaticResource} markup extension.

<UserControl x:Class="DefaultButton.Page"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:my="clr-namespace:DefaultButton"
    Width="400" Height="300">
    <UserControl.Resources>
        <my:DefaultButtonHub x:Key="defaultHub"/>
    </UserControl.Resources>
    <Grid x:Name="LayoutRoot" Background="White">
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <TextBox x:Name="theText" Grid.Row="0"
                 my:DefaultButtonHub.DefaultHub="{StaticResource defaultHub}"/>
        <Button x:Name="theButton" Grid.Row="1" Content="Default"
                Click="theButton_Click" my:DefaultButtonHub.DefaultHub="{StaticResource defaultHub}"/>
    </Grid>
</UserControl>

Note that the new DefaultHub attached property is applied to both the text box and the button, each pointing the the single resource.  This way everything gets wired up property, there isn’t any problem with name resolution (aside from the usual resource name scoping) and everything will get cleaned up if the form needs to be GC’d.

Thursday, 11 June 2009 12:03:22 (Pacific Daylight Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  |