【问题标题】:Get the name of caller (or method) that created the WCF Service instance?获取创建 WCF 服务实例的调用者(或方法)的名称?
【发布时间】:2014-03-19 07:22:05
【问题描述】:

我有一个带有私有构造函数的 WCF 服务。如果我没记错的话,WCF中的构造函数必须是无参数的,而我需要的参数是调用者的名字(或者调用者的方法名),所以我可以分配几个只读字段。

有没有一种方法可以让我得到调用者的名字——或者调用它的方法?我正在玩 OperationContext.Current,但没有任何运气。

【问题讨论】:

    标签: c# wcf


    【解决方案1】:

    出于性能原因,我不建议访问堆栈跟踪。

    如果您使用默认的ServiceHostFactory,WCF 服务构造函数只需要无参数。您可以像这样在 .svc 文件中指定自定义服务工厂:

    <%@ ServiceHost Language="C#" Debug="true"
       Service="Namespace.To.Service"
       Factory="Namespace.To.ServiceFactory" %>
    

    以自定义方式创建类的过程如下:

    1. 您的 ServiceHostFactory 在 CreateServiceHost 中创建您的自定义 ServiceHost 的实例
    2. ServiceHost 覆盖OnOpening 并将自定义IServiceBehavior 添加到Description.Behaviors(Description 是基类上的属性)
    3. 您的 IServiceBehavior 实现 ApplyDispatchBehavior 并枚举 serviceHostBase.ChannelDispatchers,检查每个是否为 ChannelDispatcher
    4. 自定义 IInstanceProvider 在GetInstance 中创建实例

    我已经使用它来将创建委托给 IoC 容器。

    【讨论】:

    • 非常感谢,有没有更详细的指南可以看?
    • 我的答案中对“ServiceHostFactory”的引用链接到文档,其中包括一个示例。
    • 虽然,我没有配置文件,因为我通过控制台应用程序托管我的服务 -- serviceHost=new ServiceHost(typeof(Service), new Uri("net.tcp://localhost: 1234")); serviceHost.AddServiceEndpoint(typeof(ISubscribe), new NetTcpBinding(SecurityMode.None), "");服务主机.Open(); -- 我可能会弄明白,但如果您对如何快速设置有任何建议,请告诉我 ;)
    • 更新了答案以包含所涉及的步骤。在您的情况下,您将跳过 ServiceHostFactory 并直接使用您的自定义 ServiceHost。
    【解决方案2】:

    您可以像这样访问 .NET 调用堆栈:

    var trace = new System.Diagnostics.StackTrace();
    var frame = trace.GetFrame( 1 ); // Frame 0 is current function
    var callingMethodName = frame.GetMethod().Name;
    

    我不知道这种技术是否适用于您的情况,但您可以尝试一下。

    【讨论】:

    • 不幸的是它没有帮助:(如果我从 0 访问所有帧,我会得到这些:.ctor CreateService GetInstance GetInstance GetServiceInstance ProcessMessage5 ProcessMessage4 ProcessMessage3 ProcessMessage2 ProcessMessage1 Process Dispatch DispatchAndReleasePump HandleRequest AsyncMessagePump OnAsyncReceiveComplete UnhandledExceptionFrame Complete OnReceive UnhandledExceptionFrame Complete OnReceiveComplete OnAsyncReadComplete FinishRead AsyncReadCallback CompleteCallback UnhandledExceptionFrame PerformIOCompletionCallback -- 除了 (.ctor) 构造函数,这些都是由 wcf 自动生成的
    • 如果 WCF 服务可以看到另一个系统上的调用堆栈,我会感到震惊。
    【解决方案3】:

    我从未见过被调用方法根据调用者的身份执行不同操作的有效案例。如果调用者的身份很重要,那么调用者应该将它需要的任何信息传递给被调用的方法。而不是:

    public MyClass(string callerName) {
        if (callerName == "Caller1")
            _field = "Value1";
        else
            _field = "Value2";
    }
    

    使用

    public MyClass(string value) {
        _field = value;
    }
    

    【讨论】:

    • 我想传递必要的值,但是 wcf 服务中的构造函数必须是无参数的。
    • 答案见下文。
    【解决方案4】:

    我认为您最好的选择是将您的服务分解为多个类似的服务 (yuk),或者将您的方法分解为供不同调用者使用的重载。

    即如果您有 Service1,它为 CallerA 和 CallerB 提供方法 foo(),则可以尝试将 foo 设为私有,并公开分别由 CallerA 和 CallerB 专门调用的 fooA() 和 fooB()。然后 fooA() 和 fooB() 可以在调用 foo() 之前适当地设置只读属性。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-04-19
      • 2012-05-24
      • 1970-01-01
      • 2011-10-27
      • 2022-12-10
      • 1970-01-01
      • 1970-01-01
      • 2010-12-23
      相关资源
      最近更新 更多