I would like to have my classes exposed without displaying the base methods Equals(), GetHashCode(), GetType(), ToString(). I also want Intellisense to work properly. Here is my sample code:
using System;
using System.IO;
using System.Runtime.InteropServices;
namespace InteropTest
{
[ClassInterface(ClassInterfaceType.AutoDual),
ComVisible(true)]
[ProgId("InteropTest.Wrapper")]
public class Wrapper
{
public string Text1 = "hello";
public string Text2 = "world";
public Class1 Class1 = new Class1();
public Class2 Class2 = new Class2();
}
[ClassInterface(ClassInterfaceType.AutoDual),
ComVisible(true)]
public class Class1
{
public string Method1a(string myText)
{
return myText;
}
public string Method1b(string myText)
{
return myText;
}
}
[ClassInterface(ClassInterfaceType.AutoDual),
ComVisible(true)]
public class Class2
{
public string Method2a(string myText)
{
return myText;
}
public string Method2b(string myText)
{
return myText;
}
}
}
When I use [ClassInterface(ClassInterfaceType.None), ComVisible(true)], I can see the 2 properties in the Wrapper class, but I cannot see, nor access, Class1 or Class2.
When I use this class, I expect to be able to create the object and use it as well as see the appropriate Intellisense for the inner class objects.
o = CreateObject("InteropTest.Wrapper")
o.Class1.Method1a("Some text")
I guess, my real question is, how do I setup my classes for COM and make both Class1 and Class2 visible without displaying the extra methods?
I also tried using the refactor tool to extract the interfaces, but I could not get those to work the way I want to work, either. I don't want to put in any funky work-arounds, either.
Using AutoDual
on classes exposes every public method of the class automatically. To avoid that you can use AutoDual
interfaces instead and implement it. Something like this should be equivalent:
[InterfaceType(ComInterfaceType.InterfaceIsDual), ComVisible(true)]
public interface IWrapper
{
string Text1 { get; set; }
string Text2 { get; set; }
IClass1 Class1 { get; set; }
IClass2 Class2 { get; set; }
}
[ClassInterface(ClassInterfaceType.None), ComVisible(true)]
[ProgId("InteropTest.Wrapper")]
public class Wrapper : IWrapper
{
public string Text1 { get; set; } = "hello";
public string Text2 { get; set; } = "world";
public IClass1 Class1 { get; set; } = new Class1();
public IClass2 Class2 { get; set; } = new Class2();
}
[InterfaceType(ComInterfaceType.InterfaceIsDual), ComVisible(true)]
public interface IClass1
{
string Method1a(string myText);
string Method1b(string myText);
}
[ClassInterface(ClassInterfaceType.None), ComVisible(true)]
public class Class1 : IClass1
{
public string Method1a(string myText) => myText;
public string Method1b(string myText) => myText;
}
[InterfaceType(ComInterfaceType.InterfaceIsDual), ComVisible(true)]
public interface IClass2
{
string Method2a(string myText);
string Method2b(string myText);
}
[ClassInterface(ClassInterfaceType.None), ComVisible(true)]
public class Class2 : IClass2
{
public string Method2a(string myText) => myText;
public string Method2b(string myText) => myText;
}
Note .NET fields have been replaced by .NET properties since you cannot define fields in interfaces, but at COM level it shouldn't change anything.