Why is my COM object not displaying methods in Component Services?

2k views Asked by At

I am trying to create a COM object and register it under COM+. Everything seems to go well, but when I look in Component Services and drill down through

Console Root | Component Services | Computers | My Computer | COM+ Applications | TestCom | Components | TestCom.Com.MyCom | Interfaces | _MyCom | Methods

I do not see my method listed.

In my project properties I have signed my assembly.

AssemblyInfo.cs:

[assembly: ApplicationName("TestCom")]
[assembly: ApplicationAccessControl(false)]
[assembly: ApplicationActivation(ActivationOption.Server)]
[assembly: ComVisible(true)]

MyCom.cs

using System; using System.EnterpriseServices;

namespace TestCom.Com
{
    [Transaction(TransactionOption.Required)]
    public class MyCom : ServicedComponent
    {
        [AutoComplete]
        public int GetIntFromCom()
        {
            var results = new Random(DateTime.Now.Second).Next();
            return results;
        }
    }
}

I build the dll and in the VS2012 command prompt I run regsvcs TestCom.Com.dll. This results in:

Installed Assembly:
Assembly: c:\TestCom.Com.dll
Application: TestCom
TypeLib: c:\TestCom.Com.tlb

I must be missing something, I just can't figure out what it is.

1

There are 1 answers

0
Hans Passant On BEST ANSWER

You are using default settings here. The default interface supported by [ComVisible] objects is IDispatch, good only for late-binding. It is the way Microsoft prefers, lots less misery when the client code assumes a different version of the component, a problem known as DLL Hell. Scripting languages always use IDispatch and don't need the methods to be visible. Compiled languages usually support early binding, you can add the type library and you'll get syntax error checking and auto-completion as well as greatly improved runtime performance. A great convenience while programming, but very risky when DLL Hell strikes.

If you want to see the methods then you have to use the [InterfaceType(ComInterfaceType.InterfaceIsDual)] attribute on the public interfaces you declare. Which exposes IDispatch and the interface type in the type library. You won't have the auto-generated _MyCom interface anymore, you see your own. You'd typically call it IMyCom.

That requires declaring the interface explicitly so you can apply the attribute. Usually a bit of an inconvenience if you didn't start out that way. You can also apply [ClassInterface(ClassInterfaceType.AutoDual)] to the public class you expose. With the disadvantage that you also expose the members of System.Object and take a dependency on the .NET Framework type library. Which is okayish.