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



我可能用词不对,但我已经尽力了。

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

因此,在我的类中,当我创建另一个函数DoWork2、DoWork3时,有没有任何方法可以将CheckScore()作为第一行执行,而不是每次都键入这些?

例如,我能避免吗

string DoWork2(){
CheckScore()
}

相反,只有

string DoWork2(){}

但是CheckScore()是执行的吗?

一种潜在的方法,尽管仍然不是万无一失的,是将安全检查抽象到属性中。通过这种方式,你可以用类似的东西来装饰你的方法:

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

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

[CheckToken]
public class MyWebService {
   ...
}

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

一个具有良好安全特性的C#web服务框架是service Stack。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做了这件事,代码就在某个地方。

这可能不是您想要的,但当访问分数时,我会将"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
        }
    }

将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
        }
    }
}

考虑到注释中的附加信息,这个问题的一个解决方案是创建一个小类来封装需要身份验证的方法:

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
 }

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

最新更新