【问题标题】:Programmatically set InstanceContextMode以编程方式设置 InstanceContextMode
【发布时间】:2012-02-12 16:54:03
【问题描述】:

有没有办法做到这一点...

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]

...以编程方式?

原因是我想在集成测试我的服务时将我的服务实例直接传递到我的自托管帮助器类中。

我正在使用 Castle Windsor 创建我的所有对象,在使用测试网站时效果很好。但是当我尝试使用我的 HttpWebService 帮助程序类时出现以下错误...

System.InvalidOperationException was unhandled by user code
  Message=In order to use one of the ServiceHost constructors that takes a service instance, the InstanceContextMode of the service must be set to InstanceContextMode.Single.  This can be configured via the ServiceBehaviorAttribute.  Otherwise, please consider using the ServiceHost constructors that take a Type argument.
  Source=System.ServiceModel

这是我的助手类的构造函数...

public HttpWebService(string baseUri, string acceptType, TApi serviceInstance = null)
{
    _baseUri = baseUri;
    _acceptType = acceptType.ToLower();

    _host = serviceInstance == null
                ? new HttpServiceHost(typeof (TApi), baseUri)
                : new HttpServiceHost(serviceInstance, baseUri);
    _host.Open();
    _client = new HttpClient();
    _client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(_acceptType));
}

所以,我需要在“集成测试模式”下以编程方式设置InstanceContextMode,即在我的助手类中。

我想我需要做这样的事情......

if (serviceInstance != null)
{
    _host = new HttpServiceHost(serviceInstance, baseUri);
    var whatDoIDoNow = null;
    _host.Description.Behaviors.Add(whatDoIDoNow);
}

任何帮助/指导都会很棒,因为我真的坚持这一点。

【问题讨论】:

    标签: wcf-web-api


    【解决方案1】:

    我正在回答我自己的问题,因为我在 stackoverflow 上的另一个 answer 中找到了解决方案,我认为 stackoverflow 是一个无需提问即可搜索的好地方,所以希望我能补充一下通过用指向其他答案的链接回答我自己的问题而不只是关闭我自己的问题来丰富自己的问题。

    我的代码现在看起来像这样......

    public HttpWebService(string baseUri, string acceptType, TApi serviceInstance = null)
    {
        _baseUri = baseUri;
        _acceptType = acceptType.ToLower();
    
        if (serviceInstance != null)
        {
            _host = new HttpServiceHost(serviceInstance, baseUri);
            var behaviour = _host.Description.Behaviors.Find<ServiceBehaviorAttribute>();
            behaviour.InstanceContextMode = InstanceContextMode.Single;
        }
        _host = _host ?? new HttpServiceHost(typeof (TApi), baseUri);
    
        _host.Open();
        _client = new HttpClient();
        _client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(_acceptType));
    }
    

    我改变了这个...

    _host = serviceInstance == null
                ? new HttpServiceHost(typeof (TApi), baseUri)
                : new HttpServiceHost(serviceInstance, baseUri);
    

    ...到这个...

    if (serviceInstance != null)
    {
        _host = new HttpServiceHost(serviceInstance, baseUri);
        var behaviour = _host.Description.Behaviors.Find<ServiceBehaviorAttribute>();
        behaviour.InstanceContextMode = InstanceContextMode.Single;
    }
    _host = _host ?? new HttpServiceHost(typeof (TApi), baseUri);
    

    【讨论】:

    • 答案如果只包含解决方案而不是完整的代码会更容易阅读。
    • 谢谢。正是我想要的。拯救了我自己的研究。
    【解决方案2】:

    即使原始答案包含解决方案,它只是对问题的直接回答

    ServiceHost host = new ServiceHost(typeof(YourService)); //Or get the Servicehost
    ((ServiceBehaviorAttribute)host.Description.
    Behaviors[typeof(ServiceBehaviorAttribute)]).InstanceContextMode 
    = InstanceContextMode.Single;
    

    【讨论】:

      【解决方案3】:

      我们也可以在Service类中使用ServiceBehaviourAttribute来设置InstanceContextMode如下:

      [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single,
      ConcurrencyMode = ConcurrencyMode.Multiple)]
      public class MyService : IMyService
      {
      //service code
      }
      

      【讨论】:

        猜你喜欢
        • 2021-11-21
        • 2018-11-26
        • 2011-04-18
        • 2012-07-18
        • 2016-02-15
        • 2014-07-26
        • 1970-01-01
        • 2011-06-06
        • 1970-01-01
        相关资源
        最近更新 更多