12

I'm trying to new up a LocalCommand instance which is a private class of System.Data.SqlClient.SqlCommandSet. I seem to be able to grab the type information just fine:

Assembly sysData = Assembly.Load("System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
localCmdType = sysData.GetType("System.Data.SqlClient.SqlCommandSet+LocalCommand");

but Activator.CreateInstance throws an exception when I try to instantiate it:

object item = Activator.CreateInstance(localCmdType,
  new object[] { commandText, parameters, num7, commandType });

System.MissingMethodException: Constructor on type 'System.Data.SqlClient.SqlCommandSet+LocalCommand' not found.

The constructor arguments match the signature I see in Reflector. Is new'ing up a private class with an internal ctor supported with a different CreateInstance overload or what?

4 Answers4

22

My first thought would be to get the ConstructorInfo using ConstructorInfo constructorInfo = Type.GetConstructor(), and then constructorInfo.Invoke() that. I suspect that Activator.CreateInstance makes it hard to call constructors you wouldn't normally have access to, although I don't remember trying it myself.

ErikE
  • 48,881
  • 23
  • 151
  • 196
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 2
    The docs say CreateInstance only calls public constructors before 2.0sp1. After that, there's a bunch of permissions that are necessary. – Robert C. Barth Jan 13 '09 at 17:56
  • 1
    Good call on GetConstructor(), that does work. I find it strange considering that the GetConstructor call looks very similar to one of the Activator.CreateInstance() overloads. –  Jan 13 '09 at 22:20
19

I got it to work this way:

using System;
using System.Reflection;

class Test
{
    public String X { get; set; }

    Test(String x)
    {
        this.X = x;
    }
}

class Program
{
    static void Main()
    {
        Type type = typeof(Test);

        ConstructorInfo c = type.GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, 
            null, new Type[] { typeof(String) }, null);

        Object o = c.Invoke(new Object[] { "foo" });
    }
}

The trick was to go after the constructor specifically with GetConstructor rather then trying to find it in the results of GetConstructors. Go figure.

Andrew Hare
  • 344,730
  • 71
  • 640
  • 635
15

I might be a little late in responding, but I ran into a similar problem that fits into this topic.
I wanted to instantiate a non public constructor using Activator.CreateInstance and passing it arguments.

public class Node
{
    string name;
    Node parent;

    protected Node(string name,Node parent)
    {
       this.name = name;
       this.parent = parent;
    }

    public static Node Create(string name,Node parent)
    {
       Node result = Activator.CreateInstance(
         type: typeof(Node),
         bindingAttr: BindingFlags.Instance  | BindingFlags.NonPublic,
         binder: null, //default binder
         args: new object[] { name, parent },
         culture: null);
       return (Node)result;
    }
}

The tricky part was the binding flags.

My first instinct was to use BindingFlags.CreateInstance | BindingFlags.NonPublic, however that caused an exception to be thrown: MissingMethodException Constructor on type 'Node' not found.

Shimmy Weitzhandler
  • 101,809
  • 122
  • 424
  • 632
  • This fails for me with the error you describe but oddly, Andrew Hare's answer does work, even though both answers share the same binding flags. – Jerther Jun 25 '14 at 20:57
  • Simply does not work. Like Jerther said, Andrew Hare's answer does. –  Oct 01 '16 at 05:06
  • Worked like a charm for me! I too tried using ```BindingFlags.CreateInstance | BindingFlags.NonPublic``` and got the same error message. Changing it to ```BindingFlags.Instance | BindingFlags.NonPublic``` made it work!! – Kabua Jan 14 '17 at 17:32
0

Trick is to make sure to use the right CreateInstance overload:

// WRONG
... Activator.CreateInstance(
       type,
       BindingFlags.Instance
       | BindingFlags.NonPublic
    );

This calls the params overload, which will default to Instance | Public | CreateInstance, and your binding flags will be passed as arguments to the constructor, giving the vague MissingMethodException.

Also, use Instance | Public | NonPublic if you aren't sure of the visibility of the constructor:

// right
... Activator.CreateInstance(
       type,
       BindingFlags.Instance
       | BindingFlags.Public
       | BindingFlags.NonPublic,
       null,
       new object[] { }, // or your actual constructor arguments
       null
    );
Dave Cousineau
  • 12,154
  • 8
  • 64
  • 80