Reputation: 59491
We are Using Castle.Windsor for Dependency Injection of our asp.net mvc (C#) application.
How to resolve Dependencies declared in Parameter Constructor while calling parameterless constructor?
Following is the ErrorController Code:
public class ErrorController : BaseController
{
#region Declaration
private readonly ICommonService _commonService;
#endregion
#region Constructor
public ErrorController()
{
}
public ErrorController(ICommonService commonService)
: base(commonService)
{
this._commonService = commonService;
}
#endregion
.
.
.
}
Following is the code in the Global.asax which is used to show custom error page if any error occurs:
protected void Application_Error()
{
Exception lastException = Server.GetLastError();
HttpException httpException = lastException as HttpException;
RouteData routeData = new RouteData();
//Possible reason for null is the the server error may not be a proper http exception
if (httpException == null)
{
errorController = new ErrorController();
routeData.Values.Add("controller", "Error");
routeData.Values.Add("action", "Index");
Response.Clear();
}
else
//It's an Http Exception, Let's handle it.
{
switch (httpException.GetHttpCode())
{
case 404:
//Page not found.
//Call target Controller
errorController = new ErrorController();
routeData.Values.Add("controller", "Error");
routeData.Values.Add("action", "PageNotFound");
break;
case 302:
//Page Temporarily Moved
errorController = new ErrorController();
routeData.Values.Add("controller", "Error");
routeData.Values.Add("action", "PageNotFound");
break;
case 500:
//Server error.
errorController = new ErrorController();
routeData.Values.Add("controller", "Error");
routeData.Values.Add("action", "Index");
Response.Clear();
break;
default:
errorController = new ErrorController();
routeData.Values.Add("controller", "Error");
routeData.Values.Add("action", "Index");
Response.Clear();
break;
}
}
//Pass exception details to the target error View.
routeData.Values.Add("error", lastException);
//Clear the error on server.
Server.ClearError();
//Call target Controller and pass the routeData.
errorController.Execute(new RequestContext(new HttpContextWrapper(Context), routeData));
}
From the Global.asax, we are calling ErrorController which is calling parameterless constructor and it fails in resolving the dependency of CommonService which is being used in the ErrorController to collect some basic data from the Database. But the _commonService is not initialized and its throwing null. Please suggest on how to handle this case.
Update
Below is the code where i call the dependency injection in the Global.asax
protected void Application_Start()
{
.
.
BootstrapContainer();
}
private static void BootstrapContainer()
{
container = new WindsorContainer().Install(
new ServiceInstaller(),
FromAssembly.This()
);
var controllerFactory = new WindsorControllerFactory(container.Kernel);
ControllerBuilder.Current.SetControllerFactory(controllerFactory);
}
Below is the code where the Controllers and Services are regsitered and at BootstrapContainer:
public class ControllersInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(Classes.FromThisAssembly()
.BasedOn<IController>()
.LifestyleTransient());
}
}
public class ServiceInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(Component.For<ICommonService>().ImplementedBy<CommonService>().LifeStyle.PerWebRequest);
.
.
.
}
}
Upvotes: 1
Views: 842
Reputation: 73253
You can get Castle to resolve the controller for you:
switch (httpException.GetHttpCode())
{
case 404:
errorController = container.Resolve<ErrorController>();
routeData.Values.Add("controller", "Error");
…
Upvotes: 1