在其他几个方法的开头执行一个方法

时间:2013-07-17 23:28:34

标签: c#

我可能没有正确的话,但我已尽力了。

说我在c#中有一个函数,比如DoWork,在该函数中我想调用另一个函数,比如CheckScore()。但是,CheckScore()是我想从多个地方调用的通用函数。

所以在我的班级中,当我创建另一个函数DoWork2时,DoWork3是否有任何方法可以将CheckScore()作为第一行而不是每次都输入?

例如。我可以避免

string DoWork2(){
CheckScore()
}

而只是拥有

string DoWork2(){}

但是仍然执行CheckScore()?

4 个答案:

答案 0 :(得分:2)

一种潜在的,但仍然不是万无一失的方法是将安全检查抽象为属性。这样你就可以用以下方法装饰你的方法:

[CheckToken]
public string DoWork() {
  ....
}

这不一定是最好的答案,因为它仍然要求您归因于该方法。您可以为Web服务类创建一个属性,该属性将在类的任何方法调用上执行[CheckToken]。

[CheckToken]
public class MyWebService {
   ...
}

这里唯一的问题是,如果您有一些方法要执行不同的安全检查,或者没有安全检查。

C#Web服务框架具有相当好的安全功能,它包含在服务栈中。 http://www.servicestack.net/它已经内置了您可以使用的安全属性,并且可以促进关注点的清晰分离。

另一个非常强大的选项涉及拦截方法调用。 C#有一个类“ContextBoundObject”,可用于此目的。您需要让您的类继承自ContextBoundObject,然后您可以开始动态拦截方法调用,并根据正在进行的方法调用及其参数的上下文执行安全检查。 ContextBoundObject确实会给您的调用增加一些开销,因此您需要将其考虑在内。截取方法非常适用于安全性,性能监控,运行状况检查,方法重试以及其他交叉问题。

这是一篇关于ContextBoundObject(和面向方面编程)的简单入门文章。 http://www.codeproject.com/Articles/8414/The-simplest-AOP-scenario-in-C

对于J ......

我不会让方法代码查询结果。由于我们讨论的是Web服务,因此涉及一个管道,其中请求由客户端发起,该请求被发送到服务,该服务初始化其处理程序,反序列化请求,将请求路由到适当的方法,执行该方法,序列化响应,并将响应返回给客户端(这是一个很大的简化..)。我见过的大多数框架都有一些钩子可以指定服务方法的属性,这些属性在方法执行之前进行检查,并可用于处理安全性(即,为Web服务返回401 http代码)。我相信他说他正在使用WCF,虽然自从我使用WCF已经有一段时间了,但我知道这可以做到 - 请参阅http://msdn.microsoft.com/en-us/library/ms733071.aspx

因此,他可以从某个WCF安全属性派生自定义安全属性,并根据某些令牌创建自己的身份验证逻辑,而这些令牌最有可能必须从请求的标头中获取。 ServiceStack使这非常容易,我想它使用WCF也不是那么难。很可能有人已经为WCF完成了这项工作,代码就在那里。

答案 1 :(得分:0)

这可能不是您正在寻找的,但我会在访问分数时将“CheckScore”与该属性的getter相关联。这样,当使用该属性时,您感觉自己并没有写出很多CheckScore,并且每次在应用程序中调用任何旧方法时,您都没有调用CheckScore函数。

    private int _score;

    public int Score
    {
        get
        {
            CheckScore();
            return _score;
        }
    }

    public void DoWork1()
    {
        if (Score > 10) { 
           // Case 1
        }
    }

    public void DoWork2()
    {
        if (Score < 20) { 
          // Case 2
        }
    }

答案 2 :(得分:0)

鉴于注释中的其他信息,此问题的一个解决方案是创建一个小类来封装需要身份验证的方法:

abstract class AuthenticateClass
{
    private bool AuthenticateUser(){
        return true;  // do your authentication
    }
    public int Perform(){
        if (!AuthenticateUser()){
            return -1;
        } else 
            return AuthenticatedMethod();
    }

    protected abstract int AuthenticatedMethod();
}

这为您提供了一个执行身份验证的类,如果成功,则会执行您的方法。实现它像:

class SomeAuthentMethod : AuthenticateClass 
{
    protected override int AuthenticatedMethod()
    {
        return 10; // whatever method...
    }
}

并使用它:

 SomeAuthentMethod myMethod = new SomeAuthentMethod();
 if (myMethod.Perform() = -1){
     //  unable to authenticate user, please log in, etc
 }

如果身份验证通过,则返回10,否则返回-1(身份验证失败)。这使您可以生成任意数量的自动包含身份验证的方法。

或者,您可以使用静态类进行身份验证 - 例如:

static class Authenticate
{
    public delegate int MethodDelegate();

    private static bool AuthenticateUser(){
        return true;    // do your authentication
    }
    public static int Perform(MethodDelegate MyMethod){
        if (!AuthenticateUser())
        {
            return -1;
        }
        else return MyMethod();
    }
}

你可以在哪里:

private int myMethod(){
        return 10;  //whatever method...
}

然后执行:

if (Authenticate.Perform(myMethod) = -1){
     //  unable to authenticate user, please log in, etc
 }

显然,您可以扩展这两种模式,以处理抽象或静态类本身中的“未登录”或“未经过身份验证”的操作。这应该至少提供一些如何解决问题的想法。

答案 3 :(得分:0)

将CheckScore放入属性仍然会导致它被大量调用。

您可以使用私有只读字段并在构造函数中设置它。这将最大限度地减少对CheckScore的调用次数。

public class MyClass
{
    private readonly int _score;

    public MyClass()
    {
        _score = CheckScore();
    }

    public int Score
    {
        get
        {
            return _score;
        }
    }

    public void DoWork1()
    {
        if (Score > 10) { 
           // Case 1
        }
    }

    public void DoWork2()
    {
        if (Score < 20) { 
          // Case 2
        }
    }
}