Reputation: 357
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.
Upvotes: 1
Views: 52
Reputation: 139187
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.
Upvotes: 1