Prasad
Prasad

Reputation: 59491

Castle.Windsor - Dependency Injection of the parameter constructor on calling parameterless constructor

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

Answers (1)

stuartd
stuartd

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

Related Questions