2012-09-30 7 views
8

ポスト "How to check if method has an attribute"を読んだ後、私は目を覚ます問題を解決するための一歩です。メソッドに属性(キャストと要約を含む)があるかどうかを確認する方法

public interface IFlyable 
{ 
    ActionResult Fly(); 
}  

public interface IRunnable 
{ 
    ActionResult Run(); 
} 

この抽象クラス

これらのインタフェース(私はASP.Net MVC 4で働いている):

私は状況を提示します
public abstract class SuperHero : Controller 
{ 
    public void SavePeople() 
    { 
    }  
} 

このコントローラ:

public class SuperManController : SuperHero,IFlyable,IRunnable { 

    [Authorize] 
    public ActionResult Fly(){ 
     // Flying... 
    }  

    [Authorize] 
    public ActionResult Run(){ 
     // Running... 
    }  

} 

(テスト用)この抽象クラス

[TestClass] 
public abstract class SuperHeroTest<TSuperHero>{ 

    protected abstract TSuperHero GetSuperHero(); 

    [TestMethod] 
    public void IfSuperHeroCanFlyMustHaveAuthorizeAttribute(){ 

     var superHero=GetSuperHero(); 

     if(superHero is IFlyable) 
     { 
      var superHeroFlyable = (IFlyable) superHero; 

      var have = MethodHasAuthorizeAttribute(() => superHeroFlyable.Fly()); 

      Assert.IsTrue(have); 
     } 

    } 
} 

そしてSuperManControllerをテストするためにSuperHeroTestから継承された最終的にはこのクラス:

[TestClass] 
public class SuperManControllerTest : SuperHeroTest<SuperManController>{ 

    private SuperManController _superManController; 

    public SuperManControllerTest(){ 
     _superManController=new SuperManController(); 
    } 


    protected override SuperManController GetSuperHero() 
    { 
     return _superManController; 
    } 

} 

方法MethodHasAuthorizeAttributeされています。私の問題はある(上記のポストから)

public static MethodInfo MethodOf(Expression<System.Action> expression) 
{ 
    MethodCallExpression body = (MethodCallExpression)expression.Body; 
    return body.Method; 
} 

public static bool MethodHasAuthorizeAttribute(Expression<System.Action> expression) 
{ 
    var method = MethodOf(expression); 

    const bool includeInherited = false; 
    return method.GetCustomAttributes(typeof(AuthorizeAttribute),includeInherited).Any(); 
} 

コールMethodHasAuthorizeAttribute(() => superHeroFlyable.Fly())SuperHeroTestクラス復帰falseで、それはtrueを返すべきとき。

SuperManControllerの実装方法Flyには、属性Authorizeがあります)。

FlyのメソッドのAuthorizeIFlyableに追加した後、trueを返します。

public interface IFlyable 
{ 
    [Authorize] 
    ActionResult Fly(); 
} 

私はMethodHasAuthorizeAttributeが実装ではなく、インタフェースを検査するために行うことができますどのように?

+0

ありがとう鳩編集のために! –

答えて

9

IfSuperHeroCanFlyMustHaveAuthorizeAttribute()メソッドをいくつか変更することで、動作させることができます。

コントローラがIFlyableインターフェイスを実装しているかどうか最初に確認します。その場合は、コントローラのFlyメソッドのMethodInfoを取得します。次に、返されたMethodInfoの属性をチェックするだけです。このようにして、インプリメンテーションにインタフェースの代わりに属性があるかどうかを確認します。 OK

次作品:

[TestClass] 
public abstract class SuperHeroTest<TSuperHero> 
{ 
    protected abstract TSuperHero GetSuperHero(); 

    [TestMethod] 
    public void IfSuperHeroCanFlyMustHaveAuthorizeAttribute() 
    { 
     var superHero = GetSuperHero(); 

     if (superHero is IFlyable) 
     { 
      var superHeroFlyable = superHero; 
      var method = typeof (TSuperHero).GetMethod("Fly"); 
      var hasAttribute = 
       method.GetCustomAttributes(typeof (AuthorizeAttribute), false).Any(); 
      Assert.IsTrue(hasAttribute); 
     } 
    } 

    public static MethodInfo MethodOf(Expression<System.Action> expression) 
    { 
     var body = (MethodCallExpression)expression.Body; 
     return body.Method; 
    } 

    public static bool MethodHasAuthorizeAttribute(Expression<System.Action> expression) 
    { 
     var method = MethodOf(expression); 
     const bool includeInherited = false; 
     return method.GetCustomAttributes(
      typeof(AuthorizeAttribute), includeInherited).Any(); 
    } 
} 
+0

それは完全に動作します!クリストフは本当にありがとう! –

+0

スーパーヒーローがIFlyableでない場合はテストに合格します。アサートはifブロックの外側になければなりません – Grokodile

関連する問題