Working with concurrency and complex WCF services that interact with shared application objects

I like to create and host WCF services. So far, I can create services that define contracts for services and data (interfaces), and define hosts and configuration parameters to achieve them (endpoint specifications).

Well, consider this piece of code defining a service and using it (no mention of the endpoints defined in app.config is shown here):

[ServiceContract] public interface IMyService { [OperationContract] string Operation1(int param1); [OperationContract] string Operation2(int param2); } public class MyService : IMyService { public string Operation1(int param1) { ... } public string Operation2(int param2) { ... } } public class Program { public static void Main(stirng[] args) { using (ServiceHost host = new ServiceHost(typeof(MyService))) { host.Open(); ... host.Close(); } } } 

Well, this structure is good at creating something that can be called an autonomous service. What if I need my service to use objects of a larger application. For example, I need a service that does something based on a specific collection defined somewhere in my program (which hosts the service). The service must search in this collection and search and return a specific item.

The list I'm talking about is a program-managed list edited and edited by him.

I have the following questions:

1) How can I create a service capable of handling this list? I know that a possible option uses the overloaded ServiceHost constructor, which takes an Object instead of a Type service. So I could pass on my list. It's good?

 [ServiceContract] public interface IMyService { [OperationContract] string Operation1(int param1); [OperationContract] string Operation2(int param2); } public class MyService : IMyService { private List<> myinternallist; public MyService(List<> mylist) { // Constructing the service passing the list } public string Operation1(int param1) { ... } public string Operation2(int param2) { ... } } public class Program { public static void Main(stirng[] args) { List<> thelist; ... MyService S = new MyService(thelist) using (ServiceHost host = new ServiceHost(S)) { host.Open(); ... host.Close(); // Here my application creates a functions and other that manages the queue. For this reason my application will edit the list (it can be a thread or callbacks from the user interface) } } } 

This example should clarify. Is this a good way to do it? Am i right?

2) How to handle conflicts on this shared resource between my service and my application? When my application starts by hosting the service, my application can insert items into the list and delete them, the service can do the same. Do I need a mutex? how to handle this? Note that the concurrency issue is affecting two participants: the main application and the service. It’s true that the service is single-user, but the application is listed !!! I assume that the service is called by an external object, when this happens, is the application still working correctly? Is there any concurrency in this case ???

Thankyou

+4
source share
2 answers

As for point 2, you can use Concurrent Collections to manage most of the required thread security.

I'm not sure what you mean by paragraph 1. It looks like you are describing basic polymorphism , but maybe you could clarify with an example please?

EDIT: In response to the comments you made to Sixto, consider using WCF sessions . From what you described, it sounds to me like a WCF service should sit on a separate host application. The application you are currently using must have a service link to the service, and using sessions can cause an operation that mimics your requirement to create a service instance using the list defined by the current client application.

Combine this with my comment on exposing operations that allow you to interact with this list, and you can run multiple client machines while working on saved session lists?

I hope this is explained quite well.

+1
source

Adding a constructor to MyService to pass a list will certainly work as you expected. As I said in my comment on the question, ServiceHost will only ever contain one instance of the MyService class, so the list will not be used, since only one instance of the service will use it.

I would look at the dependency injectors (DI) container for WCF to do what you are trying to do. Let the DI container provide an instance of the Singleton list for your services. Also @ Smudge202 is absolutely correct that using the Concurrent Collection function is what you need to implement a list.

UPDATE based on comments:

The DI approach will work by getting all the dependent objects from the DI container, rather than manually creating them in the code. You register all types that will be provided by the container as part of the application launch. When a new instance of an object is required for an application (or WCF), it requests it from the container instead of its newbies. Castle Windsor WCF integration library , for example, implements all the connections needed to provide a WCF instance of a service from a container. This post explains the details of using the Microsoft Unity DI container with WCF if you want to flip your own WCF integration.

The general list specified in this question will be registered in the container as an already created object from your application. When an instance of the WCF service is created from the DI container, all constructor options will be provided, including a link to the shared list. There is a lot of information about dependency injection and control inversion, but this article by Martin Fowler is a good place to start.

+1
source

All Articles