如果数据库连接在实例化DbContext资源的using语句内失败,我如何自动抛出ApplicationExceptio
本文关键字:失败 何自动 ApplicationExceptio 语句 实例化 数据库连接 DbContext 资源 using 如果 | 更新日期: 2023-09-27 18:01:04
EDIT,先读:这不是正在吞噬我的ApplicationException的using语句,而是我在实际代码中使用的DependencyResolver。一开始我甚至没有想过要看那里,但可以肯定的是,如果我尝试直接实例化类(就像我在下面的简化示例代码中所做的那样(,它会按预期工作。只有当我在using语句中使用DependencyResolver时,它的行为才会像我下面记录的那样。我只是没有想过在我的问题中提到这一点,因为我忽略了它。我使用的是Unity容器,仅供参考。我会在处理过程中更新它,可能会删除它。
更新2:好的,所以当服务位置抛出异常时返回null资源是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中包含的消息。
我认为你在没有进入数据库和连接细节的情况下出现的问题是因为使用块,使用块吞噬了构造函数中发生的异常。
http://www.digitallycreated.net/Blog/51/c%23-使用块可以吞下异常
https://msdn.microsoft.com/en-us/library/aa355056.aspx