我可能没有正确的话,但我已尽力了。
说我在c#中有一个函数,比如DoWork,在该函数中我想调用另一个函数,比如CheckScore()。但是,CheckScore()是我想从多个地方调用的通用函数。
所以在我的班级中,当我创建另一个函数DoWork2时,DoWork3是否有任何方法可以将CheckScore()作为第一行而不是每次都输入?
例如。我可以避免
string DoWork2(){
CheckScore()
}
而只是拥有
string DoWork2(){}
但是仍然执行CheckScore()?
答案 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
}
}
}