2014-04-24 47 views
0

這就是我想要實現的: 目前我正在將2500個集成測試從nunit轉換爲mstest,以便我們可以使用Microsoft Test Manager /實驗室。大多數測試需要在我正在使用的產品的用戶界面線程上運行,否則它們將不會成功。Postpost跳過裝飾用CompilerGenerated屬性標記的方法

這是我的問題: 我創建了一個postsharp方面,它會自動運行MSTEST測試方法,將初始化環境測試,並在UI線程中運行它們。這工作正常,除了用Specflow創建的測試。 Specflow生成的代碼隱藏在標記爲System.Runtime.CompilerServices.CompilerGenerated屬性的類後面。當一個類被標記爲該屬性時,Postsharp似乎會跳過它中的所有方法。

該方面在組件級別上定義。我試圖在註冊期間使用MulticastAttributes.CompilerGenerated屬性,但它似乎沒有改變行爲。當我直接將方面放在方法上時,它可以工作。

我正在使用Postsharp的最新穩定版本(目前是3.1)。

樣品方面:

[Serializable] 
public class MyAspect : PostSharp.Aspects.OnMethodBoundaryAspect 
{ 
    public override void OnEntry(PostSharp.Aspects.MethodExecutionArgs args) 
    { 
     Console.WriteLine("Starting {0}", args.Method.Name); 
    } 

    public override void OnExit(PostSharp.Aspects.MethodExecutionArgs args) 
    { 
     Console.WriteLine("Completed {0}", args.Method.Name); 
    } 
} 

我試圖將其應用到該代碼:

[組件:PostSharpTestAspects.MyAspect( AttributeTargetTypeAttributes = MulticastAttributes.Public | MulticastAttributes.AnyGeneration, AttributeTargetElements = MulticastTargets.Method, AttributeTargetMemberAttributes = MulticastAttributes.Public | MulticastAttributes.AnyGeneration)]

class Program 
{ 
    static void Main(string[] args) 
    { 
     new MyTestClass().MyTestMethod(); 
     Console.WriteLine("Press a key to exit..."); 
     Console.ReadKey(); 
    } 
} 

[System.Runtime.CompilerServices.CompilerGenerated] 
public class MyTestClass 
{   
    public void MyTestMethod() 
    { 
     Console.WriteLine("Executing MyTestMethod.."); 
    } 
} 

當拆除編譯器生成的屬性PostSharp應用方面。

我的問題是: 這是行爲設計​​?這是一個錯誤? 有沒有一些解決方法?也許我需要在程序集屬性中以不同方式應用MulticastAttributes?

回答

0

PostSharp會忽略所有在執行方面屬性組播時應用[CompilerGenerated]屬性的類型。此功能是設計人員所必需的,以避免在C#編譯器生成的所有類型上應用這些方面。 生成的類型表示C#編譯器的實現細節,默認情況下應用這些屬性會將這些實現細節公開給用戶。

但是,PostSharp會以較少的限制處理非生成類型中生成的方法。這些是用戶通常期望默認應用這些方面的方法。 例如,自動屬性訪問器被標記爲[CompilerGenerated]。您可以通過在方面的AttributeTargetTypeAttributes屬性上設置標誌MulticastAttributes.CompilerGeneratedMulticastAttributes.UserGenerated來控制此行爲。

如果您需要將該方面應用於編譯器生成的類型,那麼您可以通過實現自己的aspect provider並將其應用於程序集級別來實現。

[MulticastAttributeUsage(MulticastTargets.Assembly)] 
public class SampleAspectProvider : MulticastAttribute, IAspectProvider 
{ 
    public IEnumerable<AspectInstance> ProvideAspects(object targetElement) 
    { 
     var myAspect = new MyAspect(); 
     var assembly = (Assembly) targetElement; 

     foreach (var type in assembly.GetTypes()) 
     { 
      if (/* type is a valid target */) 
      { 
       foreach (var methodInfo in type.GetMethods()) 
       { 
        yield return new AspectInstance(methodInfo, myAspect); 
       } 
      } 
     } 
    } 
} 

而且適用於標靶組件:

[assembly: SampleAspectProvider]