0

Castle Windsor 3.2 提供了一个很酷的附加功能,即容器中的诊断日志记录。这帮助我将容器日志重定向到用于存储应用程序日志的 log4net 日志文件。

我现在想做的是能够Exception在注入我的可选属性时实际捕获容器检测到的内容。

在我的具体情况下,当 Castle 尝试执行我的代码以将属性注入类中时引发了Oracle数据库错误:ORA-28000: the account is lockedDatabaseBaseController

public class BaseController : Controller
{
    /// <summary>
    /// Repository interface injected by Castle Windsor IoC container.
    /// See <see cref="MyProject.Widgets.CastleWindsor.Facilities.PersistenceFacility.Init()"/> for more information.
    /// </summary>
    public ILogRepository Database { get; set; }
}

这个Database属性是null当我在一个继承自BaseController. 这一切都是因为温莎城堡“吞下了”例外。用户得到的唯一消息是:Object reference not set to an instance of an object. 好的,但我想向用户展示真正的异常/原因,即ORA-28000: the account is locked. 由于前面提到的诊断日志记录,这条消息被 Castle Windsor 记录下来。这很酷,但我希望能够真正捕获catch块内的异常:

public class SubCatListController : BaseController
{
    public ActionResult SubCatList(string subcat)
    {
        try
        {
            var sub = Database.GetLogSubCategory(subcat);
        }
        catch(Exception e) // I'd like to get the real exception from Castle Windsor here...
        {
            Logger.Error(e.Message, e);
        }
    }

}

这种情况可以通过属性注入实现吗?

4

2 回答 2

1

正如 Krzysztof Kozmic 在他的评论中提到的那样,我们不应该有任何代码在注入属性时尝试进行外部对象初始化。

我在后续评论中描述的问题是我在初始化属性时试图打开数据库连接。

我删除了该代码,现在只有在第一次使用注入的属性时,才会在我自己的域代码中引发异常。


今天我遇到了同样的问题:帮助我找出错误的一件事是暂时使用Constructor injection,如下所示:

private OEVizion _database;

public ReportingPeriodsController(OEVizion database)
{
    _database = database;
}

这样做我能够看到错误是什么:log4net 之间的版本不匹配 - OEVizion 类库中的一个和 .Web 项目中使用的一个。

在正确初始化 EF 上下文后Property injection,我又回到了工作中。:D

于 2014-01-11T00:59:58.623 回答
0

当您有可选的依赖项时,最好使用Null Object 模式

public BaseController() {
    Database = NullLogRepository.Instance;
}

它可以防止NullReferenceException并且您可以提供您期望的行为(什么都不做,抛出特定的异常,记录到跟踪等)

于 2014-01-09T08:37:00.737 回答