0

I am hoping someone can tell me what is wrong with my implementation of Castle Windsor. I have followed the tutorial Here. I have added a second installer that looks like this:

public class DataInstaller : IWindsorInstaller
{
    public void Install(IWindsorContainer container, IConfigurationStore store)
    {
        //breakpoint on the line below is hit when the application starts. 
        container.Register(Component.For<IDataProvider>().ImplementedBy<MyDataProvider>());
    }
}

My controller looks like this:

public IDataProvider Provider { get; set; }

    public JsonResult Get()
    {
       //Provider is always null!!! 
       var data = Provider.Retrieve(a => true).ToArray();
       //convert to JSON and return.
    }

Why is my provider always null? My second installer is being hit when the application fires up, because it hits a breakpoint, but from what I can tell the rest of the application just ignores this.

Contents of my global.asax.cs

protected void Application_Start()
    {
        GlobalConfiguration.Configure(WebApiConfig.Register);

        BootstrapContainer(); 
    }

    private static void BootstrapContainer()
    {
        container = new WindsorContainer().Install(FromAssembly.This());

        var controllerFactory = new WindsorControllerFactory(container.Kernel);
        ControllerBuilder.Current.SetControllerFactory(controllerFactory);

        //container.Register(Component.For<IDataProvider>().ImplementedBy<MyDataProvider>().LifestyleSingleton()); 
    }

I tried what the person did in this question, but that still resulted in the same problem. What am I missing here?

Edit: Someone asked if I registered the controller. The tutorial had me create the following class. I believe this would be registering the controllers?

public class ControllersInstaller : IWindsorInstaller
{
    public void Install(IWindsorContainer container, IConfigurationStore store)
    {
        container.Register(Classes.FromThisAssembly().BasedOn<IController>().LifestyleTransient());
    }
}
Community
  • 1
  • 1
Dave
  • 2,473
  • 2
  • 30
  • 55
  • There is a separate installer class called ControllerInstaller created in the tutorial. I will edit that into the question. I believe that is what this is supposed to be doing. – Dave Jun 09 '16 at 16:38
  • It should work out of the box: http://stackoverflow.com/questions/4190292/windsor-setter-injection-in-code Do `IDataProvider` refers to the same interface in Controller? – csharpfolk Jun 09 '16 at 16:44
  • PS. Are you using MVC or WebAPI? – csharpfolk Jun 09 '16 at 16:45
  • I am using WebAPI. – Dave Jun 09 '16 at 16:47
  • In WebAPI that seems to me you are using, setup is slightly different check this: http://www.macaalay.com/2014/08/27/using-castle-windsor-with-web-api-apicontroller/ – csharpfolk Jun 09 '16 at 16:47
  • @csharpfolk That did the trick! Thanks!! – Dave Jun 09 '16 at 19:19
  • The error here is that you are using property injection instead of constructor injection. You should *not* use property injection *at all*. – Steven Jun 10 '16 at 09:09
  • @Steven I tried constructor injection as well. When I did, I get some error from MVC for not having a default constructor. The link from csharpfolk resolved the issue. Why should property injection not be used? – Dave Jun 13 '16 at 13:53
  • The error of not having a default constructor means that you are not integrating with Web API. You should either add a custom IDependencyResolver or IControllerActivator. And I think there are integration packages for Castle Windsor that can help you with this. – Steven Jun 13 '16 at 14:07
  • Property injection is bad, because it causes [Temporal Coupling](http://blog.ploeh.dk/2011/05/24/DesignSmellTemporalCoupling/) and either causes your code to have a dependency on the DI library (because you'll mark your code with attributes) or you'll tell the DI library to inject a dependency when it can, which means your application will fail silently when a required dependency is missing. This all can be solved by sticking with constructor injection. – Steven Jun 13 '16 at 14:10
  • Do note that the solution provided by @csharpfolk is flawed, because the `DependencyResolver` implementation of [that](http://www.macaalay.com/2014/08/27/using-castle-windsor-with-web-api-apicontroller/) article does not release components that are resolved from Castle. This causes a memory leak which is really bad in web applications. – Steven Jun 13 '16 at 14:12
  • @Steven WebAPI and ASP.NET MVC factories for controllers doesn't have way to release controllers at the end of request. What most folk do is to register Controllers + Services + Repositories + UnitOfWork as PerWebRequest. When the request ends Windsor Castle takes care to dispose all of your classes – csharpfolk Jun 13 '16 at 14:50

0 Answers0