2011-08-22 29 views
3

我有一个问题。优雅的解决设计模式的问题C#

我需要找到一种方法来根据某些用户权限动态地实例化类并动态激活这些类中的方法,并且还可以根据用户的要求进行分组。

例如:

1.用户权限 “A”

调用类1,4,6

调用方法2,7在类1

调用方法1,2级。

调用类6中的方法1,2。

2.用户权限 “B”

调用类2,3,5-

invoke方法2,7在类2

invoke方法1,2在3

invoke方法1,2在第5类。

我只是以不同的权限做这些例子。但它也可以包含分组,这意味着可以为每个权限调用不同的类和不同的方法(某种子集)。

我可以做任何事情与开关/案件,但我正在寻找一个更优雅的方式来做到这一点。

注:

  1. 也有很多人因为许多类的方法,因为许多不同类型分组,用户可以要求的可能性。

  2. 我不知道传递权限的最佳方式是什么。

  3. 我在想,也许命令模式或修饰器可以在这里帮助。

非常感谢您的回答!

+0

看起来你可能有3步算法,也许这可以通过[模板方法模式](http://en.wikipedia.org/wiki/Template_method_pattern)表达。 –

+0

精心制作分组条款。 – abatishchev

+0

如果没有这些类/方法正在做什么的硬性示例,很难提出建议。你说他们是不同的方法,但是他们是否都有共同的最终目标(认证用户,分配资源等)? – Ocelot20

回答

0

听起来像是您在寻找类似于CodeAccessPermissionAttribute的东西 - 有关详细信息,请参阅here。我可能会推荐一个类似这样的模式;定义具有属性的对象以关联其权限状态,然后您的用户将落入具有或不具有执行具有特定属性的方法的权限的角色中。

+0

有趣..... – Mandy

3

假设你可以访问类,一个方法是使用代理类和属性:

class PermissionVerifier { 
    public void ExecuteIfHasPermission(Permission perm, Action action) { 
     if (GetCurrentUser().HasPermission(perm)) // assumes singleton-like 
                // access or injected user 
      action(); 
     throw CreatePermissionException(perm); 
    } 
} 

class A { 
    // make it obvious what permissions are required for execution 
    [RequiresPermission(Permissions.CanExecuteClassAMethod1)] 
    public virtual void Method1() { 
     //... 
    } 

}  

class AProxy: A { 
    private PermissionVerifier verifier; 

    public override void Method1() { 
     ExecuteIfHasPermission(
      GetCurrentMethodRequiresPermissionAttribute(), // reflection 
      () => base.Method1()); 
    } 
    private ExecuteIfHasPermission(Permission perm, Action action) { 
     verifier.ExecuteIfHasPermission(perm, action); 
    } 
} 

相反,如果手动创建您使用动态代理生成器,拦截所有方法的代理,你可以显式执行权限检查,而无需手动编写大量样板代码。

+0

非常好,成熟! – Mandy

0

您可以通过使用Func <>将字符串绑定到类和方法调用。它在处理你正在处理的许多排列方面给你很大的灵活性。我有一个下面的代码的例子,但你可以使用枚举而不是字符串作为键。

这不一定是一种模式,但它可以用于已经提到的几种模式。

public void Call(Stream str) 
    { 
     //Single Permission 
     Generate["PermissionA"](str); 

     //Say this user has multiple permissions, you can iterate over them 
     IEnumerable<string> userPerms = GetUserPerms(); 
     foreach (var perm in userPerms) 
     { 
      Generate[perm](str); 
     } 
    } 

    public static Dictionary<string, Func<Stream, object>> Generate 
    { 
     get 
     { 
      var ret = new Dictionary<string, Func<Stream, object>>(); 

      ret.Add("PermissionA", (s) => 
             { 
              Class1 cl1 = new Class1(s); 
              Class4 cl4 = new Class4(s); 
              Class6 cl6 = new Class6(s); 

              cl1.Method2(); 
              cl1.Method7(); 
              cl4.Method1(); 
              cl4.Method2(); 
              cl6.Method1(); 
              cl6.Method2(); 

              cl1.DoXml(); 
              cl4.DoXml(); 
              cl6.DoXml(); 

              return ""; 
             }); 

      ret.Add("PermissionB", (s) => 
             { 
              Class2 cl2 = new Class2(s); 
              Class3 cl3 = new Class3(s); 
              Class5 cl5 = new Class5(s); 

              cl2.Method2(); 
              cl2.Method7(); 
              cl3.Method1(); 
              cl3.Method2(); 
              cl5.Method1(); 
              cl5.Method2(); 

              cl2.DoXml(); 
              cl3.DoXml(); 
              cl5.DoXml(); 

              return ""; 
             }); 

      return ret; 
     } 
    } 
+0

非常非常有趣....非常感谢你的努力。 – Mandy