编辑,先阅读:不是使用我的ApplicationException的using语句,它是我在实际代码中使用的DependencyResolver。我一开始并没想过要看那里,但果然,如果我尝试直接实例化这个类(就像我在下面简化的示例代码中所做的那样),它按预期工作。如果我在using语句中使用DependencyResolver,它只会按照我在下面记录的方式运行。我根本没想到在我的问题中提到这一点,因为我忽略了它。我使用的是Unity容器,仅供参考。我会通过它来更新它,并且可能会删除它。
更新2:确定结果是,当服务位置抛出异常时返回空资源是MVC中完全正常且预期的行为。当我第一次遇到这种行为并迷惑自己时,我完全不知道我正在使用依赖注入这一事实。因此,我会留下这个问题,万一其他人发现自己处于类似情况。在创建使用DependencyResolver服务定位器解析的资源时,您不能抛出异常!它会吞下异常并返回一个空资源!
如果有人想知道我根据这些新信息改变了什么:我只是将数据库检查/异常抛出逻辑放在存储库中的几个关键方法中,而不是在构造函数中。我也停止使用Unity并切换到Ninject,并从服务定位器模式转到将我的容器包装在单例类中,但这与我遇到的导致此线程的问题无关,而且更像是一种风格选择。
结束修改
所以我想说我有一些访问数据库的类,比如这个......
public class Foo : IDisposable {
private DbContext db = new FooDbContext();
public DoSomething(){
// do something with the FooDbContext...
}
// Dispose is implemented here as well...
}
当我去使用那个课程时,我会像这样访问它......
using (Foo foo = new Foo()){
foo.DoSomething();
}
所以我想要完成的是,每当构造一个Foo类时,如果底层DbContext无法建立连接,则抛出ApplicationException。
所以我将以下构造函数添加到Foo类...
public Foo() {
try
{
db.Database.Connection.Open();
}
catch
{
throw new ApplicationException("Database is not currently available. Try again later.");
}
}
但问题出现了,回到这段代码......
using (Foo foo = new Foo()){
foo.DoSomething();
}
当数据库不可用时执行using语句(并且我已经通过调试确认了这一点),在构造Foo时抛出ApplicationException ,但是忽略了ApplicationException,并且无论如何都要调用DoSomething方法。那时,我得到的是NullReferenceException而不是我想要的ApplicationException,因为foo为null。
我的ApplicationException发生了什么变化?为什么被忽略?我该怎么做才能确保ApplicationException冒泡?
我实际上并不想处理ApplicationException。对于某些上下文,这是一个ASP.NET MVC应用程序。我希望ApplicationException不被处理,并让我设置的自定义错误页面向用户显示ApplicationException中包含的消息。
答案 0 :(得分:1)
我认为你的问题没有进入db和连接细节是因为使用了block,使用块吞下了构造函数中发生的异常。
http://www.digitallycreated.net/Blog/51/c%23-using-blocks-can-swallow-exceptions