Behavior Merge in WCF 4.0 Configuration

One of the brand new configuration features you can find in the Beta 2 release of .NET 4.0 is the ability to merge behaviors in the configuration hierarchy. This should make it easier to manage behaviors when you want a set of common behaviors to be used consistently. To illustrate how this works, let’s say you have the following virtual directory layout hosted in IIS:

 

~\Web.config

~\Service.svc

~\Child\Web.config

~\Child\Service.svc

                               

And let’s say your ~\Web.config looks like this:

 

<configuration>

  <system.serviceModel>

    <behaviors>

      <serviceBehaviors>

        <behavior>

          <serviceDebug includeExceptionDetailInFaults="True" />

        </behavior>

      </serviceBehaviors>

    </behaviors>

  </system.serviceModel>

</configuration>

And that your child Web.config at ~\Child\Web.config looks like this:

 

<configuration>

  <system.serviceModel>

    <behaviors>

      <serviceBehaviors>

        <behavior>

          <serviceMetadata httpGetEnabled="True" />

        </behavior>

      </serviceBehaviors>

    </behaviors>

  </system.serviceModel>

</configuration>

Then, the service at ~\Child\Service.svc will behave as though it had both the serviceDebug and the serviceMetadata behaviors. The service at ~\Service.svc will only have the serviceDebug behavior though. What has happened is that the two behavior collections with the same name (in this case the empty string) have had their behavior elements merged.

 

Apart from adding behaviors to a behavior collection, you can also clear behavior collections by using the <clear> tag, and remove individual behaviors from the collection by using the <remove> tag. So both of these ~\Child\Web.config files:

 

<configuration>

  <system.serviceModel>

    <behaviors>

      <serviceBehaviors>

        <behavior>

          <remove name="serviceDebug"/>

          <serviceMetadata httpGetEnabled="True" />

        </behavior>

      </serviceBehaviors>

    </behaviors>

  </system.serviceModel>

</configuration>

 

And

 

<configuration>

  <system.serviceModel>

    <behaviors>

      <serviceBehaviors>

        <behavior>

          <clear/>

          <serviceMetadata httpGetEnabled="True" />

        </behavior>

      </serviceBehaviors>

    </behaviors>

  </system.serviceModel>

</configuration>

 

Would result in the child service having only the serviceMetadata behavior, and not the serviceDebug behavior.

 

A few notes:

 

· This works not only for nameless behavior collections as shown above, but also for named behavior collections. So if you had:

<serviceBehaviors>

<behavior name="Foo">

At both the root Web.config and the child Web.config, the child service would have the behaviors merged for both of the behavior collections named “Foo”.

 

· Behavior merge works in the IIS hosting environment, in which Web.config files merge hierarchically with the root Web.config file and machine.config. But it also works in the application environment, where machine.config can merge with the App.config file.

 

· Behavior merge applies to both endpoint behaviors and service behaviors in configuration.

 

· If a child behavior collection contains a behavior that’s already present in the parent behavior collection, the child behavior overrides the parent one. So if a parent behavior collection had <serviceMetadata httpGetEnabled="False" /> and a child behavior collection had <serviceMetadata httpGetEnabled="True" />, the child behavior would override the parent behavior in the behavior collection and httpGetEnabled would be “true”.