2

As I understand from this article:

Single: This will help us to share the data globally. We can create only one instance and the same instance will be reused on the subsequent calls. Same like Per Session this will work with all bindings except basicHttpBinding.

InstanceContextMode.Single not available for basicHttpBinding.

But according to this answer it works.

This article adds confusion.

I'd like to get clear answer and explanation.

Alexan
  • 8,165
  • 14
  • 74
  • 101

1 Answers1

2

InstanceContextMode.Single will force the WCF engine to create a single instance of your service class through the lifetime of your service. This means that all requests will share the same instance rather than creating one per request.

This is entirely possible with basicHttpBinding.

Here is an example using basicHttpBinding and InstanceContextMode.Single:

First my Service class which has private field that keeps the count of requests:

using System.ServiceModel;

namespace WcfService1
{
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
    public class Service1 : IService1
    {
        private int _singleCounter = 0;//this will be preserved across requests
        public Service1() 
        {
            //this constructor executes only ONCE
        }
        public string GetData()
        {
            //this will increment with each request 
            //because it is a SINGLE instance the count
            //will be preserved
            _singleCounter++;
            return string.Format("Requests on this instance: {0}", _singleCounter);
        }
    }
}

Now my Service Contract:

using System.ServiceModel;

namespace WcfService1
{    
    [ServiceContract]
    public interface IService1
    {
        [OperationContract]
        string GetData();
    }
}

Lastly here is my config file with a single binding using basicHttpBinding:

<?xml version="1.0"?>
<configuration>
  <appSettings>
    <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
  </appSettings>
  <system.web>
    <compilation debug="true" targetFramework="4.5" />
    <httpRuntime targetFramework="4.5"/>
  </system.web>
  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <!-- To avoid disclosing metadata information, set the values below to false before deployment -->
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
          <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="false"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <protocolMapping>
        <add binding="basicHttpsBinding" scheme="https" />
    </protocolMapping>    
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
    <directoryBrowse enabled="true"/>
  </system.webServer>
</configuration>

Now using the default WCF Test Client that comes with Visual Studio here are the results:

First call the count is 1: enter image description here

Second call the count is 2: enter image description here

A few clicks later the count is still being preserved: enter image description here

I am not sure why some articles state that InstanceContextMode.Single is not supported by basicHttpBinding. It is obviously not true.

I use InstanceContextMode.Single combined with ConcurrencyMode.Multiple for high throughput services all the time.

It also has the advantage that you can keep some "state" during the lifetime of the service that can be shared across all requests. For example I keep commonly used data in private fields to avoid loading it from the database on every request etc.

Jonathan Alfaro
  • 4,013
  • 3
  • 29
  • 32
  • what about performance? Has this mode some performance advantages? When I should use it? – Alexan Mar 20 '20 at 01:17
  • @Alexan In my opinion it has a higher performance than PerCall and PerSession because there is only one instance being created and there is no Garbage Collection. That is why I stated that I use for high throughput services. Another performance advantage is that all common data that can be shared across requests can be loaded once in the constructor. With PerCall or PerSession you would have to load this data every single call. – Jonathan Alfaro Mar 20 '20 at 01:20
  • you have only one service method. Will it work if I have many? Will they be able to share the same instance? – Alexan Mar 20 '20 at 02:26
  • @Alexan there will be one single instance of that service class no matter what. That is what a single instance means. It does not matter how many methods you add to it. The service class is just a class there is nothing special about it. It will work as any other C# class. – Jonathan Alfaro Mar 20 '20 at 04:28