Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Castle windsor controller factory and repository not resolving

I am currently testing out Castle Windsor vs. Ninject, and I really like what Windsor has to offer, I am just having an issue with a repository injection.

So, here's the setup...I have a ControllersInstaller that looks like this...

public class ControllersInstaller : IWindsorInstaller
{
    public void Install(IWindsorContainer container, IConfigurationStore store)
    {
        container.Register(FindControllers().Configure(ConfigureControllers()));
    }

    private BasedOnDescriptor FindControllers()
    {
        return AllTypes.FromThisAssembly()
            .BasedOn<IController>()
            .If(Component.IsInSameNamespaceAs<HomeController>())
            .If(t => t.Name.EndsWith("Controller"));

    }

    private ConfigureDelegate ConfigureControllers()
    {
        return c => c.LifeStyle.Transient;
    }
}

A context installer that looks like this...

public class ContextInstaller : IWindsorInstaller
{
    public void Install(IWindsorContainer container, IConfigurationStore store)
    {
        container.Register(AllTypes.FromThisAssembly()
            .Where(t => t.Name == "MyContext"));
    }
}

And a repo installer that looks like...

public class RepoInstaller : IWindsorInstaller
{

    public void Install(IWindsorContainer container, IConfigurationStore store)
    {
        container.Register(AllTypes.FromThisAssembly()
            .Where(type => type.Name.EndsWith("Repo"))
            .WithService.DefaultInterface()
            .Configure(c => c.LifeStyle.Singleton));
    }
}

Then in Global.asax I am registering them by...

private static void BootstrapContainer()
    {
        var container = new WindsorContainer()  // Create a container to hold the dependencies
            .Install(
            new ContextInstaller(),
            new RepoInstaller(),
             new ControllersInstaller()
            );      // Scan this assembly for all IWindsorInstaller

        var controllerFactory = new WindsorControllerFactory(container.Kernel);     // Create a new instance
        ControllerBuilder.Current.SetControllerFactory(controllerFactory);          // Use my factory instead of default
    }

My home controller looks like...

    public class HomeController : Controller
{
    IMyRepo _repo;

    public HomeController(MyRepo repo)
    {
        _repo = repo;
    }

But for whatever reason when I debug the thing I get... Some dependencies of this component could not be statically resolved. MyProject.Controllers.HomeController is waiting for the following dependencies: Services: - MyProject.Models.MyRepo which was not registered.

And I can't figure out why! I tried making my repo installer install as singleton, and I tried reordering the Registration process so the repo get's setup before the controllers.

When I debug and hit the controller factory line in Global.asax, it says that everything except HomeController has been resolved correctly.

Thoughts?

like image 574
jcreamer898 Avatar asked Oct 10 '22 22:10

jcreamer898


2 Answers

If you register your Repository including interface .WithService.DefaultInterface() your dependecy has to based on interface (maybe IRepo) not on concrete.

If your dependency is based on concrete, than remove .WithService.DefaultInterface() and so dependency will be resolved... but that's nont the best way: for Repository always have dependency based on Interface

like image 158
Crixo Avatar answered Oct 13 '22 12:10

Crixo


I always hate answering my own question, but sometimes it must be done...

This is a small yet stupid thing that I missed! Turns out, the issue was in my controllers. I was trying to pass the actual Repo into my HomeController() constructor.

I switched it to

public ActionResult HomeController(IRepo repo)
{
     _repo = repo;
}

And that was what it needed to work...Sheesh...

like image 44
jcreamer898 Avatar answered Oct 13 '22 12:10

jcreamer898