2014-04-24 4 views
0

속성 CompilerGenerated으로 표시됩니다 방법 장식을 생략 : 우리는 마이크로 소프트 테스트 관리자로 실행할 수 있도록, 은 현재 내가 MSTEST하는 NUNIT에서 2500 개 통합 테스트를 변환 오전/랩. 대부분의 테스트는 내가 작업중인 제품의 사용자 인터페이스 스레드에서 실행해야합니다. 그렇지 않으면 성공하지 못합니다. 내가 자동으로 테스트를위한 환경을 초기화하고, UI 스레드에서 실행할 것 MSTEST 시험 방법을 실행하는 postsharp 측면을 만들었습니다 :Postsharp이 내가 달성하기 위해 노력하고 무엇

이것은 내 문제입니다. 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.."); 
    } 
} 

CompilerGenerated 제거

PostSharp는이 양태를 적용 때문이다.

내 질문은 : 의도적으로 설계된 동작입니까? 이거 버그 야? 해결 방법이 있습니까? 어쩌면 어셈블리 특성에서 MulticastAttributes를 다르게 적용해야합니까?

답변

0

PostSharp는 aspect 속성의 멀티 캐스팅을 수행 할 때 [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] 
관련 문제