Castle Windsor 3.2 provides a cool addition that is Diagnostic logging in the container. This helped me redirect the container logs to a log4net log file that's being used to store the application logs.
What I'd like to do now is to be able to actually catch the Exception
the container detects while injecting my optional property.
In my specific situation, an Oracle
database error ORA-28000: the account is locked
was being raised while Castle tried to execute my code to inject the Database
property in a BaseController
class:
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; }
}
This Database
property is null
when I'm inside an action method in an Controller that inherits from BaseController
. This all happens because Castle Windsor "swallows" the exception. The only message the user gets is: Object reference not set to an instance of an object
. OK but I'd like to show the real exception/reason to the user, that is, ORA-28000: the account is locked
. This message gets logged by Castle Windsor thanks to the aforementioned Diagnostic logging. This is cool but I want to be able to really catch the exception inside the catch
block:
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);
}
}
}
Is this scenario possible with property injection?
As Krzysztof Kozmic mentioned in his comment we should not have any code that tries to do external object initialization while injecting a property.
My problem as I describe in this subsequent comment was that I was trying to open a database connection while initializing the property.
I removed that code and now the exception is only raised in my own domain code when that injected property is used for the 1st time.
Today I hit this same problem: one thing that helped me figure out the error was to momentarily use Constructor injection
instead, like this:
private OEVizion _database;
public ReportingPeriodsController(OEVizion database)
{
_database = database;
}
Doing this I was able to see what was the error: version mismatch between log4net - the one in the OEVizion class library and the one used in the .Web project.
After getting the EF context correctly initialized I got back to Property injection
and I'm back in business. :D