2012-09-30 6 views
8

Nach dem Lesen der Post "How to check if method has an attribute" bin ich ein Schritt, um ein Problem zu lösen, das mich wach hält.Wie überprüft man, ob Methode ein Attribut hat (mit Schnittstellen, Casting und Abstract)

stelle ich die Situation:

(Ich arbeite mit ASP.Net MVC 4)

Diese Schnittstellen:

public interface IFlyable 
{ 
    ActionResult Fly(); 
}  

public interface IRunnable 
{ 
    ActionResult Run(); 
} 

Diese abstrakte Klasse:

public abstract class SuperHero : Controller 
{ 
    public void SavePeople() 
    { 
    }  
} 

Dieser Controller:

public class SuperManController : SuperHero,IFlyable,IRunnable { 

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

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

} 

Diese abstrakte Klasse (für Tests)

[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); 
     } 

    } 
} 

Und schließlich diese Klasse von SuperHeroTest geerbt testen SuperManController:

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

    private SuperManController _superManController; 

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


    protected override SuperManController GetSuperHero() 
    { 
     return _superManController; 
    } 

} 

Methode MethodHasAuthorizeAttribute ist: (aus dem Beitrag oben)

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(); 
} 

Mein Problem ist:

Der Aufruf MethodHasAuthorizeAttribute(() => superHeroFlyable.Fly()) in SuperHeroTest Klasse Rückkehr false wenn es true zurückkehren.

(Die implementierte Methode Fly in Klasse SuperManController hat das Attribut Authorize).

Ich fügte das Attribut Authorize in Methode Fly in IFlyable hinzu und gibt dann true zurück.

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

Wie ich tun kann, um MethodHasAuthorizeAttribute die Umsetzung zu machen kontrollieren, anstatt die Schnittstelle?

+0

Dank Dove zur Bearbeitung! –

Antwort

9

Mit einigen Änderungen an der IfSuperHeroCanFlyMustHaveAuthorizeAttribute() -Methode können Sie es zum Laufen bringen.

Überprüfen Sie zunächst, ob Ihr Controller die IFlyable-Schnittstelle implementiert. Wenn ja, rufen Sie die MethodInfo für die Fly-Methode des Controllers ab. Dann müssen Sie nur die Attribute für die zurückgegebene MethodInfo überprüfen. Auf diese Weise prüfen Sie, ob die Implementierung das Attribut anstelle der Schnittstelle besitzt.

Folgende Arbeiten 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

Es funktioniert perfekt! Christophe vielen Dank! –

+0

Der Test besteht, wenn SuperHero nicht IFlyable ist, die Assert sollte außerhalb des If-Blocks sein – Grokodile

Verwandte Themen