1

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

我应该使用什么扩展机制?它们很多,所以我很困惑,因为我几乎没有使用 WCF 的经验。

4

1 回答 1

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); 
于 2014-11-27T08:55:42.257 回答