2012-01-01 1 views
1

私はビジネスオペレーション(またはその名前)をデータベースに入れて、ユーザーロール(認可用)にリンクして通知をセットアップすることを検討していますシステムを操作します。ビジネスオペレーションのモデリング:コードに名前をリンクする

問題は、データベース(「Customer.New」または「Customer.View」などの文字列で表される可能性が高い)をシステムで実行されるコードに変換する方法です。私が思いついた方法のほとんどは、クルージングのように見えます。

例1 - すべての操作

public static object RunOperation(string Op, string User, params object[] Parms) 
{ 
    switch(Op) 
    { 
     case "Customer.View": 
      return BLL.Facade.GetCustomerById((int)Parms[0]); 
      break; 
     case "Customer.New": 
      return BLL.Facade.CreateCustomer(Parms[0] as Customer); 
      break; 
     ... 
    } 
} 

を処理するための一般的な方法私はこれについて嫌いなものはすべて鋳物です。しかし、承認はかなり簡単です。 Authorize(Op, User);

は、この方法があります:

[BusinessOp("Customer.New")] 
public static int CreateCustomer(Customer NewCustomer) 
{ 
    ... 
} 

しかし、私は、私が承認メソッドにcreateCustomerのメソッドの参照を渡す必要があります(と異なるOPSは別の方法を持っていると仮定するので、認可は、少しグラグラです署名)。次に、Authorizeメソッドはリフレクションを使用してBusinessOpAttributeを検索し、操作の文字列名(データベース内の表現方法)を取得する必要があります。

私は、操作の文字列名を表す一連の定数を作成し、それをAuthorizeメソッドに使用するだけで、操作を実行する時間が来たときにビジネスメソッドを呼び出すことができます。しかし、私はまだ、すべての関係者にビジネスオペレーションを表す1つの項目(メソッドまたは文字列)を持っていません。

誰もこの経験がありますか、私が考えていない別のオプションがありますか?最終的には受け入れ答えとコメントを通じて決定

ANSWER

。私は各ビジネスオペレーションのクラスを作っていきます。

[BusinessOperation] 
public static class CustomerNew 
{ 
    public const string Key = "Customer.New"; 

    public static bool Authorize(string UserName) // or perhaps IPrincipal User 
    { 
     // Authorize method will use key to check against database 
     ... 
    } 

    public static int Invoke(Customer NewCustomer) 
    { 
     // Invoke method has well-defined parameters 
     ... 
     // Can also use key to notify listeners of operation completion 
    } 
} 

答えて

0

同様の問題を処理する方法は、実際の操作で指定されたクラスの具体的なメソッドを表現することです。これの最大の問題はparamsです。私たちはこれを常に処理方法に委ねます。

だからあなたの場合には、私は次のようにリファクタリングします:私はCustomerFacadeにファサードを変更し、このCustomerFacadeで、にgetCustomerByIdは、ビューに変更することを

var asValues = Op.Split('.'); 

switch(asValues[0].ToLower()) 
{ 

    case "customer": 
     Type type = typeof(BLL.CustomerFacade); 

     System.Reflection.MethodInfo method = type.GetMethod(asValues[1], System.Reflection.BindingFlags.IgnoreCase); 

     if (method != null) 
     { 
      return method.Invoke(BLL.CustomerFacade, Parms); 
     } 
     break; 

注意。これは、これにアプローチする単なる方法です。

また、すべてを単一のファサードに保持し、メソッド名をCustomerViewに変更することもできます。また、既存のファサード名に依存する他のコードがある場合は、オペレーション名を変更するか、要求を正しい基礎となるファサードメソッドにリダイレクトするリダイレクトメソッドを追加することができます。

これはおそらく実装に応じて調整する必要がありますが、一般的な考え方が必要です。

この方法の利点は、新しい操作を実装するたびにこのメソッドを更新する必要がないことです。

+0

ありがとうございました。呼び出し元のメソッドは、呼び出すメソッドの内部的な詳細を知っていなければなりません(どのパラメータを渡すかを正確に知っていなければならない)ので、カプセル化の原則に違反します。しかし、私がより良い解決策を見つけることができない場合、私はこのようなことをやり遂げるかもしれません。 –

+0

@ KaseySpeakman:私は同意する、それは鶏と卵の状況のようなものです。ただし、メソッドのパラメータを調べて呼び出し元に適切な値を問い合わせることで、制御を逆転させることができます。たとえば、呼び出し側によって実装されるValueFetchインタフェースを追加し、名前に基づいてパラメータの値を提供したり、リフレクションを使用したりすることができます(実装クラスにはプロパティに格納された値があると仮定します)。次に、param配列の代わりに実装するインスタンスを渡します。 –

+0

私は、AuthorizeメソッドとInvokeメソッドを持つ各ビジネスオペレーションのクラスと、そのオペレーションのデータベース名であるconst Keyを作成することを考えています。 Authorizeメソッドはキーを使用して操作を承認しますが、Invokeメソッドには明確なパラメータがあります。それは余分な仕事ですが、反射を避けています。思考? –

関連する問題