Instantiating Internal class with private constructor
EDIT: I hadn't noticed that you mentioned that the type you're trying to initialize is part of the .NET framework. I thought it was one of your own types, just referenced from elsewhere.
I would strongly urge you not to attempt this. Microsoft are perfectly at liberty to change or remove internal classes between framework releases - your code will be incredibly brittle if you rely on implementation details like this.
Change your design to avoid needing to do this.
Original answer:
Yes, you'd have to use reflection - like this:
using System;
using System.Reflection;
internal sealed class ABC
{
private ABC(string password)
{
Console.WriteLine("Constructor called");
}
}
public class Test
{
static void Main()
{
ConstructorInfo ctor = typeof(ABC).GetConstructors
(BindingFlags.Instance | BindingFlags.NonPublic)[0];
ABC abc = (ABC) ctor.Invoke(new object[] { "test" });
}
}
Note that violating access modifiers in this way requires the ReflectionPermissionFlag.MemberAccess
permission. If you know there will be a static method called Create
, you'd be better off invoking that via reflection:
using System;
using System.Reflection;
internal sealed class ABC
{
private ABC(string password)
{
Console.WriteLine("Constructor called");
}
public static ABC Create(string password)
{
return new ABC(password);
}
}
public class Test
{
static void Main()
{
MethodInfo method = typeof(ABC).GetMethod("Create",
BindingFlags.Static | BindingFlags.Public);
ABC abc = (ABC) method.Invoke(null, new object[]{"test"});
}
}
First of all, the very fact that it is internal means you're not supposed to be doing what you want to do.
You should seriously try to find an alternate route to what you want to accomplish.
Unfortunately, you don't tell us what you want to accomplish, only the next step you think you want to do, so that's what I can help you with.
This code will work, and accesses the public static method:
Type t = typeof(SomeOtherTypeInSameAssembly)
.Assembly.GetType("ClassLibrary1.ABC");
MethodInfo method = t.GetMethod("Create",
BindingFlags.Public | BindingFlags.Static, null,
new Type[] { typeof(String) },
new ParameterModifier[0]);
Object o = method.Invoke(null, new Object[] { "test" });
Note that this relies on having access to another type in the same assembly, that is public. If you don't have that, you need to get hold of the Assembly object that contains the type.
If it's internal
to an assembly that is not yours and the constructor is marked as private
, the author of the assembly is trying very hard to keep you from creating the object.
The below is really evil as you're relying on non-public classes and methods which could change on you without advance notice.
Added:
System.ServiceModel.Channels.SelfSignedCertificate
is theinternal
class I am trying to use
Do not do this. The framework could change under you in the blink of an eye ruining your code and all of your hard work.
That said, you could do this:
MethodInfo method = Type.GetType(assemblyQualifiedName).GetMethod("Create");
ABC o = (ABC)method.Invoke(null, new[] { "test" });
This invokes the static
method Create
. Another option is
MethodInfo method = Type.GetType(assemblyQualifiedName).GetConstructor(
BindingFlags.NonPublic | BindingFlags.Instance,
null,
new[] { typeof(string) },
null
);
ABC o = (ABC)method.Invoke(new[] { "test" });
which uses reflection to load the constructor that accepts a string
as a parameter.
An easy way to get the assembly-qualified name is
string name = typeof(somePublicType).Assembly.GetType("Namespace.ABC");
where somePublicType
is a type that is public and in the same assembly as ABC
.
Use the Activator class to instantiate it
Activator.CreateInstance(myType, true);