簡體   English   中英

使用ImportingConstructor處理從ctor引發的異常

[英]Handle an exception thrown from ctor with ImportingConstructor

下面是兩個類,其中一個使用ImportingConstructor導入另一個,並從ctor引發MyException。 因此,我希望在另一個類中捕獲MyException,但是我得到了另一個類,即:

 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){...}
}

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文檔

為了完整起見,這是完整的實現

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM