using Actvator.CreateInstance to create object of class which is having private constructor?
By using Ac开发者_开发百科tivator.CreateInstance
we can create objects of a class, even if the constructor is private.
Is there anyway to prevent this?
Reflection breaks encapsulation in general. Any private member of any type (constructor, method, property, field, you name it) can be accessed using reflection (Activator.CreateInstance
falls under this umbrella).
That said, if you want your type not to be instantiatable via the overload of Activator.CreateInstance
generally used to overcome private
constructors, you could get rid of its parameterless constructor for your type altogether (by defining only constructors that take parameters).
You still can't do anything about someone using one of the overloads that specifies parameters, though.
The short answer: You can't
The more detailed answer: Read about .NET code access security. It's possible to run code in a limited-trust environment; partially trusted code can't bypass access restrictions. By default, code runs with full trust, and full-trust code can use reflection to access private members.
There is a way to prevent it from happening, but it's not pretty:
In the private constructor, you can add some checks based on the StackTrace
class. Create a new StackTrace
within your private constructor. Call GetFrames()
and iterate over them, checking to see if any of the frames contain a call from the Activator
type. Within the StackFrame
. you can query for the method via GetMethod
function. That returns a MethodBase
which inherits from MemberInfo
class. That will have the DeclaringType
property you care about.
As you iterate over the stack frame, if you notice that one the invoking types is the Activator
class, you know your private constructor is being called via that approach.
You should only need to look at two stackframes (skipping over your current one) to verify this. I believe that there is one other way besides the Activator
class to instantiate using reflection, but I don't remember it at this point.
I know it's an older post but I ran into it and I just couldn't resist.
There is a way to prevent Activator
to access the private constructor. For example in the Singleton pattern class using a nested class:
public sealed class SingletonClass
{
SingletonClass()
{
}
public static SingletonClass Instance
{
get
{
return InnerClass.instance;
}
}
class InnerClass
{
static InnerClass()
{
}
internal static readonly SingletonClass instance = new SingletonClass();
}
}
精彩评论