# Wednesday, October 27, 2010

It’s not uncommon to want to dynamically add new sections to an XML file, such as a config file, without having to recompile existing code for processing said XML file.  One common example is the way that .NET’s app.config file supports a config section / config section handler model.  You can add new arbitrary XML that is specific to a particular bit of code in its schema, then register a “handler” for that config section so that the standard System.Configuration classes can read and deal with that otherwise unknown schema. 

Rather then explicitly registering “handlers” in the XML file itself, we can use the Managed Extensibility Framework (MEF), which is now a fully baked part of the .NET 4 framework. 

Let’s say I start off with a configuration file that looks like this

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <products>
    <product name="Product1">
      <P1Config>
        <secretP1Value>42</secretP1Value>
      </P1Config>
    </product>
    <product name="Product2">
      <Product2Config>
        <installedFeatures>
          <feature id="1"/>
          <feature id="36"/>
        </installedFeatures>
      </Product2Config>
    </product>
  </products>
</configuration>

I want to be able to add new <product> sections in the future which will contain XML that only that particular product’s plugin will know what to do with. 

MEF is all about the “plugin” pattern.  It allows me to declare “Exported” contracts that plugins essentially publish for use, and to declare that other components “Import” those plugins, meaning they require a runtime instance of one or more of those published exports.  For the sake of the above example, I’ve defined an interface that each product plugin will need to support to process the XML from its config section.

interface IProductPlugin
{
    bool Configure(XElement config);
}

When the overall XML file is processed, an instance of each product’s plugin will be instantiated and “fed” the XElement that represents its config section.  MEF makes it easy to choose which plugin gets loaded for each section using named contracts.  The following two plugins

[Export("Product1", typeof(IProductPlugin))]
public class ProductOnePlugin : IProductPlugin
{
    public bool Configure(XElement config)
    {
        var secret = from el in config.Descendants()
                     where el.Name == "secretP1Value"
                     select el.Value;

        Debug.WriteLine(secret.FirstOrDefault());

        return true;
    }
}

[Export("Product2", typeof(IProductPlugin))]
public class ProductTwoPlugin : IProductPlugin
{
    public bool Configure(XElement config)
    {
        var installed = from el in config.Descendants()
                        where el.Name == "feature"
                        select el.Attribute("id").Value;

        foreach (var off in installed)
        {
            Debug.WriteLine(off);
        }

        return true;
    }
}

both export the IProductPlugin interface, but they also declare a name under which it will be exported.  We can use a corresponding “name” attribute in the <product> element of each section to get the right plugin.  At runtime, the code to load the file reads each product element and instantiates the right plugin by asking MEF for the named instance from MEF’s catalog.

XDocument top = XDocument.Load(s);
var products = from product in top.Root.Element("products").Elements()
               select product;

foreach (var prod in products)
{
    string name = prod.Attribute("name").Value;
    var plugin = _container.GetExport<IProductPlugin>(name);
    plugin.Value.Configure(prod);
}

The key in this case is the GetExport method.  It optionally takes that arbitrary string and tries to find the right instance from the catalog.  In this particular case, for the sake of simplicity, the catalog is loaded from the running assembly.

_container = new CompositionContainer(new AssemblyCatalog(Assembly.GetExecutingAssembly()));
_container.ComposeParts(this);

In practice, I would use the DirectoryCatalog class to build the catalog from all the assemblies in one directory, which would allow new plugin assemblies to be simply dropped into place without anything needing to be compiled.

