Search code examples
c#.netdcom

How to get one DCOM Server per client


Due to the nature of the legacy code we need one DCOM server per client (lots of static and global data in the server code).

We have utilised the Enterprise Services .NET library to achieve a basic implementation.

Before we can fix it properly (which means months+ of work) we would like to have a usable system for 20 or so users which means one server per client.

Is this at all possible with .NET, C# and DCOM?

EDIT: (More Technical info) The client is a thread\session in a IIS Hosted process. We have a web api that logs into our server gets some data and logs out.


Solution

  • You can use COM+ Application Pooling for that. Inherit your service from ServicedComponent and set application activation to ActivationOption.Server using the ApplicationActivation attribute.

    You'd need to install your assembly into GAC which means you need to sign it and you need to register it with regsvcs.exe

    Then open Component Services snap-in in mmc.exe, find your newly registered application, open Properties, switch to Pooling & Recycling tab, set Pool Size to some reasonable value and set Activation Limit to 1. Also set Expiration Timeout for COM+ to shut down old processes.

    After that COM+ would create a new process for every new instance of your COM object that you'll be creating.

    Here's my sample code:

    using System.Diagnostics;
    using System.EnterpriseServices;
    using System.Runtime.InteropServices;
    
    [assembly: ApplicationActivation(ActivationOption.Server)]
    [assembly: ApplicationAccessControl(false)]
    
    namespace SingleUseServer
    {
        [ComVisible(true)]
        [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
        [Guid("6C3295E3-D9C9-40E3-AFBD-1398D4D1E344")]
        public interface IService
        {
            int GetProcessId();
        }
    
        [ComVisible(true)]
        [ClassInterface(ClassInterfaceType.None)]
        [ProgId("Test.Service")]
        [Guid("6B198197-3E88-4429-883D-A818E4E447D3")]
        public class Service : ServicedComponent, IService
        {
            public int GetProcessId()
            {
                return Process.GetCurrentProcess().Id;
            }
        }
    }