在我的代码中,我只需要允许类GetStorePrivateData,,EchoProcess,,方法,从类,MainData,,.I,这不是更好的方法,但是在这段代码中,它工作,done.How,我应该这样做吗?
**在以后的类中,MainData将拥有更多受保护的类,并允许特定的其他类调用它。
internal sealed class EchoProcess : MainData
{
private EchoProcess()
{
}
public static string EchoPrivate(string someCondition)
{
var result = GetStorePrivateData<EchoProcess, Key>();
//Condition here >
return "";
}
private class Key
{
}
}
internal class MainData
{
protected MainData()
{
}
private static readonly List<string> StorePrivateData = new List<string>();
protected static List<string> GetStorePrivateData<TEcho, TKey>() where TEcho : class where TKey : class
{
return CheckAllowGetStorePrivateDataClassAccess<TEcho, TKey>() ? StorePrivateData : null;
}
private static bool CheckAllowGetStorePrivateDataClassAccess<TEcho, TKey>()
{
var thisClass = MethodBase.GetCurrentMethod().DeclaringType;
var echoProcessType = typeof(TEcho);
var isEchoProcess = echoProcessType.Name == "EchoProcess";
var keyType = typeof(TKey);
var isKey = keyType.Name == "Key";
var isEqualNameSpace = thisClass.Namespace.Equals(echoProcessType.Namespace) &&
keyType.Namespace.Equals(echoProcessType.Namespace);
var keyTypeFullName = $"{echoProcessType.FullName}+{keyType.Name}";
var isEqulaKeyTypeNameSpace = keyType.FullName.Equals(keyTypeFullName);
return isEqualNameSpace && isEqulaKeyTypeNameSpace && isEchoProcess && isKey;
}
}发布于 2018-02-17 00:59:24
在我的代码中,我只需要允许类
EchoProcess调用方法GetStorePrivateData从类MainData。
不使用反射或堆栈跟踪来完成这些操作。
这两种类型都是internal。他们在同一个集会上。将希望限制调用者的方法标记为internal。现在,程序集中的任何代码都可以调用该方法。,谁在乎呢?您编写了该代码;如果您不喜欢它,可以更改它。
这个问题应该通过与编写程序集的编码人员进行通信来解决,这些代码编写程序说明了使用程序集实现详细信息的正确协议是什么。这是一个人际关系问题,所以不要试图通过编写代码来解决它。将该方法标记为内部方法,如果有您不喜欢的调用站点,请与在代码评审期间编写该方法的开发人员交谈,找出他们为什么认为这是个好主意。
发布于 2018-02-17 00:17:30
在将来的类中,MainData将有更多的受保护类,并允许特定的其他类调用它。
很高兴听到这个..。下面我提供的解决方案并不理想(例如,您在编译时不会得到任何错误),而且有些对象模型可能更适合于此。
在我的代码中,我只需要允许来自MainData.I类的类EchoProcess调用方法GetStorePrivateData,我认为这不是更好的方法,但是在这段代码中,它可以工作done.How,我应该这样做吗?
编写检查调用堆栈的代码非常容易(您可以使用var s = new StackTrace()获得副本,用s.GetFrames()遍历堆栈)。您可以遍历调用堆栈,查看EchoProcess是调用方还是来自其他地方的调用。下面是一个简单的例子:
static public class CallPermissionHelper
{
static public bool IsAllowed<T>() where T : class
{
var callers = new StackTrace()
.GetFrames()
.Select
(
f => f.GetMethod().DeclaringType
);
var immediateCaller = callers.ElementAt(1);
var firstOutsideCaller = callers
.Skip(2)
.Where
(
t => t != immediateCaller
)
.FirstOrDefault();
return (firstOutsideCaller == typeof(T));
}
}逻辑很简单:
MainData。我们可以忽略该类中的任何堆栈帧,例如,如果它正在调用自己或使用实用程序函数,因为它显然拥有调用自己的权限。EchoProcess,则返回true。在所有其他情况下,我们返回false。下面是如何在您的示例中使用它:
internal sealed class EchoProcess : MainData
{
private class Key {}
public static string GetPrivateFromMainData()
{
return MainData.GetStorePrivateData<EchoProcess, Key>();
}
}
internal class MainData
{
public static string GetStorePrivateData<TEcho, TKey>() where TEcho : class where TKey : class
{
var allowed = CallPermissionHelper.IsAllowed<EchoProcess>(); //Magic!!!
return allowed ? "Allowed" : "Blocked";
}
}
public class Program
{
public static void Main()
{
var a = EchoProcess.GetPrivateFromMainData();
var b = MainData.GetStorePrivateData<object, object>();
Console.WriteLine("a={0}", a);
Console.WriteLine("b={0}", b);
}
}输出:
a=Allowed
b=Blockedhttps://stackoverflow.com/questions/48836518
复制相似问题