0

私はおそらく正しい言葉を持っていませんが、最善を尽くしました。

C# に DoWork などの関数があり、その関数内で CheckScore() などの別の関数を呼び出したいとします。ただし、CheckScore() は、複数の場所から呼び出したい汎用関数です。

私のクラスでは、別の関数 DoWork2、DoWork3 を作成するときに、毎回入力する代わりに最初の行として CheckScore() を実行する方法はありますか?

たとえば。避けられますか

string DoWork2(){
CheckScore()
}

代わりにただ持っている

string DoWork2(){}

しかし、CheckScore() はとにかく実行されますか?

4

4 に答える 4

2

可能性のある方法の 1 つは、まだ確実ではありませんが、セキュリティ チェックを属性に抽象化することです。このようにして、次のような方法でメソッドを装飾できます。

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

メソッドに属性を付ける必要があるため、これは必ずしも最良の答えではありません。代わりに、クラスのメソッド呼び出しで [CheckToken] を実行する Web サービス クラスの属性を作成することもできます。

[CheckToken]
public class MyWebService {
   ...
}

ここでの唯一の問題は、異なるセキュリティ チェックを実行するメソッドがある場合、またはセキュリティ チェックを実行しない場合です。

フレームワークに組み込まれた非常に優れたセキュリティ機能を備えた AC# 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 を参照してください。

そのため、WCF セキュリティ属性から独自のセキュリティ属性を取得し、トークンに基づいて独自の認証ロジックを作成できます。トークンは、おそらく要求のヘッダーから取得する必要があります。ServiceStack を使用すると、これが非常に簡単になります。WCF を使用してもそれほど難しくないと思います。誰かが既に WCF でこれを行っていて、コードがどこかにある可能性があります。

于 2013-07-18T03:34:17.407 に答える
0

コメントに追加情報がある場合、この問題の解決策の 1 つは、認証を必要とするメソッドをカプセル化する小さなクラスを作成することです。

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
 }

明らかに、これらのパターンの両方を拡張して、抽象クラスまたは静的クラス自体内の「ログインしていない」または「認証されていない」アクションを処理できます。これにより、少なくとも、問題へのアプローチ方法についていくつかのアイデアが得られるはずです。

于 2013-07-18T02:51:54.120 に答える
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
        }
    }
}
于 2013-07-18T03:13:09.703 に答える