Search code examples
asp.net-mvcdependency-injectioncastle-windsor

ASP.NET MVC Castle Windsor and dependency injection


I am trying to create an ASP.NET MVC project with Castle Windsor and dependency injection. Everything is working fine expect the following:

Global.asax

Container = new WindsorContainer();
Container.Install(new WebInstaller(), new LoggingInstaller());

var customControllerFactory = new CustomControllerFactory(Container);
ControllerBuilder.Current.SetControllerFactory(customControllerFactory);

Webinstaller to register the Castle classes:

string connectionStr = GetConnectionString("MainModel");
container.Register(Component.For(typeof(MainModelContainer)).DependsOn(new { 
          connectionString = connectionStr }).LifestylePerWebRequest());
container.Register(Classes.FromAssemblyContaining<MemberQueries>().InNamespace("User.EF.Queries").WithService.DefaultInterfaces().LifestylePerWebRequest());
container.Register(Classes.FromAssemblyContaining<HomeController>().BasedOn<IController>().LifestylePerWebRequest());

//PROBLEM that doesn't work
container.Register(Classes.FromAssemblyContaining<HomeController>().BasedOn<IAddMessage>().LifestylePerWebRequest());

HomeController

public IAddMessage AddMessage { get; set; }
private readonly IMemberQueries _memberContract;

public HomeController(IMemberQueries memberContract)
{
  _memberContract = memberContract;
}

public ActionResult Index()
{
   //PROBLEM AddMessage is Null and is not resolved automaticaly
   AddMessage.Add("Test", MessageTypes.message);
   return View("Index");
}

IAddMessage Implementation

public class CustomMessage : IAddMessage
{
    private IController Controller { get; set; }

    public CustomMessage(IController controller)
    {
        Controller = controller;
    }

    public void Add(string text, MessageTypes messageTypes)
    {
        //TODO
    }
}

IAddMessage Interface

public interface IAddMessage
{
    void Add(string text, MessageTypes messageTypes);
}

The problem is, that the IAddMessage property is null, because the container can't resolve the IController dependency in the CustomMessage constructor. But I don't know how to resolve this Problem.

The internal error message in the Castle container shows this:

Some dependencies of this component could not be statically resolved. 'User.Web.UI.Helper.Messages.CustomMessage' is waiting for the following dependencies: - Service 'System.Web.Mvc.IController' which was not registered.

I looked a lot in the web but I can't find any working hints or Solution for my problem.


Solution

  • The problem is that you haven't registered the IController-dependency. I suppose you're thinking that you did that with the following line:

    container.Register(Classes.FromAssemblyContaining<HomeController>().BasedOn<IController>().LifestylePerWebRequest());
    

    This might seem like you're doing that, but what you're actually doing is registering all the classes that implement this interface. So, when you ask the container for a HomeController, it will know how to resolve that, however, if you ask it for an IController, it won't know whether to create a HomeController or whatever other controller.

    What you probably want is the current active controller. In order to do this, you would probably have to inherit from the CustomControllerFactory and save the created controller in the request scope. Then you can retrieve it from the request scope inside your CustomMessage class.

    You can check the following thread to see how to do that: Asp.net mvc 3- get the current controller instance (not just name)