Программно установленный InstanceContextMode - PullRequest
38 голосов
/ 18 января 2012

Есть ли способ сделать это ...

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

Любая помощь / руководство было бы замечательно, поскольку я действительно застрял в этом.

Ответы [ 3 ]

54 голосов
/ 18 января 2012

Я отвечаю на свой вопрос, так как нашел решение в другом ответе на stackoverflow, и я думаю, что 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));
}

Iизменил это ...

_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);
1 голос
/ 19 июля 2016

Несмотря на то, что оригинальный ответ содержит решение, это просто прямой ответ на вопрос

ServiceHost host = new ServiceHost(typeof(YourService)); //Or get the Servicehost
((ServiceBehaviorAttribute)host.Description.
Behaviors[typeof(ServiceBehaviorAttribute)]).InstanceContextMode 
= InstanceContextMode.Single;
0 голосов
/ 28 декабря 2018

Мы также можем использовать ServiceBehaviourAttribute в классе Service, чтобы установить InstanceContextMode, как показано ниже:

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