将WCF属性应用于服务中的所有方法

时间:2011-03-29 15:52:41

标签: c# wcf attributes

我有一个自定义属性,我想将其应用于我的WCF服务中的每个方法。

我这样做:

[MyAttribute]
void MyMethod()
{

}

问题是我的服务包含数百种方法,我不想在所有方法上面写[Attribute]。有没有办法将属性应用于我服务中的所有方法?

这是我的属性的签名:

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

在Aliostad的回答后编辑:

我试过了:

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);
            }
        }
    }
}

那:

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);
            }
        }
    }
}

但它仍然不起作用。

5 个答案:

答案 0 :(得分:8)

以下应该通过使用服务行为来添加调用调用者的正确操作行为。

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
}

答案 1 :(得分:6)

根据IServiceBehaviour文档,如果您实现此接口并创建属性并将其放在类级别,它将应用于所有操作:

  

创建一个自定义属性   实现IServiceBehavior并使用它   标记要的服务类   改性。当ServiceHost对象是   构造,使用反射   发现服务上的属性   类型。如果有任何属性实现   IServiceBehavior,它们被添加到   行为集合   ServiceDescription。


更新

不是实施IOperationBehaviour,而是通过循环执行所有操作IServiceBehaviour中添加所需行为:

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 
    }                        
}

答案 2 :(得分:0)

定义服务行为属性,在服务级别应用该属性。在行为中,迭代合同中定义的所有方法并执行所有MyAttribute的东西。

答案 3 :(得分:-1)

您可以考虑使用AOP或后构建操作,以便将属性注入已编译的代码中。

答案 4 :(得分:-2)

为什么不使用T4生成可重复的代码? 我们在编译时使用反射比运行时更好。

逻辑上,服务方法是业务方法的调用者。因此,您可以通过阅读业务类的公共方法轻松生成具有所需属性的服务方法。在实施业务类时,只需要注意。