See the question and my original answer on StackOverflow

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.