views:

80

answers:

2

I have tried to make a webservice interface to a state-holding COM component.

The webservice basically contains operations Start, Shutdown and GetCurrentState.

Start creates a COM component, Stop releases. And GetCurrentState retrieves information from the COM component.

It seemed an easy thing, but after a day it still refuses to work.

I have tried storing the COM-reference as a member variable in the C# object. The object is constantly re-created. Then I tried to store the COM-reference in the Session object. But still, something is still wrong.

Anyone know how one should store COM reference which should stay alive inside webservices?
/L

+2  A: 

Web service by its nature is stateless. Try creating Windows service and using Web service to control it. Start method would start Windows service and that service would instantiate COM-component. GetCurrentState method would communicate with the service and grab COM reference.

Another approach is to make your COM component COM+ accessible:

  1. Open Administrative Tools -> Component Services.
  2. Open COM+ Applications node.
  3. Create new application. Select "Create an empty application" in the first wizard step. Type application name and select "Server application" option in the next step.
  4. Create new component. Select "Install new component(s)" in the wizard. Locate and select your COM dll.
  5. Go to component properties and enable object pooling. Set minimum and maximum pool size to 1. This will make your component a singleton.
Pavel Chuchuva
+3  A: 

Hi there,

Assuming you are using ASMX here, and not WCF where you could control the life time little bit differently, each time a request comes in the class that services the request is recreated. This is the standard behaviour for ASMX.

What you need to do is store the COM object either inside the Cache[] or Application[] collections. It may still get destroyed when the worker pool is recycled. Some code like this is what you need:

public FooClass GetFooClassInstance()
{
    FooClass instance = (FooClass)this.Context.Application["FooClassInstance"];

    if (instance == null)
    {
        instance = new FooClass(); // Creates the RCW.
        this.Context.Application["FooClassInstance"] = instance;
    }

    return instance;
}

The FooClass is the runtime callable wrapper for your COM object. The Application object contents is retained between requests. One thing you do need to watch out for is the threading model that the COM component is using as some can cause performance problems because they marshal calls onto a single thread.

Mitch Denny
@Mitch: you need to lock after the null check, check for null again, then create the new instance.
John Saunders