下面是两个类,其中一个使用ImportingConstructor导入另一个类,并从ctor中直接抛出一个MyException。所以,我希望在另一个类中捕获MyException,但我得到另一个类,即:
System.InvalidOperationException: GetExportedValue cannot be called before prerequisite import 'Class1..ctor ' has been set. (...)
如何强制MEF抛出原始异常,或者至少将原始异常包装到异常中,以便从代码中处理它?</ p>
[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 :(得分: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
}
}
}
}