Как запретить вызов метода C#
Я хочу разрешить вызов метода только из определенных методов. Посмотрите на код ниже.
private static void TargetMethod()
{
}
private static void ForbiddenMethod()
{
TargetMethod();
}
private static void AllowedMethod()
{
TargetMethod();
}
Мне нужно только AllowedMethod может вызвать TargetMethod. Как это сделать с помощью классов из System.Security.Permissions
?
Обновлено: спасибо за ваши ответы, но я не хочу спорить о дизайне моего приложения. Я просто хочу знать, возможно ли это сделать с помощью.net security или нет?
7 ответов
CAS не может сделать это, если код работает с полным доверием.
Если код выполняется в режиме полного доверия (т. Е. Обычное локальное приложение, а не приложение silverlight или что-то запускаемое из сети), то все проверки.NET CAS полностью игнорируются; любой атрибут безопасности просто игнорируется.
CAS просто обходит стек, чтобы определить разрешения, и вы можете сделать это тоже, как указывал ранее Дарин, просто проверив StackTrace
,
Вы можете решить это, используя обычный объектно-ориентированный дизайн. Переехать AllowedMethod
в новый класс и сделать ForbiddenMethod
приватный метод этого класса:
public class MyClass
{
public void AllowedMethod() { // ... }
private void TargetMethod() { // ... }
}
AllowedMethod имеет доступ к закрытым членам, но никто другой не имеет.
Я считаю, что вы должны попытаться структурировать свой код в значимых классах и использовать стандартные модификаторы доступа (private
, protected
, public
, internal
). Есть ли какая-то конкретная причина, по которой это не решило бы вашу проблему?
Единственная альтернатива, о которой я могу подумать, - это прохождение стека вызовов внутри вызываемого абонента, но это, скорее всего, приведет к путанице кода и неоптимальной производительности.
Вы можете проверить стек вызовов для достижения этой цели, но это довольно медленно. Я не рекомендовал бы это, если этого можно избежать.
Если вы все еще хотите это сделать, вам следует быть осторожным, чтобы избежать встраивания методов, иначе ваш код может внезапно перестать работать в сборках Release.
[MethodImpl(MethodImplOptions.NoInlining)]
private static void TargetMethod()
{
StackFrame fr = new StackFrame(1, false);
Console.WriteLine(fr.GetMethod().Name);
}
Насколько я знаю, нет никаких готовых атрибутов для этого.
Я не уверен, что это достижимо с System.Security.Permissions
, но внутри TargetMethod
Вы можете получить звонящего и действовать соответственно:
StackTrace stackTrace = new StackTrace();
Console.WriteLine(stackTrace.GetFrame(1).GetMethod().Name);
Возможно, вы сможете использовать объекты CodeAccessPermission. Вы должны будете реализовать интерфейс в своем собственном объекте, чтобы он работал так, как вы предлагаете.
http://msdn.microsoft.com/en-us/library/system.security.codeaccesspermission.aspx
Используя атрибуты, вы можете решить эту проблему.
Используйте условные атрибуты.
На вершине
#define "Show"
public void TargetMethod()
{
//Code
}
[ Conditional("Hidden")]
public void HiddenMethod()
{
TargetMethod()
}
[ Conditional("Show")]
public void AllowMethod()
{
TargetMethod()
}
Будет назван один из ваших методов.