10

I have a factory class that needs to instantiate an unknown class. It does it as so:

public class Factory
{
    public void SetFoo(Type f)
    {
        Activator.CreateInstance(f);
    }
}

Problem is I'd like that constructor to be internal, but marking it internal gives me a MissingMethodException, but the constructor is in the same assembly. if it's set to puclic it works fine.

I've tried the solutions provided here How to create an object instance of class with internal constructor via reflection?

and here Instantiating a constructor with parameters in an internal class with reflection

which translates to doing as such:

Activator.CreateInstance(f,true)

but no success...

I'm using NETStandard.Library (1.6.1) with System.Reflection (4.3.0)

Update:

the answers provided at the time of this update pointed me in the right direction:

var ctor = f.GetConstructors(BindingFlags.Instance | BindingFlags.NonPublic);

var instance = (f)ctor[0].Invoke(null);

Thanks guys!

Athari
  • 33,702
  • 16
  • 105
  • 146
João Sequeira
  • 157
  • 3
  • 12

3 Answers3

19

BindingFlags:

var ctor = typeof(MyType).GetConstructors(BindingFlags.Instance | BindingFlags.NonPublic).FirstOrDefault(c => !c.GetParameters().Any());

var instance = (MyType)ctor.Invoke(new object[0]);

The BindingFlags gets the non public constructors. The specific constructor is found via specified parameter types (or rather the lack of parameters). Invoke calls the constructor and returns the new instance.

Patrick McDonald
  • 64,141
  • 14
  • 108
  • 120
Eric
  • 1,737
  • 1
  • 13
  • 17
3

First, you need to find the constructor:

var ctor = typeof(MyType).GetTypeInfo().GetConstructors(BindingFlags.NonPublic | BindingFlags.Instance).Single(x => /*filter by the parameter types*/);
var instance = ctor.Invoke(parameters) as MyType;

Please add a reference to the System.Reflection namespace.

Ricardo Peres
  • 13,724
  • 5
  • 57
  • 74
1

You can retrieve the constructor via reflection, and invoke it.

var ctor = typeof(Test)
    .GetConstructors(
        BindingFlags.NonPublic | 
        BindingFlags.Public | 
        BindingFlags.Instance
    )
    .First();
var instance = ctor.Invoke(null) as Test;
Maarten
  • 22,527
  • 3
  • 47
  • 68
  • you may want to filter out to parameter less constructor, else may run into `ArgumentNullExceptions` i.e. `.GetConstructors().First(c=>c.GetParameters().Length==0)` – zafar Aug 04 '21 at 18:34
  • @zafar The example in the question does not have a parameterless constructor. And the answer is more to show how it is done. – Maarten Aug 05 '21 at 08:32