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);
}
}
}
这种情况是否可以通过属性注入来实现?
答案 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
并且您可以提供您期望的行为(不执行任何操作,抛出特定异常,记录跟踪等)。