Castle Windsor IoC Property Injection simple how-to
Asked Answered
D

1

6

OK I think there is maybe too much information about Castle Windsor because looking for these keywords gives me examples of everything, and frankly I don't understand enough about how it works to properly troubleshoot this. I have tried quite a few permutations with little luck at this point.

I have an IUnitOfWorkFactory that I want to instantiate as a singleton. So, I install Castle Windsor, write a bit of code like so:

iocContainer = new WindsorContainer()
    .Install(FromAssembly.This());

var propInjector = iocContainer.Register(
    Component.For<IUnitOfWorkFactory>()
    .LifestyleSingleton()
    .Instance(new NHUnitOfWorkFactory())
    );

propInjector.Resolve<IUnitOfWorkFactory>();

This gets called from my Application_Start method.

I have an AccountController wired up like so:

public class AccountController : SecureController
{
    public IUnitOfWorkFactory UnitOfWorkFactory { get; set; }
    ...

...as far as I can figure, this should just "work" (although don't ask me how). But my property is always null when I try to use it.

It seems like I'm missing something silly and simple, but I have no idea what it is.

I have also tried

var propInjector = iocContainer.Register(
    Component.For<IUnitOfWorkFactory>()
    .ImplementedBy<NHUnitOfWorkFactory>()
    .LifestyleSingleton()
    );

with no success.

What am I doing wrong?

CONCLUSION

I was missing several steps here. I had built an installer and a bootstrapper per the tutorial, but I registered my services at the wrong spot... before building the controller factory. Now my bootstrapper looks like this:

iocContainer = new WindsorContainer()
    .Install(FromAssembly.This());

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

iocContainer.Register(
    Component.For<IUnitOfWorkFactory>()
    .ImplementedBy<NHUnitOfWorkFactory>()
    .LifestyleSingleton()
    );

... and my property injections were no longer null.... now I just have to debug the other 87 problems...

Disperse answered 15/3, 2013 at 23:14 Comment(6)
Have you registered your controller?Fern
...Wouldn't that only be necessary for constructor dependency injection? Perhaps I misunderstand how this is supposed to work.Disperse
No, the container must create the root of the object graph. In this case the controller. This is the case for Property or Constructor injection (because they work the same way).Fern
If you look at the windsor example on the site, the first thing that it does is resolves the root object container.Resolve<IKing>() - that's what gets the ball rolling (docs.castleproject.org/…)Matte
Hmm... I thought that was a servicelocator pattern. I will look into that.Disperse
You can safely remove the last line propInjector.Resolve<IUnitOfWorkFactory>(); as it is not doing anything.Crumpler
F
7

Both constructor and property injection work when the root object is resolved by the container. In this case, your AccountController would be the root object that Windsor would need to create.

In order to wire this up, you should use a controller factory. Once the controller is registered and resolved by the container, everything should work as you expect.

Fern answered 15/3, 2013 at 23:35 Comment(2)
Actually that was originally the tutorial I started with, and I already had this controller factory built... but this seems to do nothing. I have the installer too... still nothing.Disperse
OK, this and Charleh's comment put me on to what I was doing wrong. I'll write it up in my question. Thanks!Disperse

© 2022 - 2024 — McMap. All rights reserved.