web-dev-qa-db-fra.com

Définir par programme InstanceContextMode

Y a-t-il un moyen de faire cela ...

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]

... par programmation?

La raison en est que je souhaite transmettre une instance de mon service directement à ma classe d'assistance auto-hébergée lorsque l'intégration teste mon service.

J'utilise Castle Windsor pour créer tous mes objets, ce qui fonctionne bien avec le site Web de test. Mais j'obtiens l'erreur suivante lorsque j'essaie d'utiliser ma classe d'assistance 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

Ceci est le constructeur de ma classe d'assistance ...

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

Je dois donc définir par programme la InstanceContextMode en "mode de test d'intégration", c'est-à-dire - dans ma classe d'assistance.

Je pense que je dois faire quelque chose comme ça ...

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

Toute aide/orientation serait formidable car je suis vraiment coincé là-dessus.

37
Antony Scott

Je réponds à ma propre question car j'ai trouvé une solution dans un autre réponse sur stackoverflow, et je pense que stackoverflow est un excellent endroit pour chercher sans même avoir à poser une question, alors j'espère ajouter à cette richesse en répondant à ma propre question par un lien vers l'autre réponse et en ne fermant pas ma propre question.

Mon code ressemble maintenant à ceci ...

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

J'ai changé ça ...

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

... pour ça ...

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);
53
Antony Scott

Même si la réponse initiale contient la solution, il ne s'agit que d'une réponse directe à la question

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

Nous pouvons également utiliser ServiceBehaviourAttribute à la classe Service afin de définir InstanceContextMode comme ci-dessous:

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