2014-12-02 2 views
0

다음은 두 클래스 중 하나가 ImportingConstructor를 사용하여 다른 클래스를 가져오고 ctor에서 MyException 권한을 throw하는 두 클래스입니다. 그래서, 다른 클래스에 MyException을 잡을 것으로 예상하지만 즉, 확실히 다른 하나를 얻을 :ImportingConstructor를 사용하여 ctor에서 예외를 처리합니다.

System.InvalidOperationException: GetExportedValue cannot be called before prerequisite import 'Class1..ctor ' has been set. (...) 

가 어떻게 원래의 예외를 던져 MEF 강제 할 수 있습니다, 또는 적어도 일부 예외에 원래의 포장에, 그래서 나는 그것을 코드에서 처리 할 수 ​​있을까?

[Export] 
class Class1 
{ 
    public Class1() 
    { 
     (....) 
     throw new MyException("MyException has been thrown"); 
    } 
} 

class Class2 
{ 
    [ImportingConstructor] 
    public Class2(Class1 class1) 
    { 
     (....) 
    } 
} 

static void Main(string[] args) 
{ 
    var catalog = new AggregateCatalog(
     new AssemblyCatalog(typeof (Class1).Assembly)); 
    CompositionContainer container = new CompositionContainer(catalog, true); 
    try{ 
     Class2 class2 = container.GetExportedValue<Class2>(); 
    } 
    catch(MyException ex){...} 
} 

답변

0

AFAIK, 당신은 MEF는 원래의 예외를 던져 얻을 수 있지만, 당신은 파고 경우 원래의 예외 스택 추적에 있습니다. 따라서 이것을 처리하는 한 가지 방법은 예상 한 예외에 대해 CompositionException을 검사하는 것입니다. 찾으면 필요한 오류 처리를 계속할 수 있습니다.

try 
{ 
    Class2 class2 = container.GetExportedValue<Class2>(); 
} 
catch (CompositionException ex) 
{ 
    foreach (var cause in ex.RootCauses) 
    { 
     //Check if current cause is the Exception we're looking for 
     var myError = cause as MyException; 

     //If it's not, check the inner exception (chances are it'll be here) 
     if (myError == null) 
      myError = cause.InnerException as MyException; 

     if (myError != null) 
     { 
      //do what you want 
     } 
    } 
} 

예외가 당신이 스택 추적에서 볼 필요가 경우에 따라 달라질 수 있습니다 던져하지만, 간단한 예를 들어 위의 옳은 길을 당신을 얻어야한다 위치에 따라. 당신이 관심이 경우, 여기 오른쪽 완성도를 들어 MSDN docs

는, 여기에 전체 구현

[Export] 
class Class1 
{ 
    public Class1() 
    { 
     throw new MyException("MyException has been thrown"); 
    } 
} 

[Export] 
class Class2 
{ 
    [ImportingConstructor] 
    public Class2(Class1 class1) 
    { 

    } 
} 

static void Main(string[] args) 
{ 
    var catalog = new AggregateCatalog(
     new AssemblyCatalog(typeof (Class1).Assembly)); 
    CompositionContainer container = new CompositionContainer(catalog, true); 
    try 
    { 
     Class2 class2 = container.GetExportedValue<Class2>(); 
    } 
    catch (CompositionException ex) 
    { 
     foreach (var cause in ex.RootCauses) 
     { 
      var myError = cause as MyException; 

      if (myError == null) 
       myError = cause.InnerException as MyException; 

      if (myError != null) 
      { 
       //do what you want 
      } 
     } 
    } 
} 
+0

예입니다입니다. CompositionException에는 원인에 대한 정보가 들어 있지만 InvalidOperationException이 발생하므로 추가 데이터를 추출 할 수 없습니다. –

+0

@AndrewOrlov : 예, 그리고 당신이보고있는 예외가 class1 생성자로부터 발생하지 않았다고 내기를 기꺼이합니다. 오류를 복제하는 코드를 게시 할 수 있습니까? 개인적으로 예외가 멀티 스레드 응용 프로그램에서 본 유일한 시간. 제공 한 예제 코드는 현재 가지고있는 문제를 복제하지 않고 'CompositionException'을 던집니다. – Nathan

+0

예, 'Class2'의 형식 이니셜 라이저가 예외를 던진 것과 같은 일반 메시지가 표시된 System.TypeInitializationException이 표시됩니다. –

관련 문제