Castle Windsor - how to resolve components based o

2019-04-06 09:36发布

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!

1条回答
甜甜的少女心
2楼-- · 2019-04-06 10:22

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.

查看更多
登录 后发表回答