判断一个方法是否是策略注入中的属性的最佳方法是什么?

Mat*_*sto 3 c# enterprise-library policy-injection

我有一个应用于类的自定义处理程序(使用 entlib 4 中的策略注入应用程序块),我想知道调用 Invoke 时输入方法是否是一个属性。以下是我的处理程序的样子。

[ConfigurationElementType(typeof(MyCustomHandlerData))]
public class MyCustomHandler : ICallHandler
{
    public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
    {
        if (input.MethodBase.IsPublic && (input.MethodBase.Name.Contains("get_") || input.MethodBase.Name.Contains("set_")))
        {
            Console.WriteLine("MyCustomHandler Invoke called with input of {0}", input.MethodBase.Name);
        }
        return getNext().Invoke(input, getNext);
    }

    public int Order { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

正如您从我的代码示例中看到的,到目前为止我想到的最好方法是解析方法名称。难道没有更好的方法吗?

Shu*_*oUk 5

您还可以检查 IsSpecialName 是否为 true。这在房产中也是如此(除其他外)

在il级别,方法公开如下(使用Environment.ExitCode作为示例):

.method public hidebysig specialname static int32 get_ExitCode() cil managed
.method public hidebysig specialname static void set_ExitCode(int32 'value') cil managed
Run Code Online (Sandbox Code Playgroud)

如果你想变得更奇特,你可以在提取名称后验证该属性是否存在,但说实话

if (m.IsSpecialName && (m.Attributes & MethodAttributes.HideBySig) != 0)) 
Run Code Online (Sandbox Code Playgroud)

以及以 get_ 或 set_ 开头,那么即使对于使用令人讨厌的名称的人也应该很好(伪造 hidebysig 很容易,伪造 IsSpecialName 将非常棘手)

但没有什么是可以保证的。有人可以发出一个带有 set_Foo 方法的类,该方法看起来就像真正的 set 方法,但实际上不是只读属性上的集合。除非你检查属性是否为CanRead/CanWrite。

尽管你并没有预料到会被故意规避,但我觉得这对你来说是疯狂的。MethodInfo 上执行此逻辑的简单实用程序/扩展方法不会太难,并且包含 IsSpecialName 几乎肯定会满足您的所有需求。