tags:

views:

35

answers:

2

Hi,

I have a need to run multiple WCF services at the same time, from a single windows service. Each WCF service is basically the same, but has one object specific to that instance. So with the following service class:

public class MyService : IMyContract
{
    public MyType MyObject { get; set; }

    public MyService(MyType myObject)
    {
        this.MyObject = myObject;
    }
    // more here...
}

I hoped I would be able to do something like this:

MyType o1 = new MyType();
MyService s1 = new MyService(o1);
ServiceHost host1 = new ServiceHost(s1, anEndpointAddress);
MyType o2 = new MyType();
MyService s2 = new MyService(s2);
ServiceHost host2 = new ServiceHost(s2, anEndpointAddress);

The problem is, that if you use the ServiceHost constructor that takes an object as its first argument, that object needs to be a singletonInstance, but I need multiple instances.

On the other hand, if I use the constructor which takes a type as its first argument (ServiceHost host = new ServiceHost(typeof(MyService), endpointAddress);), I don't know how I can set MyObject to a suitable value.

Is there a way to solve this problem?

Thanks, regards, Miel.

A: 

You need to plug-in your own ServiceHost.

First create your custom ServiceHost by inheriting it and implement your custom loading there. Then create a behaviour by implementing IServiceBehavior and modify ChannelDispatchers to set your own ServiceHost.

Have a look here for more info:

http://msdn.microsoft.com/en-us/library/aa395224.aspx

Aliostad
+1  A: 

I can think of two ways - way 2 will be preferred approach.

  1. Create multiple classes that simply inherits from your service class. For example,

    public class MyService1 : MyService { 
    ... // put a constructor that accepts your object 
    }
    public class MyService2 : MyService { ...  }
    
    
    ...
    

And now host as

MyType o1 = new MyType();
MyService s1 = new MyService1(o1);
ServiceHost host1 = new ServiceHost(s1, anEndpointAddress);
MyType o2 = new MyType();
MyService s2 = new MyService2(s2);
ServiceHost host2 = new ServiceHost(s2, anEndpointAddress);

If you don;t want singleton then you need to modify these classes such as

 public class MyService1 : MyService
{
   public MyService1() : base(new MyType()) { }
}

and then use another service host constructor

ServiceHost host1 = new ServiceHost(typeof(MyService1), anEndpointAddress);

2. I would prefer this approach. Service implementation will not have instance variable holding MyObject. Write custom ServiceHost class such as

public class MyServiceHost : ServiceHost
{
    public MyType MyObject { get; private set; }

   public MyServiceHost(Type serviceType, Uri[] baseAddresses, MyType myObject) 
     :base(serviceType, baseAddresses)
   {
     this.MyObject = myObject;
   }
}

Now, host your service on multiple endpoint addresses using

MyType o1 = new MyType();
ServiceHost host1 = new MyServiceHost(typeof(MyService, anEndpointAddress, o1);

In service methods, use OperationContext.Current.Host to get servicehost and from hostm you can get your object.

VinayC
Nr 2 is the one, indeed. The first only allows for a fixed number of services, which isn't flexible enough. I didn't know about OperationContext.Current.Host. And that's exactly what I needed. Thanks.
Miel