Thanks everyone for your response so far. In the last post, we saw the use of session in WCF and how to implement the same.
In this post, we will see how to manage instances in WCF, instancing refers to the lifetime of a service instance.
Introduction
In the last post, we saw how we can allow our WCF service to use session. When we enable session, all calls are handled by the same instance from the time object was created and destroyed. By using instance mode, we can configure how to handle the call once object is created.
Let's see how we can use this feature. There are 3 possible modes, which we can set using the InstanceContextMode
property of ServiceBehavior
attribute. Unlike the session which we configured on Interface level using ServiceContext
attribute, we needs to set ServiceBehavior
on the actual class which is implementing the interface.
Let’s see all 3 modes:
PerCall
: The WCF runtime creates a new service object each time a client calls the service. It releases the object after the call. This is the default mode.
- We will prefer to use this approach when we don’t need to maintain state between requests.
- Scalability is a major concern and service holds expensive resources like communication ports, files or database connections, etc.
PerSession
: The WCF runtime creates a new service object the first time a client calls the service. It keeps the object active for subsequent calls by the client. The runtime releases the object when the session ends. This is the default value for this property.
- Approach is preferable when we need to maintain state.
- Scalability is a concern but not the biggest concern.
Single
: The WCF runtime creates a new service object the first time a client calls the service. It keeps the object active for subsequent calls by any client.
- We want to share global data using service.
- Scalability is not a concern at all.
We will use LIbrary Application used in our first WCF service to see how it works. Let’s implement the same.
- First, we will create an empty web application named
Library
, which we will use later to consume our service.
- Now we have an empty application ready, let’s add services to this. We will use 3 tier architecture to implement this. Now we will add a new WCF project to our application, we will name it as
Library.Service.Click
on Application root and select Add -> New Project, select WCF from available project types.
- Now we will add 2 more WCF library projects to use as
ServiceContract
and DataContract
respectively. - First, we will create
DataContract
project, when project is delete the existing files, and add new class file, name it as Book
and add the properties in it. Refer to the class below:
using System.Runtime.Serialization;
namespace Library.DataContract
{
[DataContract]
public class Book
{
[DataMember]
public long BookId { get; set; }
[DataMember]
public string Name { get; set; }
[DataMember]
public string Author { get; set; }
[DataMember]
public string Publisher { get; set; }
[DataMember]
public string Subject { get; set; }
}
}
- The attributes
DataContract
and DataMember
tell the service, this class will take part in our service. If we don’t get the attributes, make sure we have the reference to System.Runtime.Serialization
in our project. - Now let’s move to
ServiceContract
part, delete all existing files from ServiceContract
project, and add new interface and name it as ILibraryManager
, we will have 2 methods AddNewBook
and RetriveBooks
, which will return list of books. Refer to the code below:
using Library.DataContract;
using System.Collections.Generic;
using System.ServiceModel;
namespace Library.ServiceContract
{
[ServiceContract]
public interface ILibraryManager
{
[OperationContract]
List<Book> AddNewBook(Book book);
[OperationContract]
List<Book> RetriveBooks();
}
}
- Also add the reference to
Library.DataContract
project: - Once reference is added, compile the
ServiceContract
project to see if we are going on the correct path. - Now add the reference of both
ServiceContract
and DataContract
to our Service project.
- Now we need to implement the interface in our service project, delete all files from the existing project, and add new WCF Service and name it as
LibraryManagerService
. It will add an interface as well, remove that interface and replace it with ILibraryManager
from Library.ServiceContract
. - To configure the instance management, decorate
LibraryManagerService
service with [ServiceBehavior]
attribute. We will configure the same service and see how it works with different properties. - First, let’s configure for
PerCall
Mode, which is default instance mode.
using Library.DataContract;
using Library.ServiceContract;
using System;
using System.Collections.Generic;
using System.ServiceModel;
namespace Library.Service
{
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
public class LibraryManagerService : ILibraryManager
{
private List<Book> _books = new List<Book>()
{
new Book { BookId=1,Author="Santosh",Name="Test Book",
Publisher="Test Publisher",Subject="Test" },
new Book {BookId=2,Author="Santosh",Name="Test Book",
Publisher="Test Publisher",Subject="Test" }
};
public List<Book> AddNewBook(Book book)
{
_books.Add(book);
return _books;
}
public List<Book> RetriveBooks()
{
return _books;
}
}
}
- Now let’s build the service project again to see if we are on the right path, if build is successful, also we are using dummy data here, in real case scenario, we will be using data access layer.
- Now browse the LibraryManagerService.svc file, we will see the metadata of service.
- Now let’s go to
Library
project, and add a new controller and name it as LibraryController
, we can choose Empty MVC5 controller. - Now add a new service reference to our project, right click on project and go to Add-> Service Reference, and follow the below steps:
- Change the collection type to generic list, and add the below code in controller file:
using Library.libraryService;
using System.Collections.Generic;
using System.Web.Mvc;
namespace Library.Controllers
{
public class LibraryController : Controller
{
[HttpGet]
public JsonResult Index()
{
List<Book> book = new List<Book>();
using (LibraryManagerClient client = new LibraryManagerClient())
{
Book b = new Book() { BookId = 3, Author = "Hiya",
Name = "Test Book", Publisher = "Sam", Subject = "Comedy" };
book = client.AddNewBook(b);
}
return Json(book, JsonRequestBehavior.AllowGet);
}
}
}
- Now start the Library application and browse the given URL in browser, we will get the list.
- You can try for another operation by yourself and try. Even if we make multiple calls, we will get the same result for different clients.
- Now let's see the next mode which is
PerSession
, change the property of ServiceBehavior
attribute to set it to PerSession
.
using Library.DataContract;
using Library.ServiceContract;
using System;
using System.Collections.Generic;
using System.ServiceModel;
namespace Library.Service
{
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
public class LibraryManagerService : ILibraryManager
{
private List<Book> _books = new List<Book>()
{
new Book { BookId=1,Author="Santosh",Name="Test Book",
Publisher="Test Publisher",Subject="Test" },
new Book {BookId=2,Author="Santosh",Name="Test Book",
Publisher="Test Publisher",Subject="Test" }
};
public List<Book> AddNewBook(Book book)
{
_books.Add(book);
return _books;
}
public List<Book> RetriveBooks()
{
return _books;
}
}
}
- Now build the application and update the solution and update the service reference, in per session state is maintained as per object created.
- Now let's see next mode which is
Single
, change the property of ServiceBehavior
attribute to set it to Single
. Single
we can use if we want to maintain some data globally, you can try both by yourself.
Conclusion
Instance management is another great feature from WCF, we can combine it with session management discussed in the last blog. Make sure you are using wsHttpBinding
to make it work.
In the next post, we will discuss concurrency and will start with transaction support in WCF.
You can follow my official Facebook page, also subscribe to my blog for more information.
You can also mail me on santosh.yadav19613@gmail.com in case you have any questions.