如何处理Castle Windsor可选属性注入期间引发的异常?

时间:2014-01-08 22:35:49

标签: exception exception-handling dependency-injection castle-windsor property-injection

Castle Windsor 3.2提供了一个很酷的添加Diagnostic logging in the container。这有助于我将容器日志重定向到用于存储应用程序日志的log4net日志文件。

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

在我的特定情况下,当Castle尝试执行我的代码以在Oracle类中注入ORA-28000: the account is locked属性时,引发了Database数据库错误BaseController:< / p>

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

当我在Controller中继承自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);
        }
    }

}

这种情况是否可以通过属性注入来实现?

2 个答案:

答案 0 :(得分:1)

正如Krzysztof Kozmic在他的comment中提到的,我们不应该在注入属性时尝试进行外部对象初始化。

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

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


今天我遇到了同样的问题:帮助我弄清楚错误的一件事就是暂时使用Constructor injection,就像这样:

private OEVizion _database;

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

执行此操作我能够看到错误是什么:log4net之间的版本不匹配 - 在OEVizion类库中的版本与.Web项目中使用的版本不匹配。

在正确初始化EF上下文后,我回到了Property injection,我又回来了。 :d

答案 1 :(得分:0)

如果您有可选的依赖项,最好使用Null Object pattern

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

它会阻止NullReferenceException并且您可以提供您期望的行为(不执行任何操作,抛出特定异常,记录跟踪等)。

相关问题