Func<T> injecting with Windsor container
Asked Answered
B

3

6

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.

Balfour answered 8/4, 2010 at 13:40 Comment(0)
F
5
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());
}
Fayefayette answered 8/4, 2010 at 13:46 Comment(3)
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?Balfour
You can get Autofac-like behavior with no additional work by using the following custom facility: assembla.com/code/kkozmic/subversion/nodes/Garage/… If you don't want to use the facility, the solution you outlined in the previous comment is the way to go.Bellman
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.Bellman
M
7
Container.Register(
  Component.For<IMessagesProcessor>()
           .ImplementedBy<MessagesProcessor>()
           .Lifetime.Transient,
  Component.For<Func<IMessagesProcessor>>()
           .Instance(() => Container.Resolve<IMessagesProcessor>())
)

That should do the trick

Mcbride answered 13/5, 2010 at 21:59 Comment(0)
F
5
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());
}
Fayefayette answered 8/4, 2010 at 13:46 Comment(3)
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?Balfour
You can get Autofac-like behavior with no additional work by using the following custom facility: assembla.com/code/kkozmic/subversion/nodes/Garage/… If you don't want to use the facility, the solution you outlined in the previous comment is the way to go.Bellman
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.Bellman
M
2

Castle.Windsor 2.5+ comes with delegate-based factories support which allows it to resolve a delegate for you without any explicit registration.

Mingrelian answered 9/5, 2017 at 18:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.