Castle Windsor - how to resolve components based on constructor parameters
Asked Answered
L

1

9

Say I have a component like this

public class MyComponent
{
    public MyComponent(string name)
    {
    }
}

I basically want to have the provided constructor parameters behave as part of the component identifier when resolving it. If you've never resolved it with that set of parameters, it will instantiate a new one.

In other words, I want to somehow modify the following test to succeed:

IWindsorContainer container = new WindsorContainer();
container.Register(Component.For<MyComponent>());
MyComponent a1 = container.Resolve<MyComponent>(new { name = "a" });
MyComponent a2 = container.Resolve<MyComponent>(new { name = "a" });
MyComponent b = container.Resolve<MyComponent>(new { name = "b" });

Assert.AreSame(a1, a2);
Assert.AreNotSame(a1, b);

Currently it fails because it will instantiate with name=a, then return the same object for all future name=a and name=b.

Thanks!

Libenson answered 20/8, 2010 at 13:59 Comment(1)
are you sure you want to do this at resolution-time instead of registration-time?Madalynmadam
M
8

Normally this is done at registration-time, not at resolution-time. In fact, calling Resolve() in your code should be rare since you're using the container as a service locator.

container.Register(
   Component.For<MyComponent>()
            .Named("comp_a")
            .DependsOn(new { name = "a" }),
   Component.For<MyComponent>()
            .Named("comp_b")
            .DependsOn(new { name = "b" }));

var a1 = container.Resolve<MyComponent>("comp_a");
var a2 = container.Resolve<MyComponent>("comp_a");
var b = container.Resolve<MyComponent>("comp_b");
Assert.AreSame(a1, a2);
Assert.AreNotSame(a1, b);

Instead of using Resolve() as in my code (which is purely for testing purposes) you normally use service overrides or a handler selector to select which MyComponent to inject into your other services.

Madalynmadam answered 20/8, 2010 at 16:0 Comment(5)
I'm aware that I can do that, but I'm actually using the typed auto-factory facility. By default, you can select components with Get{component-name} methods but for me it needs to be dynamic. However, it looks like it's possible to write a selector that would let me implement a Get(component-name) method or something similar.Libenson
@Cameron: I recommend creating another question stating all relevant details about your issue, and a relevant test case. There was no mention of the typed factory facility until this comment.Madalynmadam
I literally did want to know if what I described in the original question was possible. I know what the factory support facility is doing to the container underneath as I have read the source code, so I just wanted to know if the container itself supported something similar to what I described. If it's not, that's okay, and I'll implement it another way.Libenson
@cameron: again, I recommend creating a question with your actual issue, not a similar issue. There might be a better solution.Madalynmadam
some good reference : stw.castleproject.org/Windsor.Inline-Dependencies.ashxEmanate

© 2022 - 2024 — McMap. All rights reserved.