web-dev-qa-db-ja.com

プログラムでInstanceContextModeを設定します

これを行う方法はありますか...

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]

...プログラム的に?

その理由は、サービスの統合テストを行うときに、サービスのインスタンスをセルフホスティングヘルパークラスに直接渡したいからです。

Castle Windsorを使用してすべてのオブジェクトを作成しています。これは、テストWebサイトを使用するときに正常に機能します。しかし、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);
}

私は本当にこれに固執しているので、どんな助け/ガイダンスも素晴らしいでしょう。

41
Antony Scott

スタックオーバーフローの別の answer で解決策を見つけたので、私は自分の質問に答えています。スタックオーバーフローは、質問することなく検索するのに最適な場所だと思います。自分の質問を閉じるだけでなく、他の回答へのリンクを使って自分の質問に答えることで、その豊かさになります。

私のコードは次のようになります...

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

元の答えには解決策が含まれていますが、それは質問に対する正直な答えです

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

次のようにInstanceContextModeを設定するために、ServiceクラスでServiceBehaviourAttributeを使用することもできます。

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