Wednesday, October 27, 2010 2:32:51 PM (Pacific Daylight Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  | 

I’ll be speaking at PADNUG next Tuesday about the wonders of WF 4 and how to apply it to real world problems.  We’ll look at what problems WF solves, when it might be appropriate, and how to get started building your own workflows.  We’ll also look at using WF/WCF integration to create “declarative services” or “workflow services” quickly and easily.

Wednesday, October 27, 2010 9:40:47 AM (Pacific Daylight Time, UTC-07:00)  #    Disclaimer  |  Comments [1]  | 
# Wednesday, September 15, 2010

As of this week, I’m now working at WebMD Health Service in NW Portland.  I’m looking forward to working with the very smart people here, and learning about the latest in ASP.NET and Agile development in the enterprise.

More information to follow as the situation warrants. Smile

Wednesday, September 15, 2010 11:30:54 AM (Pacific Daylight Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  | 
# Thursday, September 02, 2010
A while back I posted a revision to my original default button sample that made it a bit easier to use, but there was still an issue...  If you invoke the button while the focus is still in a text box, any changes made to the text in the text box may not get pushed into the databinding source, since by default that happens when the text box loses focus.  I didn't come up with a good solution, but luckily somebody did. :)  I got the following revision from Glenn Orr, and this should solve the problem.  If you have any custom data entry controls, etc. you may have to add additional clauses to handle them, but this will work with text boxes for sure.

Change the OnKeyUp method to look like this...


private void OnKeyUp(object sender, KeyEventArgs arg)
{
	  if (arg.Key == Key.Enter)
			  if (peer != null)
			   {
					   if (sender is TextBox)
					  {
							   BindingExpression expression = (sender as TextBox).GetBindingExpression(TextBox.TextProperty);
							   expression.UpdateSource();
					  }
					  ((IInvokeProvider)peer).Invoke();
			  }
}
This will make sure that any changes get pushed into the databinding source before the button is invoked. Thanks Glenn!
Thursday, September 02, 2010 10:00:05 AM (Pacific Daylight Time, UTC-07:00)  #    Disclaimer  |  Comments [1]  | 
# Sunday, May 23, 2010

The sample app I used for my Code Camp presentation is here.  I’ll post details about the sample later in the week.

Sunday, May 23, 2010 8:26:25 PM (Pacific Daylight Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  | 
# Thursday, April 15, 2010

While I guess I understand why this would be a problem, I don’t understand why it worked before…

If I want to create a style for a button, let’s say with a red background, I might create a brush resource that defines my special color of red, then reference that brush in a style resource like so

<SolidColorBrush x:Key="TheBrush">
    <SolidColorBrush.Color>Red</SolidColorBrush.Color>
</SolidColorBrush>            
<Style x:Key="RedButton" TargetType="Button">
    <Setter Property="Background" Value="{StaticResource TheBrush}"/>
</Style>

That works just fine.  I get a red button like this

image

If the two resources are in the opposite order

<Style x:Key="RedButton" TargetType="Button">
    <Setter Property="Background" Value="{StaticResource TheBrush}"/>
</Style>
<SolidColorBrush x:Key="TheBrush">
    <SolidColorBrush.Color>Red</SolidColorBrush.Color>
</SolidColorBrush> 

then at runtime I’m going to end up with an exception because the resource “TheBrush” can’t be found.  Hmmm.  I suppose that makes sense if we imagine the XAML processor instancing objects as it comes to them in the XZML file.  It would try to instance “RedButton” and not be able to create the static reference to “TheBrush” because that object hasn’t been instanced yet.

If I happen to apply that style some something in my XAML

<Button 
    Style="{StaticResource RedButton}" 
    Content="Red Button" Height="23"
    Click="button1_Click" />

I’ll get a compile error.  OK.  If, however, the reference to “RedButton” is in something like a DataTemplate that doesn’t get applied until runtime, then I get a rather jarring runtime exception instead. 

Again, I suppose this behavior makes sense given my theoretical model of the XAML processor (though it smacks of C++-ishness).  What doesn’t make sense is why it worked just fine in the RC, and just recompiling in the release of VS 2010 I now get runtime exceptions.  Something obviously changed in the way resources are loaded and/or referenced at runtime.

Thursday, April 15, 2010 1:02:03 PM (Pacific Daylight Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  | 
# Friday, February 12, 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, February 12, 2010 11:14:40 AM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [0]  | 
# Wednesday, February 10, 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, February 10, 2010 5:03:13 PM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [0]  | 
# Wednesday, December 16, 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, December 16, 2009 9:51:04 AM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [1]  | 
# Tuesday, December 15, 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, December 15, 2009 4:16:05 PM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [0]  |