应该使用哪个WCF的扩展点来设置每个操作的上下文?

时间:2014-11-24 17:54:10

标签: c# wcf ambientcontext

我想为主机内运行的所有服务的每个操作设置环境上下文(类似于Thread.CurrentPrincipal的工作原理)。

我应该使用哪种扩展机制?因为我几乎没有使用WCF的经验,所以我很困惑。

1 个答案:

答案 0 :(得分:2)

以下是解决方案:

首先,我们创建端点行为,为操作添加初始化程序:

public class CallContextInitializerBehavior : IEndpointBehavior
{
    private readonly ICallContextInitializer callContextInitializer;
    private ServiceHost serviceHost;

    public CallContextInitializerBehavior(ICallContextInitializer callContextInitializer)
    {
        this.callContextInitializer = callContextInitializer;
    }

    public void AddToHost(ServiceHost host)
    {
        // only add to host once
        if (this.serviceHost != null)
        {
            return;
        }

        this.serviceHost = host;

        foreach (ServiceEndpoint endpoint in this.serviceHost.Description.Endpoints)
        {
            endpoint.Behaviors.Add(this);
        }
    }

    public void Validate(ServiceEndpoint endpoint)
    {
    }

    public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
    {
    }

    public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
    {
        foreach (DispatchOperation operation in endpointDispatcher.DispatchRuntime.Operations)
        {
            operation.CallContextInitializers.Add(callContextInitializer);
        }
    }

    public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
    {
    }
}

然后我们创建自己的ICallContextInitializer实现:

public class MyCallContextInitializer : ICallContextInitializer
{
    public object BeforeInvoke(InstanceContext instanceContext, IClientChannel channel, Message messa
    {
        ...do domething here...

        return myCorrelationState; // or null if not important;
    }

    public void AfterInvoke(object correlationState)
    {
        UserInfo userInfoBeforeInvoke = (UserInfo) correlationState;

        AmbientContext.Context.SetCurrent(userInfoBeforeInvoke);
    }
}

最后通过调用来应用行为(当然,最好使用IoC):

var initializer = new MyCallContextInitializer();
var behavior = new CallContextInitializerBehavior(initilizer);
behvior.AddToHost(serviceHost);