Question

I have a custom OperationBehavior. I would like to apply it for all operations at once. Unfortunately, OperationBehaviors cannot be configured per entire service or in web.config.

When hosting WCF service in a test application, I can do the following:

        foreach (var ep in _serviceHost.Description.Endpoints)
        {
            foreach (OperationDescription od in ep.Contract.Operations)
            {
                od.Behaviors.Add(new MyOperationBehavior());
            }
        }

        _serviceHost.Open();

But how do I do it in a IIS hosted web application?

I tried to get OperationContext.Current.Host.Description.Endpoints in Application_Start but of course OperationContext.Current is not available before any operation has started, so my approach fails.

Was it helpful?

Solution

You can use a ServiceHostFactory to do that. With it, you can get access to the OM prior to the service being opened.

This is an example:

public class MyFactory : ServiceHostFactory
{
    protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
    {
        ServiceHost host = base.CreateServiceHost(serviceType, baseAddresses);
        foreach (var ep in host.Description.Endpoints)
        {
            foreach (OperationDescription od in ep.Contract.Operations)
            {
                od.Behaviors.Add(new MyOperationBehavior());
            }
        }

        return host;
    }
}

And you can get more information about service host factories at http://blogs.msdn.com/b/carlosfigueira/archive/2011/06/14/wcf-extensibility-servicehostfactory.aspx

OTHER TIPS

At the end I found an alternative solution: use a contract behavior which injects any other behvaior as needed. Like this:

public class InjectAllOperationsBehavior : Attribute, IContractBehavior
{
    private IOperationBehavior _operationBehavior = null;

    public InjectAllOperationsBehavior(Type operationBehaviorType)
    {
        _operationBehavior = 
            (IOperationBehavior)Activator.CreateInstance(operationBehaviorType);
    }

    public void ApplyDispatchBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, DispatchRuntime dispatchRuntime)
    {
        foreach (OperationDescription opDescription in contractDescription.Operations)
        {
            opDescription.Behaviors.Add(_operationBehavior);
        }
    }

... other IContractBehavior methods can be left empty. You might want also to use the ApplyClientBehavior method with the same code from the ApplyDispatchBehavior method.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top