문제

좋아, 그래서 나는 눈썹을 올리는 다음 문제를 해결했다.

여러 가지 이유로 TestingAssembly.dll에서 테스트 클래스가 BasetestingAsembly.dll의 Testingbase 클래스에 의존하는 테스트 설정이 있습니다. 그 동안 Testbase가하는 일 중 하나는 자체적으로 특정 임베디드 리소스를 찾는 것입니다.

그래서 내 기초에 다음 줄이 포함되어 있습니다 ...

public class TestBase {    
  private static Assembly _assembly;
  private static Assembly _calling_assembly;

  static TestBase() {
    _assembly = Assembly.GetExecutingAssembly();
    _calling_assembly = Assembly.GetCallingAssembly();
  }
}

내가 생각한 이래로,이 어셈블리는 응용 프로그램의 수명 동안 동일 할 것이므로 모든 테스트마다 그것을 다시 계산하는 이유는 무엇입니까?

그러나 이것을 실행할 때 나는 _assembly와 _calling_assembly가 각각 basetestingesmbly 및 testingasembly보다는 basetestingesmbly로 설정되고 있음을 알았습니다.

변수를 정적이 아닌 것으로 설정하고 일반 생성자로 초기화하면이 문제가 해결되었지만 왜 이런 일이 시작된 이유는 혼란 스럽습니다. 정적 생성자가 정적 멤버가 처음으로 참조 할 때 실행되었다고 생각했습니다. 이것은 내 테스트 어셈블리에서만 발생했을 수 있었으며, 그런 다음 발신자가되어야했을 것입니다. 무슨 일이 있었는지 아는 사람이 있습니까?

도움이 되었습니까?

해결책

정적 생성자는 사용자 코드가 아닌 런타임에 의해 호출됩니다. 생성자에서 중단 점을 설정 한 다음 디버거에서 실행하여이를 볼 수 있습니다. 통화 체인의 바로 위의 기능은 기본 코드입니다.

편집하다: 정적 초기화기가 다른 사용자 코드와 다른 환경에서 실행되는 방법에는 여러 가지가 있습니다. 몇 가지 다른 방법입니다

  1. 그것들은 멀티 스레딩으로 인한 인종 조건으로부터 암시 적으로 보호됩니다
  2. 이니셜 라이저 외부에서 예외를 포착 할 수 없습니다

일반적으로 너무 정교한 것에 사용하지 않는 것이 가장 좋습니다. 다음 패턴으로 단일 이니 니트를 구현할 수 있습니다.

private static Assembly _assembly;
private static Assembly Assembly {
  get {
    if (_assembly == null) _assembly = Assembly.GetExecutingAssembly();
    return _assembly;
  }
}

private static Assembly _calling_assembly;
private static Assembly CallingAssembly {
  get {
    if (_calling_assembly == null) _calling_assembly = Assembly.GetCallingAssembly();
    return _calling_assembly;
  }
}

멀티 스레드 액세스를 기대하면 잠금을 추가하십시오.

다른 팁

나는 대답이 여기에 있다고 생각합니다. C# 정적 생성자. 가장 좋은 추측은 정적 생성자가 예기치 않은 상황에서 호출되는 것입니다.

사용자는 프로그램에서 정적 생성자가 실행되는시기를 제어 할 수 없습니다.

Assembly.getCallingAssembly ()는 통화 스택에서 두 번째 항목의 어셈블리를 반환합니다. 이는 방법/getter/생성자가 어떻게 호출되는지에 따라 매우 가능합니다. 다음은 라이브러리에없는 첫 번째 방법의 어셈블리를 얻기 위해 도서관에서 한 일입니다. (이것은 정적 생성자에서도 작동합니다.)

private static Assembly GetMyCallingAssembly()
{
  Assembly me = Assembly.GetExecutingAssembly();

  StackTrace st = new StackTrace(false);
  foreach (StackFrame frame in st.GetFrames())
  {
    MethodBase m = frame.GetMethod();
    if (m != null && m.DeclaringType != null && m.DeclaringType.Assembly != me)
      return m.DeclaringType.Assembly;
  }

  return null;
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top