views:

106

answers:

2

Here is a code excerpt from AspComet project that works with Autofac.

public MessageBus(IClientRepository clientRepository, Func<IMessagesProcessor> messagesProcessorFactoryMethod)
{
    this.clientRepository = clientRepository;
    this.messagesProcessorFactoryMethod = messagesProcessorFactoryMethod;
}

How can I inject "Func<IMessagesProcessor> messagesProcessorFactoryMethod" with Windsor, is it possible?

Thanks.

+1  A: 
container.Register(Component.For<Func<Foo>>().Instance(f));

Here's a passing unit test that demonstrates the concept:

[TestMethod]
public void Test2()
{
    Func<string> f = () => "Hello world";

    var container = new WindsorContainer();
    container.Register(Component.For<Func<string>>().Instance(f));

    var resolvedFunc = container.Resolve<Func<string>>();

    Assert.AreEqual("Hello world", f());
}
Mark Seemann
It works as you suggested but I had to return IMessagesProcessor from the container so I coded it like this: Func<IMessagesProcessor> messagesProcessorFactoryMethod = () => container.Resolve<IMessagesProcessor>();Is there a better way or this is the best way?
yang
You can get Autofac-like behavior with no additional work by using the following custom facility: http://www.assembla.com/code/kkozmic/subversion/nodes/Garage/Castle.LightweightFactoryFacilityIf you don't want to use the facility, the solution you outlined in the previous comment is the way to go.
Krzysztof Koźmic
As of trunk (and starting with upcoming version 2.5) this behavior is baked in, that is you won't have to register the `Func` explicitly. Just having the constructor will be enough for Windsor to figure out what to do, and it will provide the delegate itself.
Krzysztof Koźmic
A: 
Container.Register(
  Component.For<IMessagesProcessor>()
           .ImplementedBy<MessagesProcessor>()
           .Lifetime.Transient,
  Component.For<Func<IMessagesProcessor>>()
           .Instance(() => Container.Resolve<IMessagesProcessor>())
)

That should do the trick

Neil Mosafi