Service Extensions, ActivationContextExtension.Current & Configuration

Jan 22, 2010 at 11:04 AM

Hi,

I'm begining a WCF Project and I've got to trace some usefull informations.

It seems WcfContrib would be quite usefull to get these informations without the need to code a lot of things for that since it would be only configurations.

So I'm trying to use the Service Extensions and the configuration shown in the Show Cases downloadable on your site, but it seems my Wcf Service doesn't get any ActivationContextExtension.Current context (the instance is null).

I'm using this configuration for the WCF Service :

 

  <system.serviceModel>
    <extensions>
      <behaviorExtensions>
        <add name="serviceExtensionsBehavior"
             type="WcfContrib.Extensions.ServiceExtensionsBehaviorElement, WcfContrib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=242f357400093587" />
      </behaviorExtensions>
    </extensions>
    <services>
      <service name="WcfService1.Service1" behaviorConfiguration="WcfService1.Service1Behavior">
        <endpoint address=""
                  binding="wsHttpBinding"
                  contract="WcfService1.IService1" />
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="WcfService1.Service1Behavior">
          <serviceExtensionsBehavior tracingActivation="Enabled" mockingActivation="Disabled"
                                       knownOutputControllers="Console,File" durationNoticeLimitInMs="5000"
                                       parameterDetail="SerializeOnFaultReply" parameterSerializationDepth="2" />
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="false"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>

And my WCF Service code is :

 

    [ServiceBehavior(ConfigurationName = "WcfService1.Service1")]
    public class Service1 : IService1
    {
        public string GetData(int value)
        {
            return string.Format("You entered: {0}", value);
        }

        public CompositeType GetDataUsingDataContract(CompositeType composite)
        {
            if (composite.BoolValue)
            {
                composite.StringValue += "Suffix" + TestContrib();
            }
            return composite;
        }

        private string TestContrib()
        {
            ActivationContextExtension ctx = ActivationContextExtension.Current;
            if (ctx != null)
            {
                return ctx.Action;
            }
            return string.Empty;
        }
    }

Anyone could help me and tell me why I'm not getting anything in the ActivationContextExtension.Current please ?

 

 

 

Jan 22, 2010 at 2:04 PM
Edited Jan 22, 2010 at 2:07 PM

I've found a way to make it to work .. just had to look in reflector how it is done to activate that ActivationContextExtension.

I've just added an attribute implementing IServiceBehavior :

 

    public class ActivationContextAttribute : Attribute, IServiceBehavior
    {
        private ActivationContextInitializerBehavior behavior;

        public ActivationContextAttribute()
            : base()
        {
            behavior = new ActivationContextInitializerBehavior();
        }

        #region IServiceBehavior Membres

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

        public void ApplyDispatchBehavior(ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase)
        {
            ((IServiceBehavior)behavior).ApplyDispatchBehavior(serviceDescription, serviceHostBase);
        }

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

        #endregion
    }

And to create a BehaviorExtensionElement to add it with the Web.config of my WCF Service :

 

    public class ActivationContextExtensionBehaviorElement : BehaviorExtensionElement
    {
        public override Type BehaviorType
        {
            get { return typeof(ActivationContextAttribute); }
        }

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

 

And Config :

 

  <system.serviceModel>
    <extensions>
      <behaviorExtensions>
        <add name="activationContextExtension"
             type="WcfService1.Extensions.ActivationContextExtensionBehaviorElement, WcfService1.Extensions, Version=1.0.0.0, Culture=neutral, PublicKeyToken=9ef371af512f0802" />
        <add name="serviceExtensionsBehavior"
             type="WcfContrib.Extensions.ServiceExtensionsBehaviorElement, WcfContrib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=242f357400093587" />
      </behaviorExtensions>
    </extensions>
    <services>
      <service name="WcfService1.Service1" behaviorConfiguration="WcfService1.Service1Behavior">
        <!-- Service Endpoints -->
        <endpoint address=""
                  binding="wsHttpBinding"
                  contract="WcfService1.IService1" />
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="WcfService1.Service1Behavior">
          <activationContextExtension />
          <serviceExtensionsBehavior tracingActivation="Disabled" mockingActivation="Disabled"
                                       knownOutputControllers="Console,File" durationNoticeLimitInMs="5000"
                                       parameterDetail="SerializeOnFaultReply" parameterSerializationDepth="2" />
          <!--<serviceMetadata httpGetEnabled="true" />-->
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>

 

 

Just like it is done with ServiceExtensionBehavior.

Cheers ! 

 

 

Coordinator
Jan 29, 2010 at 7:18 PM

Hi,

If you're using the ServiceHost that comes with WcfContrib you will get that behavior by default.
If not, that is a good  way to wrap it so you could use it as you wish.

Thanks for the reply with your elegant solution.

Coordinator
Feb 6, 2010 at 4:51 PM

Similar classes were added to WCF Contrib v2.1 for your convenience.

ActivationContextInitializerAttribute and ActivationContextExtensionBehaviorElement.