Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Apply a WCF attribute to all method in the service

Tags:

c#

attributes

wcf

I have a custom attribute that I want to apply to each methods in my WCF service.

I proceed like this:

[MyAttribute]
void MyMethod()
{

}

The problem is that my service contains hundreds of methods and I don't want to write [Attribute] above all of them. Is there a way to apply the attribute to all my methods in my service?

Here's my attribute's signature:

//[AttributeUsage(AttributeTargets.Class)]
public class SendReceiveBehaviorAttribute : Attribute, /*IServiceBehavior,*/ IOperationBehavior

EDIT after Aliostad's answer:

I tried this:

public void ApplyDispatchBehavior(ServiceDescription desc, ServiceHostBase host)
{
    foreach (ChannelDispatcher cDispatcher in host.ChannelDispatchers)
    {
        foreach (EndpointDispatcher eDispatcher in cDispatcher.Endpoints)
        {
            foreach (DispatchOperation op in eDispatcher.DispatchRuntime.Operations)
            {
                op.Invoker = new OperationInvoker(op.Invoker);
            }
        }
    }
}

And that:

public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)
{
    foreach (ChannelDispatcher cDispatcher in serviceHostBase.ChannelDispatchers)
    {
        foreach (EndpointDispatcher eDispatcher in cDispatcher.Endpoints)
        {
            foreach (DispatchOperation op in eDispatcher.DispatchRuntime.Operations)
            {
                op.Invoker = new OperationInvoker(op.Invoker);
            }
        }
    }
}

But it still don't work.

like image 601
Jean-Philippe Leclerc Avatar asked Mar 29 '11 15:03

Jean-Philippe Leclerc


2 Answers

The following should do the trick by using the service behavior to add the correct operation behavior which calls the invoker.

public class MyAttribute : Attribute, IServiceBehavior, IOperationBehavior
{
    #region IServiceBehavior Members
    public void ApplyDispatchBehavior(ServiceDescription description, ServiceHostBase host)
    {
        foreach (ServiceEndpoint endpoint in host.Description.Endpoints)
        {
            foreach (var operation in endpoint.Contract.Operations)
            {
                operation.Behaviors.Add(this);
            }
        }
    }
    ...
    #endregion

    #region IOperationBehavior Members
    public void ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation)
    {
        dispatchOperation.Invoker = new OperationInvoker(dispatchOperation.Invoker);
    }
    ...
    #endregion
}
like image 103
Aaron Stainback Avatar answered Sep 23 '22 00:09

Aaron Stainback


According to IServiceBehaviour documentation, if you implement this interface and create an attribute and put it at the class level, it will be applied to all operations:

Create a custom attribute that implements IServiceBehavior and use it to mark service classes that are to be modified. When a ServiceHost object is constructed, uses reflection to discover the attributes on the service type. If any attributes implement IServiceBehavior, they are added to the behaviors collection on ServiceDescription.


UPDATE

Instead of implementing IOperationBehaviour, add required behaviour in the IServiceBehaviour by looping through all operations:

foreach (EndpointDispatcher epDisp in chDisp.Endpoints)
{
    epDisp.DispatchRuntime.MessageInspectors.Add(this);
    foreach (DispatchOperation op in epDisp.DispatchRuntime.Operations)
    {
        op.ParameterInspectors.Add(this); // JUST AS AN EXAMPLE 
    }                        
}
like image 24
Aliostad Avatar answered Sep 23 '22 00:09

Aliostad