【问题标题】:Pass a class method name as a lamba expression将类方法名称作为 lambda 表达式传递
【发布时间】:2014-02-12 21:32:31
【问题描述】:

我正在为具有各种安全要求的各种客户端编写一些 api 调用的插件框架,以收集各种特定于业务的数据。所有插件都实现了IApiServiceEntryPoint,看起来像这样:

public interface IApiServiceEntryPoint : IDisposable
{
    /// <summary>
    /// Gets the name of the API Plugin
    /// </summary>
    string Name { get; }

    /// <summary>
    /// Registers the assembly in the application, sets up the routes, and enables invocation of API requests
    /// </summary>
    void Register();

    /// <summary>
    /// Gets the routing namespace of the plugin
    /// </summary>
    string UrlNameSpace { get; }

    /// <summary>
    /// Validates the user is authorized to invoke the supplied method.
    /// </summary>
    /// <param name="methodName"></param>
    bool IsAuthorized(string methodName);

    /// <summary>
    /// The user initiating the API call
    /// </summary>
    IPrincipal User { get; }
}

请注意IsAuthorized 方法。我的意图是允许插件确定特定的IPrincipal 是否被授权调用具体类中的特定方法。使用字符串是可行的,但我宁愿更具体和可重构一些;例如,使用 lambda 表达式。

目前,我可以在我的 API 控制器中执行类似的操作:

    [HttpGet]
    public DateTime GetSystemTimeStamp()
    {
        if (IsAuthorized("GetSystemTimeStamp"))
        {
            return DateTime.UtcNow;
        }
        throw new AuthorizationException();
    }

我想做的是这样的:

   [HttpGet]
    public DateTime GetSystemTimeStamp()
    {
        if (IsAuthorized(me => me.GetSystemTimeStamp))
        {
            return DateTime.UtcNow;
        }
        throw new AuthorizationException();
    }

如何在我的界面中声明它,以及如何在IsAuthorized 方法中提取方法的名称来检查授权?

【问题讨论】:

    标签: c# reflection interface lambda delegates


    【解决方案1】:

    你不需要 lambda;您可以直接将方法作为委托传递:

    public bool IsAuthorized<T>(Func<T> method) {
        string name = method.Method.Name;
    }
    if (IsAuthorized(GetSystemTimeStamp))
    

    对于您想要接受的每种方法,您都需要单独的 Func&lt;,,,T&gt; 重载;他们都可以简单地调用一个采用Delegate的通用方法。
    或者,您可以只创建一个采用Delegate 的方法,然后在每个调用点显式创建一个委托。

    【讨论】:

    • 当然,现在如果有人确实传入了一个 lambda,它会大笑的。
    • @Servy:它不会大笑;它将返回一个奇怪的编译器生成的名称。您可以通过查找 CompilerGeneratedAttribute 来检查。
    • 而最糟糕的情况是IsAuthorized 检查默认为 false :P
    • 是的,但这不是 OP 想要的,而且因为它是编译的,而不是 Expression,所以没有真正好的方法可以在该匿名方法中调用该方法。所以它不会工作,即使它可以编译和运行而不会抛出异常。我并不是说这不是一个好的解决方案,因为它是,我只是明确指出,如果你要使用它,你需要明确not 使用 lambda。让它与 lambdas 一起工作需要额外的努力。
    • 太棒了。我想多了。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多